DF-0414 / fix.diff
diff --git a/sys/netgraph/pppoe/ng_pppoe.c b/sys/netgraph/pppoe/ng_pppoe.c --- a/sys/netgraph/pppoe/ng_pppoe.c +++ b/sys/netgraph/pppoe/ng_pppoe.c @@ -967,6 +967,24 @@ LEAVE(EMSGSIZE); } + /* + * Sanity-check the PPPoE payload length field against + * the actual mbuf size. get_tag()/scan_tags() use + * ph->length as the walk bound (next_tag() at line ~275 + * computes end = &ph->tag[0] + ph->length), so an + * attacker-controlled ph->length that exceeds the real + * payload drives those walkers into an out-of-bounds + * kernel heap read. The session branch already + * performs the equivalent check after m_adj(); the + * discovery branch omitted it. Drop the frame if the + * claimed length does not fit in the mbuf we have. + * (m_pullup above guarantees m_pkthdr.len >= sizeof(*wh).) + */ + if (m->m_pkthdr.len - sizeof(*wh) < length) { + kprintf("pppoe: discovery ph->length too large\n"); + LEAVE(EMSGSIZE); + } + switch(code) { case PADI_CODE: /* |