summaryrefslogtreecommitdiffstats
path: root/sys/netpfil
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2012-12-13 12:51:22 +0000
committerglebius <glebius@FreeBSD.org>2012-12-13 12:51:22 +0000
commit9ffc5fc1ccef66b1ce687f4fe78278f23479a400 (patch)
tree84176de114263a35d9ffab299c62a27cfa5710f0 /sys/netpfil
parentd370f96d4ccd311d5725056967234b35a54039d2 (diff)
downloadFreeBSD-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.
Diffstat (limited to 'sys/netpfil')
-rw-r--r--sys/netpfil/pf/if_pfsync.c17
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);
OpenPOWER on IntegriCloud