diff options
author | glebius <glebius@FreeBSD.org> | 2012-12-13 12:51:22 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2012-12-13 12:51:22 +0000 |
commit | 9ffc5fc1ccef66b1ce687f4fe78278f23479a400 (patch) | |
tree | 84176de114263a35d9ffab299c62a27cfa5710f0 | |
parent | d370f96d4ccd311d5725056967234b35a54039d2 (diff) | |
download | FreeBSD-src-9ffc5fc1ccef66b1ce687f4fe78278f23479a400.zip FreeBSD-src-9ffc5fc1ccef66b1ce687f4fe78278f23479a400.tar.gz |
Merge rev. 1.119 from OpenBSD:
date: 2009/03/31 01:21:29; author: dlg; state: Exp; lines: +9 -16
...
this also firms up some of the input parsing so it handles short frames a
bit better.
This actually fixes reading beyond mbuf data area in pfsync_input(), that
may happen at certain pfsync datagrams.
-rw-r--r-- | sys/netpfil/pf/if_pfsync.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c index 7d1d54e..6d6ad4d 100644 --- a/sys/netpfil/pf/if_pfsync.c +++ b/sys/netpfil/pf/if_pfsync.c @@ -44,6 +44,7 @@ /* * Revisions picked from OpenBSD after revision 1.110 import: + * 1.119 - don't m_copydata() beyond the len of mbuf in pfsync_input() * 1.118, 1.124, 1.148, 1.149, 1.151, 1.171 - fixes to bulk updates * 1.120, 1.175 - use monotonic time_uptime * 1.122 - reduce number of updates for non-TCP sessions @@ -566,7 +567,7 @@ pfsync_input(struct mbuf *m, __unused int off) struct pfsync_header *ph; struct pfsync_subheader subh; - int offset; + int offset, len; int rv; uint16_t count; @@ -612,6 +613,12 @@ pfsync_input(struct mbuf *m, __unused int off) goto done; } + len = ntohs(ph->len) + offset; + if (m->m_pkthdr.len < len) { + pfsyncstats.pfsyncs_badlen++; + goto done; + } + /* Cheaper to grab this now than having to mess with mbufs later */ pkt.ip = ip; pkt.src = ip->ip_src; @@ -626,7 +633,7 @@ pfsync_input(struct mbuf *m, __unused int off) pkt.flags |= PFSYNC_SI_CKSUM; offset += sizeof(*ph); - for (;;) { + while (offset <= len - sizeof(subh)) { m_copydata(m, offset, sizeof(subh), (caddr_t)&subh); offset += sizeof(subh); @@ -1222,8 +1229,8 @@ static int pfsync_in_eof(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count) { /* check if we are at the right place in the packet */ - if (offset != m->m_pkthdr.len - sizeof(struct pfsync_eof)) - V_pfsyncstats.pfsyncs_badact++; + if (offset != m->m_pkthdr.len) + V_pfsyncstats.pfsyncs_badlen++; /* we're done. free and let the caller return */ m_freem(m); @@ -1592,8 +1599,6 @@ pfsync_sendout(int schedswi) subh->count = htons(1); V_pfsyncstats.pfsyncs_oacts[PFSYNC_ACT_EOF]++; - /* XXX write checksum in EOF here */ - /* we're done, let's put it on the wire */ if (ifp->if_bpf) { m->m_data += sizeof(*ip); |