summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2003-11-24 05:39:43 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2003-11-24 05:39:43 +0000
commit2a9ff3e18bdb65b9d8f6074f323d7bfcd5e39e50 (patch)
tree0cf273908034c703eb913529fab932c543824a83 /lib
parentd4477774eb9c9f6004440b0e8be6acd84ec3bd62 (diff)
prevent double-free; from aldo@nullcube.com; dhartmei@ ok
Diffstat (limited to 'lib')
-rw-r--r--lib/libpcap/pcap-bpf.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/lib/libpcap/pcap-bpf.c b/lib/libpcap/pcap-bpf.c
index 19ddc88f20e..c2ed883de2b 100644
--- a/lib/libpcap/pcap-bpf.c
+++ b/lib/libpcap/pcap-bpf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcap-bpf.c,v 1.12 2000/04/26 21:25:53 jakob Exp $ */
+/* $OpenBSD: pcap-bpf.c,v 1.13 2003/11/24 05:39:42 mickey Exp $ */
/*
* Copyright (c) 1993, 1994, 1995, 1996, 1998
@@ -22,7 +22,7 @@
*/
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /cvs/OpenBSD/src/lib/libpcap/pcap-bpf.c,v 1.12 2000/04/26 21:25:53 jakob Exp $ (LBL)";
+ "@(#) $Header: /cvs/OpenBSD/src/lib/libpcap/pcap-bpf.c,v 1.13 2003/11/24 05:39:42 mickey Exp $ (LBL)";
#endif
#include <sys/param.h> /* optionally get BSD define */
@@ -274,16 +274,25 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
+ int buflen;
/*
* It looks that BPF code generated by gen_protochain() is not
* compatible with some of kernel BPF code (for example BSD/OS 3.1).
* Take a safer side for now.
*/
- if (no_optimize)
- p->fcode = *fp;
- else if (p->sf.rfile != NULL)
- p->fcode = *fp;
- else if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
+ if (no_optimize || (p->sf.rfile != NULL)){
+ if (p->fcode.bf_insns != NULL)
+ pcap_freecode(&p->fcode);
+ buflen = sizeof(*fp->bf_insns) * fp->bf_len;
+ p->fcode.bf_len = fp->bf_len;
+ p->fcode.bf_insns = malloc(buflen);
+ if (p->fcode.bf_insns == NULL) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
+ pcap_strerror(errno));
+ return (-1);
+ }
+ memcpy(p->fcode.bf_insns, fp->bf_insns, buflen);
+ } else if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
pcap_strerror(errno));
return (-1);