PR/48198: Peter Bex: Avoid kernel panic caused by setting a very small bpf
buffer size. XXX: Pullup -6
This commit is contained in:
parent
2e16209595
commit
4a5538bfa8
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bpf.c,v 1.175 2013/08/30 15:00:08 rmind Exp $ */
|
||||
/* $NetBSD: bpf.c,v 1.176 2013/09/09 20:53:51 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1990, 1991, 1993
|
||||
|
@ -39,7 +39,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.175 2013/08/30 15:00:08 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.176 2013/09/09 20:53:51 christos Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_bpf.h"
|
||||
|
@ -1576,11 +1576,8 @@ static void
|
|||
catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen, u_int snaplen,
|
||||
void *(*cpfn)(void *, const void *, size_t), struct timespec *ts)
|
||||
{
|
||||
struct bpf_hdr *hp;
|
||||
#ifdef _LP64
|
||||
struct bpf_hdr32 *hp32;
|
||||
#endif
|
||||
int totlen, curlen;
|
||||
char *h;
|
||||
int totlen, curlen, caplen;
|
||||
int hdrlen = bpf_hdrlen(d);
|
||||
int do_wakeup = 0;
|
||||
|
||||
|
@ -1595,6 +1592,13 @@ catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen, u_int snaplen,
|
|||
totlen = hdrlen + min(snaplen, pktlen);
|
||||
if (totlen > d->bd_bufsize)
|
||||
totlen = d->bd_bufsize;
|
||||
/*
|
||||
* If we adjusted totlen to fit the bufsize, it could be that
|
||||
* totlen is smaller than hdrlen because of the link layer header.
|
||||
*/
|
||||
caplen = totlen - hdrlen;
|
||||
if (caplen < 0)
|
||||
caplen = 0;
|
||||
|
||||
/*
|
||||
* Round up the end of the previous packet to the next longword.
|
||||
|
@ -1635,33 +1639,34 @@ catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen, u_int snaplen,
|
|||
/*
|
||||
* Append the bpf header.
|
||||
*/
|
||||
h = (char *)d->bd_sbuf + curlen;
|
||||
#ifdef _LP64
|
||||
if (d->bd_compat32) {
|
||||
hp32 = (struct bpf_hdr32 *)((char *)d->bd_sbuf + curlen);
|
||||
struct bpf_hdr32 *hp32;
|
||||
|
||||
hp32 = (struct bpf_hdr32 *)h;
|
||||
hp32->bh_tstamp.tv_sec = ts->tv_sec;
|
||||
hp32->bh_tstamp.tv_usec = ts->tv_nsec / 1000;
|
||||
hp32->bh_datalen = pktlen;
|
||||
hp32->bh_hdrlen = hdrlen;
|
||||
/*
|
||||
* Copy the packet data into the store buffer and update its length.
|
||||
*/
|
||||
(*cpfn)((u_char *)hp32 + hdrlen, pkt,
|
||||
(hp32->bh_caplen = totlen - hdrlen));
|
||||
hp32->bh_caplen = caplen;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
hp = (struct bpf_hdr *)((char *)d->bd_sbuf + curlen);
|
||||
struct bpf_hdr *hp;
|
||||
|
||||
hp = (struct bpf_hdr *)h;
|
||||
hp->bh_tstamp.tv_sec = ts->tv_sec;
|
||||
hp->bh_tstamp.tv_usec = ts->tv_nsec / 1000;
|
||||
hp->bh_datalen = pktlen;
|
||||
hp->bh_hdrlen = hdrlen;
|
||||
/*
|
||||
* Copy the packet data into the store buffer and update
|
||||
* its length.
|
||||
*/
|
||||
(*cpfn)((u_char *)hp + hdrlen, pkt,
|
||||
(hp->bh_caplen = totlen - hdrlen));
|
||||
hp->bh_caplen = caplen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the packet data into the store buffer and update its length.
|
||||
*/
|
||||
(*cpfn)(h + hdrlen, pkt, caplen);
|
||||
d->bd_slen = curlen + totlen;
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue