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.
This commit is contained in:
Gleb Smirnoff 2012-12-13 12:51:22 +00:00
parent feaa4dd2d0
commit 9ff7e6e922

View File

@ -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);