Package init
This commit is contained in:
parent
81b8d9f850
commit
56c42d0d03
@ -25,3 +25,4 @@ index f5a7e0c..f220e68 100644
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
|
||||
@ -86,3 +86,4 @@ index 206be3b..75f2c9f 100644
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
From b9fa92532328daad84766753422e8a21fd474e6f Mon Sep 17 00:00:00 2001
|
||||
From: Michal Sekletar <msekleta@redhat.com>
|
||||
Date: Mon, 29 Sep 2014 08:37:25 +0200
|
||||
Subject: [PATCH 3/4] pcap-linux: apparently ctc interfaces on s390 has
|
||||
ethernet DLT
|
||||
|
||||
---
|
||||
pcap-linux.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/pcap-linux.c b/pcap-linux.c
|
||||
index 900ebbc..58292c3 100644
|
||||
--- a/pcap-linux.c
|
||||
+++ b/pcap-linux.c
|
||||
@@ -3197,6 +3197,10 @@ activate_new(pcap_t *handle)
|
||||
handle->linktype = DLT_LINUX_SLL;
|
||||
}
|
||||
|
||||
+ /* Hack to make things work on s390 ctc interfaces */
|
||||
+ if (strncmp("ctc", device, 3) == 0)
|
||||
+ handle->linktype = DLT_EN10MB;
|
||||
+
|
||||
handlep->ifindex = iface_get_id(sock_fd, device,
|
||||
handle->errbuf);
|
||||
if (handlep->ifindex == -1) {
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
@ -1,24 +0,0 @@
|
||||
From 40fe5f21bae1847a92f18efdcc8ad061db8f6cce Mon Sep 17 00:00:00 2001
|
||||
From: Guy Harris <guy@alum.mit.edu>
|
||||
Date: Thu, 7 Mar 2019 22:05:24 -0800
|
||||
Subject: [PATCH 12/83] Plug a file descriptor leak.
|
||||
|
||||
---
|
||||
savefile.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/savefile.c b/savefile.c
|
||||
index 01ee7d0..c6c0cb8 100644
|
||||
--- a/savefile.c
|
||||
+++ b/savefile.c
|
||||
@@ -317,6 +317,7 @@ pcap_t* pcap_hopen_offline_with_tstamp_precision(intptr_t osfd, u_int precision,
|
||||
{
|
||||
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "_fdopen");
|
||||
+ _close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,291 +0,0 @@
|
||||
From 4ccdc8a3cbf5195a7c089002136e53db541b36ba Mon Sep 17 00:00:00 2001
|
||||
From: Guy Harris <guy@alum.mit.edu>
|
||||
Date: Tue, 19 Mar 2019 11:03:40 -0700
|
||||
Subject: [PATCH 36/83] Use the snapshot length to set the buffer size, and set
|
||||
the len field properly.
|
||||
|
||||
The USB buffer size limits the number of bytes worth of data that is
|
||||
saved; set the buffer size based on the snapshot length. Limit the
|
||||
buffer size values to the range of values the kernel supports, and
|
||||
adjust the reported snapshot length if we can't set the buffer size
|
||||
large enough for the requested snapshot length.
|
||||
|
||||
When reading packets, for packets with URB data, set the len field based
|
||||
on the urb_len field rather than the data_len field, so it reflects how
|
||||
much data was transferred in the transaction rather than how much of
|
||||
that data was actually provided by the USB monitor mechanism.
|
||||
|
||||
Fix usb_read_linux_mmap() to use sizeof(pcap_usb_header_mmapped) rather
|
||||
than sizeof(pcap_usb_header) everywhere, as pcap_usb_header_mmapped is
|
||||
the structure being supplied as the metadata header.
|
||||
|
||||
This should fix GitHub issue #808.
|
||||
---
|
||||
pcap-usb-linux.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 178 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/pcap-usb-linux.c b/pcap-usb-linux.c
|
||||
index 3e70a8d..f202cb6 100644
|
||||
--- a/pcap-usb-linux.c
|
||||
+++ b/pcap-usb-linux.c
|
||||
@@ -381,18 +381,102 @@ usb_findalldevs(pcap_if_list_t *devlistp, char *err_str)
|
||||
}
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Matches what's in mon_bin.c in the Linux kernel.
|
||||
+ */
|
||||
+#define MIN_RING_SIZE (8*1024)
|
||||
+#define MAX_RING_SIZE (1200*1024)
|
||||
+
|
||||
+static int
|
||||
+usb_set_ring_size(pcap_t* handle, size_t header_size)
|
||||
+{
|
||||
+ /*
|
||||
+ * A packet from binary usbmon has:
|
||||
+ *
|
||||
+ * 1) a fixed-length header, of size header_size;
|
||||
+ * 2) descriptors, for isochronous transfers;
|
||||
+ * 3) the payload.
|
||||
+ *
|
||||
+ * The kernel buffer has a size, defaulting to 300KB, with a
|
||||
+ * minimum of 8KB and a maximum of 1200KB. The size is set with
|
||||
+ * the MON_IOCT_RING_SIZE ioctl; the size passed in is rounded up
|
||||
+ * to a page size.
|
||||
+ *
|
||||
+ * No more than {buffer size}/5 bytes worth of payload is saved.
|
||||
+ * Therefore, if we subtract the fixed-length size from the
|
||||
+ * snapshot length, we have the biggest payload we want (we
|
||||
+ * don't worry about the descriptors - if we have descriptors,
|
||||
+ * we'll just discard the last bit of the payload to get it
|
||||
+ * to fit). We multiply that result by 5 and set the buffer
|
||||
+ * size to that value.
|
||||
+ */
|
||||
+ int ring_size;
|
||||
+
|
||||
+ if ((size_t)handle->snapshot < header_size)
|
||||
+ handle->snapshot = header_size;
|
||||
+ /* The maximum snapshot size is small enough that this won't overflow */
|
||||
+ ring_size = (handle->snapshot - header_size) * 5;
|
||||
+
|
||||
+ /*
|
||||
+ * Will this get an error?
|
||||
+ * (There's no wqy to query the minimum or maximum, so we just
|
||||
+ * copy the value from the kernel source. We don't round it
|
||||
+ * up to a multiple of the page size.)
|
||||
+ */
|
||||
+ if (ring_size > MAX_RING_SIZE) {
|
||||
+ /*
|
||||
+ * Yes. Lower the ring size to the maximum, and set the
|
||||
+ * snapshot length to the value that would give us a
|
||||
+ * maximum-size ring.
|
||||
+ */
|
||||
+ ring_size = MAX_RING_SIZE;
|
||||
+ handle->snapshot = header_size + (MAX_RING_SIZE/5);
|
||||
+ } else if (ring_size < MIN_RING_SIZE) {
|
||||
+ /*
|
||||
+ * Yes. Raise the ring size to the minimum, but leave
|
||||
+ * the snapshot length unchanged, so we show the
|
||||
+ * callback no more data than specified by the
|
||||
+ * snapshot length.
|
||||
+ */
|
||||
+ ring_size = MIN_RING_SIZE;
|
||||
+ }
|
||||
+
|
||||
+ if (ioctl(handle->fd, MON_IOCT_RING_SIZE, ring_size) == -1) {
|
||||
+ pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
+ errno, "Can't set ring size from fd %d", handle->fd);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ return ring_size;
|
||||
+}
|
||||
+
|
||||
static
|
||||
int usb_mmap(pcap_t* handle)
|
||||
{
|
||||
struct pcap_usb_linux *handlep = handle->priv;
|
||||
- int len = ioctl(handle->fd, MON_IOCQ_RING_SIZE);
|
||||
- if (len < 0)
|
||||
+ int len;
|
||||
+
|
||||
+ /*
|
||||
+ * Attempt to set the ring size as appropriate for the snapshot
|
||||
+ * length, reducing the snapshot length if that'd make the ring
|
||||
+ * bigger than the kernel supports.
|
||||
+ */
|
||||
+ len = usb_set_ring_size(handle, sizeof(pcap_usb_header_mmapped));
|
||||
+ if (len == -1) {
|
||||
+ /* Failed. Fall back on non-memory-mapped access. */
|
||||
return 0;
|
||||
+ }
|
||||
|
||||
handlep->mmapbuflen = len;
|
||||
handlep->mmapbuf = mmap(0, handlep->mmapbuflen, PROT_READ,
|
||||
MAP_SHARED, handle->fd, 0);
|
||||
- return handlep->mmapbuf != MAP_FAILED;
|
||||
+ if (handlep->mmapbuf == MAP_FAILED) {
|
||||
+ /*
|
||||
+ * Failed. We don't treat that as a fatal error, we
|
||||
+ * just try to fall back on non-memory-mapped access.
|
||||
+ */
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LINUX_USBDEVICE_FS_H
|
||||
@@ -606,6 +690,7 @@ usb_activate(pcap_t* handle)
|
||||
/* try to use fast mmap access */
|
||||
if (usb_mmap(handle))
|
||||
{
|
||||
+ /* We succeeded. */
|
||||
handle->linktype = DLT_USB_LINUX_MMAPPED;
|
||||
handle->stats_op = usb_stats_linux_bin;
|
||||
handle->read_op = usb_read_linux_mmap;
|
||||
@@ -622,7 +707,19 @@ usb_activate(pcap_t* handle)
|
||||
return 0;
|
||||
}
|
||||
|
||||
- /* can't mmap, use plain binary interface access */
|
||||
+ /*
|
||||
+ * We failed; try plain binary interface access.
|
||||
+ *
|
||||
+ * Attempt to set the ring size as appropriate for
|
||||
+ * the snapshot length, reducing the snapshot length
|
||||
+ * if that'd make the ring bigger than the kernel
|
||||
+ * supports.
|
||||
+ */
|
||||
+ if (usb_set_ring_size(handle, sizeof(pcap_usb_header)) == -1) {
|
||||
+ /* Failed. */
|
||||
+ close(handle->fd);
|
||||
+ return PCAP_ERROR;
|
||||
+ }
|
||||
handle->stats_op = usb_stats_linux_bin;
|
||||
handle->read_op = usb_read_linux_bin;
|
||||
#ifdef HAVE_LINUX_USBDEVICE_FS_H
|
||||
@@ -1075,13 +1172,44 @@ usb_read_linux_bin(pcap_t *handle, int max_packets _U_, pcap_handler callback, u
|
||||
return -1;
|
||||
}
|
||||
|
||||
- /* we can get less that than really captured from kernel, depending on
|
||||
- * snaplen, so adjust header accordingly */
|
||||
+ /*
|
||||
+ * info.hdr->data_len is the number of bytes of isochronous
|
||||
+ * descriptors (if any) plus the number of bytes of data
|
||||
+ * provided. There are no isochronous descriptors here,
|
||||
+ * because we're using the old 48-byte header.
|
||||
+ *
|
||||
+ * If info.hdr->data_flag is non-zero, there's no URB data;
|
||||
+ * info.hdr->urb_len is the size of the buffer into which
|
||||
+ * data is to be placed; it does not represent the amount
|
||||
+ * of data transferred. If info.hdr->data_flag is zero,
|
||||
+ * there is URB data, and info.hdr->urb_len is the number
|
||||
+ * of bytes transmitted or received; it doesn't include
|
||||
+ * isochronous descriptors.
|
||||
+ *
|
||||
+ * The kernel may give us more data than the snaplen; if it did,
|
||||
+ * reduce the data length so that the total number of bytes we
|
||||
+ * tell our client we have is not greater than the snaplen.
|
||||
+ */
|
||||
if (info.hdr->data_len < clen)
|
||||
clen = info.hdr->data_len;
|
||||
info.hdr->data_len = clen;
|
||||
- pkth.caplen = clen + sizeof(pcap_usb_header);
|
||||
- pkth.len = info.hdr->data_len + sizeof(pcap_usb_header);
|
||||
+ pkth.caplen = sizeof(pcap_usb_header) + clen;
|
||||
+ if (info.hdr->data_flag) {
|
||||
+ /*
|
||||
+ * No data; just base the on-the-wire length on
|
||||
+ * info.hdr->data_len (so that it's >= the captured
|
||||
+ * length).
|
||||
+ */
|
||||
+ pkth.len = sizeof(pcap_usb_header) + info.hdr->data_len;
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * We got data; base the on-the-wire length on
|
||||
+ * info.hdr->urb_len, so that it includes data
|
||||
+ * discarded by the USB monitor device due to
|
||||
+ * its buffer being too small.
|
||||
+ */
|
||||
+ pkth.len = sizeof(pcap_usb_header) + info.hdr->urb_len;
|
||||
+ }
|
||||
pkth.ts.tv_sec = info.hdr->ts_sec;
|
||||
pkth.ts.tv_usec = info.hdr->ts_usec;
|
||||
|
||||
@@ -1108,12 +1236,12 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
|
||||
struct mon_bin_mfetch fetch;
|
||||
int32_t vec[VEC_SIZE];
|
||||
struct pcap_pkthdr pkth;
|
||||
- pcap_usb_header* hdr;
|
||||
+ pcap_usb_header_mmapped* hdr;
|
||||
int nflush = 0;
|
||||
int packets = 0;
|
||||
u_int clen, max_clen;
|
||||
|
||||
- max_clen = handle->snapshot - sizeof(pcap_usb_header);
|
||||
+ max_clen = handle->snapshot - sizeof(pcap_usb_header_mmapped);
|
||||
|
||||
for (;;) {
|
||||
int i, ret;
|
||||
@@ -1151,19 +1279,52 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
|
||||
nflush = fetch.nfetch;
|
||||
for (i=0; i<fetch.nfetch; ++i) {
|
||||
/* discard filler */
|
||||
- hdr = (pcap_usb_header*) &handlep->mmapbuf[vec[i]];
|
||||
+ hdr = (pcap_usb_header_mmapped*) &handlep->mmapbuf[vec[i]];
|
||||
if (hdr->event_type == '@')
|
||||
continue;
|
||||
|
||||
- /* we can get less that than really captured from kernel, depending on
|
||||
- * snaplen, so adjust header accordingly */
|
||||
+ /*
|
||||
+ * hdr->data_len is the number of bytes of
|
||||
+ * isochronous descriptors (if any) plus the
|
||||
+ * number of bytes of data provided.
|
||||
+ *
|
||||
+ * If hdr->data_flag is non-zero, there's no
|
||||
+ * URB data; hdr->urb_len is the size of the
|
||||
+ * buffer into which data is to be placed; it does
|
||||
+ * not represent the amount of data transferred.
|
||||
+ * If hdr->data_flag is zero, there is URB data,
|
||||
+ * and hdr->urb_len is the number of bytes
|
||||
+ * transmitted or received; it doesn't include
|
||||
+ * isochronous descriptors.
|
||||
+ *
|
||||
+ * The kernel may give us more data than the
|
||||
+ * snaplen; if it did, reduce the data length
|
||||
+ * so that the total number of bytes we
|
||||
+ * tell our client we have is not greater than
|
||||
+ * the snaplen.
|
||||
+ */
|
||||
clen = max_clen;
|
||||
if (hdr->data_len < clen)
|
||||
clen = hdr->data_len;
|
||||
-
|
||||
- /* get packet info from header*/
|
||||
- pkth.caplen = clen + sizeof(pcap_usb_header_mmapped);
|
||||
- pkth.len = hdr->data_len + sizeof(pcap_usb_header_mmapped);
|
||||
+ pkth.caplen = sizeof(pcap_usb_header_mmapped) + clen;
|
||||
+ if (hdr->data_flag) {
|
||||
+ /*
|
||||
+ * No data; just base the on-the-wire length
|
||||
+ * on hdr->data_len (so that it's >= the
|
||||
+ * captured length).
|
||||
+ */
|
||||
+ pkth.len = sizeof(pcap_usb_header_mmapped) +
|
||||
+ hdr->data_len;
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * We got data; base the on-the-wire length
|
||||
+ * on hdr->urb_len, so that it includes
|
||||
+ * data discarded by the USB monitor device
|
||||
+ * due to its buffer being too small.
|
||||
+ */
|
||||
+ pkth.len = sizeof(pcap_usb_header_mmapped) +
|
||||
+ (hdr->ndesc * sizeof (usb_isodesc)) + hdr->urb_len;
|
||||
+ }
|
||||
pkth.ts.tv_sec = hdr->ts_sec;
|
||||
pkth.ts.tv_usec = hdr->ts_usec;
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
@ -1,26 +0,0 @@
|
||||
From 593769c3637583653bafa924fe348115016618c3 Mon Sep 17 00:00:00 2001
|
||||
From: Guy Harris <guy@alum.mit.edu>
|
||||
Date: Fri, 31 May 2019 10:35:25 -0700
|
||||
Subject: [PATCH 66/83] Check for an empty description by checking if the first
|
||||
character is NUL.
|
||||
|
||||
---
|
||||
pcap.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/pcap.c b/pcap.c
|
||||
index d9917a2..0d98519 100644
|
||||
--- a/pcap.c
|
||||
+++ b/pcap.c
|
||||
@@ -802,7 +802,7 @@ get_if_description(const char *name)
|
||||
}
|
||||
#endif /* __FreeBSD__ */
|
||||
close(s);
|
||||
- if (description != NULL && strlen(description) == 0) {
|
||||
+ if (description != NULL && description[0] == '\0') {
|
||||
/*
|
||||
* Description is empty, so discard it.
|
||||
*/
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,38 +0,0 @@
|
||||
From 9157a663d9e845e23697f598994f53f67cfef799 Mon Sep 17 00:00:00 2001
|
||||
From: Tymoteusz Blazejczyk <tymoteusz.blazejczyk@intel.com>
|
||||
Date: Wed, 12 Jun 2019 10:30:32 +0200
|
||||
Subject: [PATCH 68/83] Fixed the fread call in the savefile.c file
|
||||
|
||||
Currently it was an undefined behavior (UB).
|
||||
It passes wrong parameters to the fread function call (1 byte, 4 elements).
|
||||
It should be 4 bytes and 1 element because the `magic` variable is a single 32-bits integer (4 bytes).
|
||||
|
||||
```
|
||||
bytes_read = fread(pointer, number_of_bytes, number_of_elements, file);
|
||||
```
|
||||
|
||||
On some machines the `fread()` call returned 0 with no error from the `ferror()` call with
|
||||
correct and valid PCAP files.
|
||||
|
||||
Reference: https://en.cppreference.com/w/c/io/fread
|
||||
---
|
||||
savefile.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/savefile.c b/savefile.c
|
||||
index 152c917..e6404e7 100644
|
||||
--- a/savefile.c
|
||||
+++ b/savefile.c
|
||||
@@ -359,7 +359,7 @@ pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision,
|
||||
* Windows Sniffer, and Microsoft Network Monitor) all have magic
|
||||
* numbers that are unique in their first 4 bytes.
|
||||
*/
|
||||
- amt_read = fread((char *)&magic, 1, sizeof(magic), fp);
|
||||
+ amt_read = fread(&magic, sizeof(magic), 1, fp);
|
||||
if (amt_read != sizeof(magic)) {
|
||||
if (ferror(fp)) {
|
||||
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
From b0e790519df4ec8204c843987fdfa4aa18e2a3cd Mon Sep 17 00:00:00 2001
|
||||
From: Tymoteusz Blazejczyk <tymoteusz.blazejczyk@intel.com>
|
||||
Date: Wed, 12 Jun 2019 16:01:05 +0200
|
||||
Subject: [PATCH 69/83] Fixed number of elements returned
|
||||
|
||||
---
|
||||
savefile.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/savefile.c b/savefile.c
|
||||
index e6404e7..9e4724b 100644
|
||||
--- a/savefile.c
|
||||
+++ b/savefile.c
|
||||
@@ -360,7 +360,7 @@ pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision,
|
||||
* numbers that are unique in their first 4 bytes.
|
||||
*/
|
||||
amt_read = fread(&magic, sizeof(magic), 1, fp);
|
||||
- if (amt_read != sizeof(magic)) {
|
||||
+ if (amt_read != 1) {
|
||||
if (ferror(fp)) {
|
||||
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "error reading dump file");
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,212 +0,0 @@
|
||||
From 2e9d0ae34ece4d6f67f4d66a4c3628febf0b13dd Mon Sep 17 00:00:00 2001
|
||||
From: Guy Harris <guy@alum.mit.edu>
|
||||
Date: Wed, 12 Jun 2019 11:32:21 -0700
|
||||
Subject: [PATCH 70/83] Read the magic number into a byte array.
|
||||
|
||||
Apparently, in some C implementations, attempting to do an fread() into
|
||||
a variable of a 32-bit unsigned integral type with a size of 1 and a
|
||||
count of 4 returns 0 with an EOF indication; see GitHub pull request
|
||||
|
||||
We can make the size be the size of the variable and the count be 1, but
|
||||
that means that the count returned by an fread() terminated by an EOF
|
||||
will be 0, not the number of bytes successfully read, so the "truncated
|
||||
dump file" message will give an invalid count:
|
||||
|
||||
tcpdump: truncated dump file; tried to read 4 file header bytes,
|
||||
only got 0
|
||||
|
||||
If, instead, we read into an array of 4 bytes, with a size of 1 and a
|
||||
count of 4, we'll get the right short count back.
|
||||
|
||||
Pass the byte array to the file-type-specific "is this a file of this
|
||||
type?" routines, so that if we add support for files where the magic
|
||||
number isn't byte-order dependent (e.g., Microsoft Network Monitor), we
|
||||
can handle them more cleanly (check for the standard magic number as a
|
||||
4-byte array, rather than as its numerical value in both the host's byte
|
||||
order and the byte-swapped byte order).
|
||||
---
|
||||
savefile.c | 8 ++++----
|
||||
sf-pcap.c | 24 ++++++++++++++----------
|
||||
sf-pcap.h | 2 +-
|
||||
sf-pcapng.c | 14 ++++++++------
|
||||
sf-pcapng.h | 2 +-
|
||||
5 files changed, 28 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/savefile.c b/savefile.c
|
||||
index 9e4724b..7adee42 100644
|
||||
--- a/savefile.c
|
||||
+++ b/savefile.c
|
||||
@@ -332,7 +332,7 @@ pcap_t* pcap_hopen_offline(intptr_t osfd, char *errbuf)
|
||||
}
|
||||
#endif
|
||||
|
||||
-static pcap_t *(*check_headers[])(bpf_u_int32, FILE *, u_int, char *, int *) = {
|
||||
+static pcap_t *(*check_headers[])(const uint8_t *, FILE *, u_int, char *, int *) = {
|
||||
pcap_check_header,
|
||||
pcap_ng_check_header
|
||||
};
|
||||
@@ -347,7 +347,7 @@ pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision,
|
||||
char *errbuf)
|
||||
{
|
||||
register pcap_t *p;
|
||||
- bpf_u_int32 magic;
|
||||
+ uint8_t magic[4];
|
||||
size_t amt_read;
|
||||
u_int i;
|
||||
int err;
|
||||
@@ -359,8 +359,8 @@ pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision,
|
||||
* Windows Sniffer, and Microsoft Network Monitor) all have magic
|
||||
* numbers that are unique in their first 4 bytes.
|
||||
*/
|
||||
- amt_read = fread(&magic, sizeof(magic), 1, fp);
|
||||
- if (amt_read != 1) {
|
||||
+ amt_read = fread(&magic, 1, sizeof(magic), fp);
|
||||
+ if (amt_read != sizeof(magic)) {
|
||||
if (ferror(fp)) {
|
||||
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "error reading dump file");
|
||||
diff --git a/sf-pcap.c b/sf-pcap.c
|
||||
index 87fc5ce..f56fff7 100644
|
||||
--- a/sf-pcap.c
|
||||
+++ b/sf-pcap.c
|
||||
@@ -150,9 +150,10 @@ struct pcap_sf {
|
||||
* relevant information from the header.
|
||||
*/
|
||||
pcap_t *
|
||||
-pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
+pcap_check_header(const uint8_t *magic, FILE *fp, u_int precision, char *errbuf,
|
||||
int *err)
|
||||
{
|
||||
+ bpf_u_int32 magic_int;
|
||||
struct pcap_file_header hdr;
|
||||
size_t amt_read;
|
||||
pcap_t *p;
|
||||
@@ -169,11 +170,14 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
* number for a pcap savefile, or for a byte-swapped pcap
|
||||
* savefile.
|
||||
*/
|
||||
- if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC &&
|
||||
- magic != NSEC_TCPDUMP_MAGIC) {
|
||||
- magic = SWAPLONG(magic);
|
||||
- if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC &&
|
||||
- magic != NSEC_TCPDUMP_MAGIC)
|
||||
+ memcpy(&magic_int, magic, sizeof(magic_int));
|
||||
+ if (magic_int != TCPDUMP_MAGIC &&
|
||||
+ magic_int != KUZNETZOV_TCPDUMP_MAGIC &&
|
||||
+ magic_int != NSEC_TCPDUMP_MAGIC) {
|
||||
+ magic_int = SWAPLONG(magic_int);
|
||||
+ if (magic_int != TCPDUMP_MAGIC &&
|
||||
+ magic_int != KUZNETZOV_TCPDUMP_MAGIC &&
|
||||
+ magic_int != NSEC_TCPDUMP_MAGIC)
|
||||
return (NULL); /* nope */
|
||||
swapped = 1;
|
||||
}
|
||||
@@ -182,7 +186,7 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
* They are. Put the magic number in the header, and read
|
||||
* the rest of the header.
|
||||
*/
|
||||
- hdr.magic = magic;
|
||||
+ hdr.magic = magic_int;
|
||||
amt_read = fread(((char *)&hdr) + sizeof hdr.magic, 1,
|
||||
sizeof(hdr) - sizeof(hdr.magic), fp);
|
||||
if (amt_read != sizeof(hdr) - sizeof(hdr.magic)) {
|
||||
@@ -273,7 +277,7 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
switch (precision) {
|
||||
|
||||
case PCAP_TSTAMP_PRECISION_MICRO:
|
||||
- if (magic == NSEC_TCPDUMP_MAGIC) {
|
||||
+ if (magic_int == NSEC_TCPDUMP_MAGIC) {
|
||||
/*
|
||||
* The file has nanoseconds, the user
|
||||
* wants microseconds; scale the
|
||||
@@ -290,7 +294,7 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
break;
|
||||
|
||||
case PCAP_TSTAMP_PRECISION_NANO:
|
||||
- if (magic == NSEC_TCPDUMP_MAGIC) {
|
||||
+ if (magic_int == NSEC_TCPDUMP_MAGIC) {
|
||||
/*
|
||||
* The file has nanoseconds, the
|
||||
* user wants nanoseconds; nothing to do.
|
||||
@@ -344,7 +348,7 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
break;
|
||||
}
|
||||
|
||||
- if (magic == KUZNETZOV_TCPDUMP_MAGIC) {
|
||||
+ if (magic_int == KUZNETZOV_TCPDUMP_MAGIC) {
|
||||
/*
|
||||
* XXX - the patch that's in some versions of libpcap
|
||||
* changes the packet header but not the magic number,
|
||||
diff --git a/sf-pcap.h b/sf-pcap.h
|
||||
index e9c7eaf..bc7150f 100644
|
||||
--- a/sf-pcap.h
|
||||
+++ b/sf-pcap.h
|
||||
@@ -31,7 +31,7 @@
|
||||
#ifndef sf_pcap_h
|
||||
#define sf_pcap_h
|
||||
|
||||
-extern pcap_t *pcap_check_header(bpf_u_int32 magic, FILE *fp,
|
||||
+extern pcap_t *pcap_check_header(const uint8_t *magic, FILE *fp,
|
||||
u_int precision, char *errbuf, int *err);
|
||||
|
||||
#endif
|
||||
diff --git a/sf-pcapng.c b/sf-pcapng.c
|
||||
index 7394ce4..52f795f 100644
|
||||
--- a/sf-pcapng.c
|
||||
+++ b/sf-pcapng.c
|
||||
@@ -761,9 +761,10 @@ add_interface(pcap_t *p, struct block_cursor *cursor, char *errbuf)
|
||||
* relevant information from the header.
|
||||
*/
|
||||
pcap_t *
|
||||
-pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
- int *err)
|
||||
+pcap_ng_check_header(const uint8_t *magic, FILE *fp, u_int precision,
|
||||
+ char *errbuf, int *err)
|
||||
{
|
||||
+ bpf_u_int32 magic_int;
|
||||
size_t amt_read;
|
||||
bpf_u_int32 total_length;
|
||||
bpf_u_int32 byte_order_magic;
|
||||
@@ -785,7 +786,8 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
* Check whether the first 4 bytes of the file are the block
|
||||
* type for a pcapng savefile.
|
||||
*/
|
||||
- if (magic != BT_SHB) {
|
||||
+ memcpy(&magic_int, magic, sizeof(magic_int));
|
||||
+ if (magic_int != BT_SHB) {
|
||||
/*
|
||||
* XXX - check whether this looks like what the block
|
||||
* type would be after being munged by mapping between
|
||||
@@ -944,12 +946,12 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
*/
|
||||
bhdrp = (struct block_header *)p->buffer;
|
||||
shbp = (struct section_header_block *)((u_char *)p->buffer + sizeof(struct block_header));
|
||||
- bhdrp->block_type = magic;
|
||||
+ bhdrp->block_type = magic_int;
|
||||
bhdrp->total_length = total_length;
|
||||
shbp->byte_order_magic = byte_order_magic;
|
||||
if (read_bytes(fp,
|
||||
- (u_char *)p->buffer + (sizeof(magic) + sizeof(total_length) + sizeof(byte_order_magic)),
|
||||
- total_length - (sizeof(magic) + sizeof(total_length) + sizeof(byte_order_magic)),
|
||||
+ (u_char *)p->buffer + (sizeof(magic_int) + sizeof(total_length) + sizeof(byte_order_magic)),
|
||||
+ total_length - (sizeof(magic_int) + sizeof(total_length) + sizeof(byte_order_magic)),
|
||||
1, errbuf) == -1)
|
||||
goto fail;
|
||||
|
||||
diff --git a/sf-pcapng.h b/sf-pcapng.h
|
||||
index d99b0d4..835082a 100644
|
||||
--- a/sf-pcapng.h
|
||||
+++ b/sf-pcapng.h
|
||||
@@ -26,7 +26,7 @@
|
||||
#ifndef sf_pcapng_h
|
||||
#define sf_pcapng_h
|
||||
|
||||
-extern pcap_t *pcap_ng_check_header(bpf_u_int32 magic, FILE *fp,
|
||||
+extern pcap_t *pcap_ng_check_header(const uint8_t *magic, FILE *fp,
|
||||
u_int precision, char *errbuf, int *err);
|
||||
|
||||
#endif
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
@ -1,171 +0,0 @@
|
||||
From f542342e5e232c9ed522b99897cf7aedccc89fe8 Mon Sep 17 00:00:00 2001
|
||||
From: Guy Harris <guy@alum.mit.edu>
|
||||
Date: Tue, 25 Jun 2019 01:55:16 -0700
|
||||
Subject: [PATCH 75/83] Use "ab+" rather than "rb+" for the
|
||||
pcap_dump_open_append() open mode.
|
||||
|
||||
That way, the file will be created if it doesn't exist.
|
||||
|
||||
Do a seek to the beginning of the file before checking whether it has a
|
||||
file header; ISO C says it's implementation-defined whether an open in
|
||||
append mode puts the file position indicator at the beginning or the end
|
||||
of the file, and neither the Single UNIX Specification nor the Microsoft
|
||||
documentation seemed to indicate which of those are the case.
|
||||
|
||||
Consistently cast the result of fclose() on an open failure to void -
|
||||
we've already gotten an error, so we don't care whether the close fails
|
||||
as well.
|
||||
|
||||
Clean up an error message slightly.
|
||||
|
||||
See GitHub issue #247.
|
||||
---
|
||||
sf-pcap.c | 51 +++++++++++++++++++++++++++++++++++++++------------
|
||||
1 file changed, 39 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/sf-pcap.c b/sf-pcap.c
|
||||
index f56fff7..23057a0 100644
|
||||
--- a/sf-pcap.c
|
||||
+++ b/sf-pcap.c
|
||||
@@ -930,11 +930,19 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
|
||||
return (pcap_setup_dump(p, linktype, stdout, "standard output"));
|
||||
|
||||
/*
|
||||
+ * "a" will cause the file *not* to be truncated if it exists
|
||||
+ * but will cause it to be created if it doesn't. It will
|
||||
+ * also cause all writes to be done at the end of the file,
|
||||
+ * but will allow reads to be done anywhere in the file. This
|
||||
+ * is what we need, because we need to read from the beginning
|
||||
+ * of the file to see if it already has a header and packets
|
||||
+ * or if it doesn't.
|
||||
+ *
|
||||
* "b" is supported as of C90, so *all* UN*Xes should support it,
|
||||
* even though it does nothing. It's required on Windows, as the
|
||||
* file is a binary file and must be read in binary mode.
|
||||
*/
|
||||
- f = fopen(fname, "rb+");
|
||||
+ f = fopen(fname, "ab+");
|
||||
if (f == NULL) {
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "%s", fname);
|
||||
@@ -943,18 +951,33 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
|
||||
|
||||
/*
|
||||
* Try to read a pcap header.
|
||||
+ *
|
||||
+ * We do not assume that the file will be positioned at the
|
||||
+ * beginning immediately after we've opened it - we seek to
|
||||
+ * the beginning. ISO C says it's implementation-defined
|
||||
+ * whether the file position indicator is at the beginning
|
||||
+ * or the end of the file after an append-mode open, and
|
||||
+ * it wasn't obvious from the Single UNIX Specification
|
||||
+ * or the Microsoft documentation how that works on SUS-
|
||||
+ * compliant systems or on Windows.
|
||||
*/
|
||||
+ if (fseek(f, 0, SEEK_SET) == -1) {
|
||||
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
+ errno, "Can't seek to the beginning of %s", fname);
|
||||
+ (void)fclose(f);
|
||||
+ return (NULL);
|
||||
+ }
|
||||
amt_read = fread(&ph, 1, sizeof (ph), f);
|
||||
if (amt_read != sizeof (ph)) {
|
||||
if (ferror(f)) {
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "%s", fname);
|
||||
- fclose(f);
|
||||
+ (void)fclose(f);
|
||||
return (NULL);
|
||||
} else if (feof(f) && amt_read > 0) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: truncated pcap file header", fname);
|
||||
- fclose(f);
|
||||
+ (void)fclose(f);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
@@ -990,7 +1013,7 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
|
||||
if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_MICRO) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: different time stamp precision, cannot append to file", fname);
|
||||
- fclose(f);
|
||||
+ (void)fclose(f);
|
||||
return (NULL);
|
||||
}
|
||||
break;
|
||||
@@ -999,7 +1022,7 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
|
||||
if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_NANO) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: different time stamp precision, cannot append to file", fname);
|
||||
- fclose(f);
|
||||
+ (void)fclose(f);
|
||||
return (NULL);
|
||||
}
|
||||
break;
|
||||
@@ -1008,7 +1031,7 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
|
||||
case SWAPLONG(NSEC_TCPDUMP_MAGIC):
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: different byte order, cannot append to file", fname);
|
||||
- fclose(f);
|
||||
+ (void)fclose(f);
|
||||
return (NULL);
|
||||
|
||||
case KUZNETZOV_TCPDUMP_MAGIC:
|
||||
@@ -1017,13 +1040,13 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
|
||||
case SWAPLONG(NAVTEL_TCPDUMP_MAGIC):
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: not a pcap file to which we can append", fname);
|
||||
- fclose(f);
|
||||
+ (void)fclose(f);
|
||||
return (NULL);
|
||||
|
||||
default:
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: not a pcap file", fname);
|
||||
- fclose(f);
|
||||
+ (void)fclose(f);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@@ -1035,19 +1058,19 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: version is %u.%u, cannot append to file", fname,
|
||||
ph.version_major, ph.version_minor);
|
||||
- fclose(f);
|
||||
+ (void)fclose(f);
|
||||
return (NULL);
|
||||
}
|
||||
if ((bpf_u_int32)linktype != ph.linktype) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: different linktype, cannot append to file", fname);
|
||||
- fclose(f);
|
||||
+ (void)fclose(f);
|
||||
return (NULL);
|
||||
}
|
||||
if ((bpf_u_int32)p->snapshot != ph.snaplen) {
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"%s: different snaplen, cannot append to file", fname);
|
||||
- fclose(f);
|
||||
+ (void)fclose(f);
|
||||
return (NULL);
|
||||
}
|
||||
} else {
|
||||
@@ -1064,10 +1087,14 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
|
||||
|
||||
/*
|
||||
* Start writing at the end of the file.
|
||||
+ *
|
||||
+ * XXX - this shouldn't be necessary, given that we're opening
|
||||
+ * the file in append mode, and ISO C specifies that all writes
|
||||
+ * are done at the end of the file in that mode.
|
||||
*/
|
||||
if (fseek(f, 0, SEEK_END) == -1) {
|
||||
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
- errno, "Can't seek to end of %s", fname);
|
||||
+ errno, "Can't seek to the end of %s", fname);
|
||||
(void)fclose(f);
|
||||
return (NULL);
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
From f22bd1264917671c87bb98e9c66c5734676f3150 Mon Sep 17 00:00:00 2001
|
||||
From: Guy Harris <guy@alum.mit.edu>
|
||||
Date: Sun, 30 Jun 2019 15:42:53 -0700
|
||||
Subject: [PATCH 79/83] Treat both ENXIO and EIO as "device went away".
|
||||
|
||||
ENXIO is used on FreeBSD, DragonFly BSD, and Darwin; EIO is used on
|
||||
OpenBSD.
|
||||
---
|
||||
pcap-bpf.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/pcap-bpf.c b/pcap-bpf.c
|
||||
index 6fe2eaf..62e2ed0 100644
|
||||
--- a/pcap-bpf.c
|
||||
+++ b/pcap-bpf.c
|
||||
@@ -1020,7 +1020,8 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
case EWOULDBLOCK:
|
||||
return (0);
|
||||
|
||||
- case ENXIO:
|
||||
+ case ENXIO: /* FreeBSD, DragonFly BSD, and Darwin */
|
||||
+ case EIO: /* OpenBSD */
|
||||
/*
|
||||
* The device on which we're capturing
|
||||
* went away.
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
@ -1,47 +0,0 @@
|
||||
From 8072538381d3f8f80c6ec643ce52a8355ac5fa65 Mon Sep 17 00:00:00 2001
|
||||
From: Guy Harris <guy@alum.mit.edu>
|
||||
Date: Sun, 30 Jun 2019 19:18:58 -0700
|
||||
Subject: [PATCH 80/83] Change the error message for ENXIO/EIO to match
|
||||
reality.
|
||||
|
||||
If an interface is configured down on one of the *BSDs or a Darwin-based
|
||||
OS, capturing on that interface on a BPF device doesn't get an error;
|
||||
ENXIO/EIO means "the interface went away completely" (e.g., unplugging a
|
||||
hot-pluggable interface, shutting down a dynamically-created PPP link,
|
||||
etc.).
|
||||
---
|
||||
pcap-bpf.c | 10 ++++++----
|
||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/pcap-bpf.c b/pcap-bpf.c
|
||||
index 62e2ed0..3f9e9ad 100644
|
||||
--- a/pcap-bpf.c
|
||||
+++ b/pcap-bpf.c
|
||||
@@ -1022,17 +1022,19 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
||||
|
||||
case ENXIO: /* FreeBSD, DragonFly BSD, and Darwin */
|
||||
case EIO: /* OpenBSD */
|
||||
+ /* NetBSD appears not to return an error in this case */
|
||||
/*
|
||||
* The device on which we're capturing
|
||||
* went away.
|
||||
*
|
||||
* XXX - we should really return
|
||||
- * PCAP_ERROR_IFACE_NOT_UP, but
|
||||
- * pcap_dispatch() etc. aren't
|
||||
- * defined to retur that.
|
||||
+ * an appropriate error for that,
|
||||
+ * but pcap_dispatch() etc. aren't
|
||||
+ * documented as having error returns
|
||||
+ * other than PCAP_ERROR or PCAP_ERROR_BREAK.
|
||||
*/
|
||||
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||
- "The interface went down");
|
||||
+ "The interface disappeared");
|
||||
return (PCAP_ERROR);
|
||||
|
||||
#if defined(sun) && !defined(BSD) && !defined(__svr4__) && !defined(__SVR4)
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
|
||||
@ -1,234 +0,0 @@
|
||||
From bcbef226ca11662342b5e267e7f12066bcfd60d0 Mon Sep 17 00:00:00 2001
|
||||
From: Guy Harris <guy@alum.mit.edu>
|
||||
Date: Wed, 17 Oct 2018 00:59:40 -0700
|
||||
Subject: [PATCH 194/470] Plug some memory leaks.
|
||||
|
||||
For ARCNET and MAC addresses, don't convert them to binary until we get
|
||||
to gen_acode() and gen_ecode(); instead, just save the string in a buffe
|
||||
that's allocated in a way that gets cleaned up when the parser finishes,
|
||||
the same way we do for some other string tokens. Otherwise, if the
|
||||
parser fails before we get to free it, it gets leaked; that was
|
||||
happening.
|
||||
|
||||
Save the generated binary address in the parser state until we're done
|
||||
with it, so that, if a call that uses the parser state calls
|
||||
bpf_error(), the generated binary address gets freed.
|
||||
|
||||
Credit to OSS-Fuzz for finding this issue.
|
||||
---
|
||||
gencode.c | 53 ++++++++++++++++++++++++++++++++++++++++++-----------
|
||||
gencode.h | 4 ++--
|
||||
grammar.y | 25 +++----------------------
|
||||
scanner.l | 10 ++--------
|
||||
4 files changed, 49 insertions(+), 43 deletions(-)
|
||||
|
||||
diff --git a/gencode.c b/gencode.c
|
||||
index 1b20124..7aa9638 100644
|
||||
--- a/gencode.c
|
||||
+++ b/gencode.c
|
||||
@@ -279,6 +279,13 @@ struct _compiler_state {
|
||||
struct addrinfo *ai;
|
||||
|
||||
/*
|
||||
+ * Another thing that's allocated is the result of pcap_ether_aton();
|
||||
+ * it must be freed with free(). This variable points to any
|
||||
+ * address that would need to be freed.
|
||||
+ */
|
||||
+ u_char *e;
|
||||
+
|
||||
+ /*
|
||||
* Various code constructs need to know the layout of the packet.
|
||||
* These values give the necessary offsets from the beginning
|
||||
* of the packet data.
|
||||
@@ -710,6 +717,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
|
||||
#ifdef INET6
|
||||
cstate.ai = NULL;
|
||||
#endif
|
||||
+ cstate.e = NULL;
|
||||
cstate.ic.root = NULL;
|
||||
cstate.ic.cur_mark = 0;
|
||||
cstate.bpf_pcap = p;
|
||||
@@ -720,6 +728,8 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
|
||||
if (cstate.ai != NULL)
|
||||
freeaddrinfo(cstate.ai);
|
||||
#endif
|
||||
+ if (cstate.e != NULL)
|
||||
+ free(cstate.e);
|
||||
rc = -1;
|
||||
goto quit;
|
||||
}
|
||||
@@ -6916,36 +6926,49 @@ gen_mcode6(compiler_state_t *cstate, const char *s1, const char *s2,
|
||||
#endif /*INET6*/
|
||||
|
||||
struct block *
|
||||
-gen_ecode(compiler_state_t *cstate, const u_char *eaddr, struct qual q)
|
||||
+gen_ecode(compiler_state_t *cstate, const char *s, struct qual q)
|
||||
{
|
||||
struct block *b, *tmp;
|
||||
|
||||
if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {
|
||||
+ cstate->e = pcap_ether_aton(s);
|
||||
+ if (cstate->e == NULL)
|
||||
+ bpf_error(cstate, "malloc");
|
||||
switch (cstate->linktype) {
|
||||
case DLT_EN10MB:
|
||||
case DLT_NETANALYZER:
|
||||
case DLT_NETANALYZER_TRANSPARENT:
|
||||
tmp = gen_prevlinkhdr_check(cstate);
|
||||
- b = gen_ehostop(cstate, eaddr, (int)q.dir);
|
||||
+ b = gen_ehostop(cstate, cstate->e, (int)q.dir);
|
||||
if (tmp != NULL)
|
||||
gen_and(tmp, b);
|
||||
- return b;
|
||||
+ break;
|
||||
case DLT_FDDI:
|
||||
- return gen_fhostop(cstate, eaddr, (int)q.dir);
|
||||
+ b = gen_fhostop(cstate, cstate->e, (int)q.dir);
|
||||
+ break;
|
||||
case DLT_IEEE802:
|
||||
- return gen_thostop(cstate, eaddr, (int)q.dir);
|
||||
+ b = gen_thostop(cstate, cstate->e, (int)q.dir);
|
||||
+ break;
|
||||
case DLT_IEEE802_11:
|
||||
case DLT_PRISM_HEADER:
|
||||
case DLT_IEEE802_11_RADIO_AVS:
|
||||
case DLT_IEEE802_11_RADIO:
|
||||
case DLT_PPI:
|
||||
- return gen_wlanhostop(cstate, eaddr, (int)q.dir);
|
||||
+ b = gen_wlanhostop(cstate, cstate->e, (int)q.dir);
|
||||
+ break;
|
||||
case DLT_IP_OVER_FC:
|
||||
- return gen_ipfchostop(cstate, eaddr, (int)q.dir);
|
||||
+ b = gen_ipfchostop(cstate, cstate->e, (int)q.dir);
|
||||
+ break;
|
||||
default:
|
||||
+ free(cstate->e);
|
||||
+ cstate->e = NULL;
|
||||
bpf_error(cstate, "ethernet addresses supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel");
|
||||
+ /* NOTREACHED */
|
||||
break;
|
||||
}
|
||||
+ free(cstate->e);
|
||||
+ cstate->e = NULL;
|
||||
+ return (b);
|
||||
}
|
||||
bpf_error(cstate, "ethernet address used in non-ether expression");
|
||||
/* NOTREACHED */
|
||||
@@ -8127,16 +8150,24 @@ gen_p80211_fcdir(compiler_state_t *cstate, int fcdir)
|
||||
}
|
||||
|
||||
struct block *
|
||||
-gen_acode(compiler_state_t *cstate, const u_char *eaddr, struct qual q)
|
||||
+gen_acode(compiler_state_t *cstate, const char *s, struct qual q)
|
||||
{
|
||||
+ struct block *b;
|
||||
+
|
||||
switch (cstate->linktype) {
|
||||
|
||||
case DLT_ARCNET:
|
||||
case DLT_ARCNET_LINUX:
|
||||
if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) &&
|
||||
- q.proto == Q_LINK)
|
||||
- return (gen_ahostop(cstate, eaddr, (int)q.dir));
|
||||
- else {
|
||||
+ q.proto == Q_LINK) {
|
||||
+ cstate->e = pcap_ether_aton(s);
|
||||
+ if (cstate->e == NULL)
|
||||
+ bpf_error(cstate, "malloc");
|
||||
+ b = gen_ahostop(cstate, cstate->e, (int)q.dir);
|
||||
+ free(cstate->e);
|
||||
+ cstate->e = NULL;
|
||||
+ return (b);
|
||||
+ } else {
|
||||
bpf_error(cstate, "ARCnet address used in non-arc expression");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
diff --git a/gencode.h b/gencode.h
|
||||
index 6a6fda5..e97e90f 100644
|
||||
--- a/gencode.h
|
||||
+++ b/gencode.h
|
||||
@@ -297,8 +297,8 @@ void gen_or(struct block *, struct block *);
|
||||
void gen_not(struct block *);
|
||||
|
||||
struct block *gen_scode(compiler_state_t *, const char *, struct qual);
|
||||
-struct block *gen_ecode(compiler_state_t *, const u_char *, struct qual);
|
||||
-struct block *gen_acode(compiler_state_t *, const u_char *, struct qual);
|
||||
+struct block *gen_ecode(compiler_state_t *, const char *, struct qual);
|
||||
+struct block *gen_acode(compiler_state_t *, const char *, struct qual);
|
||||
struct block *gen_mcode(compiler_state_t *, const char *, const char *,
|
||||
unsigned int, struct qual);
|
||||
#ifdef INET6
|
||||
diff --git a/grammar.y b/grammar.y
|
||||
index 62f9b5f..e3883b5 100644
|
||||
--- a/grammar.y
|
||||
+++ b/grammar.y
|
||||
@@ -307,7 +307,6 @@ DIAG_OFF_BISON_BYACC
|
||||
%union {
|
||||
int i;
|
||||
bpf_u_int32 h;
|
||||
- u_char *e;
|
||||
char *s;
|
||||
struct stmt *stmt;
|
||||
struct arth *a;
|
||||
@@ -363,9 +362,7 @@ DIAG_OFF_BISON_BYACC
|
||||
%token SIO OPC DPC SLS HSIO HOPC HDPC HSLS
|
||||
|
||||
|
||||
-%type <s> ID
|
||||
-%type <e> EID
|
||||
-%type <e> AID
|
||||
+%type <s> ID EID AID
|
||||
%type <s> HID HID6
|
||||
%type <i> NUM action reason type subtype type_subtype dir
|
||||
|
||||
@@ -437,24 +434,8 @@ nid: ID { $$.b = gen_scode(cstate, $1, $$.q = $<blk>0.q); }
|
||||
"in this configuration");
|
||||
#endif /*INET6*/
|
||||
}
|
||||
- | EID {
|
||||
- $$.b = gen_ecode(cstate, $1, $$.q = $<blk>0.q);
|
||||
- /*
|
||||
- * $1 was allocated by "pcap_ether_aton()",
|
||||
- * so we must free it now that we're done
|
||||
- * with it.
|
||||
- */
|
||||
- free($1);
|
||||
- }
|
||||
- | AID {
|
||||
- $$.b = gen_acode(cstate, $1, $$.q = $<blk>0.q);
|
||||
- /*
|
||||
- * $1 was allocated by "pcap_ether_aton()",
|
||||
- * so we must free it now that we're done
|
||||
- * with it.
|
||||
- */
|
||||
- free($1);
|
||||
- }
|
||||
+ | EID { $$.b = gen_ecode(cstate, $1, $$.q = $<blk>0.q); }
|
||||
+ | AID { $$.b = gen_acode(cstate, $1, $$.q = $<blk>0.q); }
|
||||
| not id { gen_not($2.b); $$ = $2; }
|
||||
;
|
||||
not: '!' { $$ = $<blk>0; }
|
||||
diff --git a/scanner.l b/scanner.l
|
||||
index e0890b4..e9565aa 100644
|
||||
--- a/scanner.l
|
||||
+++ b/scanner.l
|
||||
@@ -397,14 +397,8 @@ hsls return HSLS;
|
||||
"==" return '=';
|
||||
"<<" return LSH;
|
||||
">>" return RSH;
|
||||
-${B} { yylval->e = pcap_ether_aton(((char *)yytext)+1);
|
||||
- if (yylval->e == NULL)
|
||||
- bpf_error(yyextra, "malloc");
|
||||
- return AID; }
|
||||
-{MAC} { yylval->e = pcap_ether_aton((char *)yytext);
|
||||
- if (yylval->e == NULL)
|
||||
- bpf_error(yyextra, "malloc");
|
||||
- return EID; }
|
||||
+${B} { yylval->s = sdup(yyextra, yytext); return AID; }
|
||||
+{MAC} { yylval->s = sdup(yyextra, yytext); return EID; }
|
||||
{N} { yylval->i = stoi((char *)yytext); return NUM; }
|
||||
({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N}) {
|
||||
yylval->s = sdup(yyextra, (char *)yytext); return HID; }
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,319 +0,0 @@
|
||||
From 947f2be1e0345bbd6f66f6c945ad51eb7f074e8a Mon Sep 17 00:00:00 2001
|
||||
From: Guy Harris <guy@alum.mit.edu>
|
||||
Date: Wed, 17 Oct 2018 13:29:19 -0700
|
||||
Subject: [PATCH 195/470] Plug some memory leaks.
|
||||
|
||||
The optimizer and code emitter (icode_to_fcode()) allocate their own
|
||||
memory that must be cleaned up if an error is thrown, so we can't use
|
||||
bpf_error(), we need to add our own error routines for them.
|
||||
|
||||
In some cases, just free up the memory before calling bpf_error().
|
||||
|
||||
Credit to OSS-Fuzz for finding this issue.
|
||||
---
|
||||
gencode.c | 25 +++++++++++++---
|
||||
gencode.h | 5 +++-
|
||||
optimize.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++----------
|
||||
3 files changed, 108 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/gencode.c b/gencode.c
|
||||
index 7aa9638..2b18a32 100644
|
||||
--- a/gencode.c
|
||||
+++ b/gencode.c
|
||||
@@ -433,6 +433,25 @@ bpf_parser_error(compiler_state_t *cstate, const char *msg)
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * For use by the optimizer, which needs to do its *own* cleanup before
|
||||
+ * delivering a longjmp-based exception.
|
||||
+ */
|
||||
+void
|
||||
+bpf_vset_error(compiler_state_t *cstate, const char *fmt, va_list ap)
|
||||
+{
|
||||
+ if (cstate->bpf_pcap != NULL)
|
||||
+ (void)pcap_vsnprintf(pcap_geterr(cstate->bpf_pcap),
|
||||
+ PCAP_ERRBUF_SIZE, fmt, ap);
|
||||
+}
|
||||
+
|
||||
+void PCAP_NORETURN
|
||||
+bpf_abort_compilation(compiler_state_t *cstate)
|
||||
+{
|
||||
+ longjmp(cstate->top_ctx, 1);
|
||||
+ /* NOTREACHED */
|
||||
+}
|
||||
+
|
||||
/* VARARGS */
|
||||
void PCAP_NORETURN
|
||||
bpf_error(compiler_state_t *cstate, const char *fmt, ...)
|
||||
@@ -440,11 +459,9 @@ bpf_error(compiler_state_t *cstate, const char *fmt, ...)
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
- if (cstate->bpf_pcap != NULL)
|
||||
- (void)pcap_vsnprintf(pcap_geterr(cstate->bpf_pcap),
|
||||
- PCAP_ERRBUF_SIZE, fmt, ap);
|
||||
+ bpf_vset_error(cstate, fmt, ap);
|
||||
va_end(ap);
|
||||
- longjmp(cstate->top_ctx, 1);
|
||||
+ bpf_abort_compilation(cstate);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
diff --git a/gencode.h b/gencode.h
|
||||
index e97e90f..a819900 100644
|
||||
--- a/gencode.h
|
||||
+++ b/gencode.h
|
||||
@@ -384,8 +384,11 @@ struct icode {
|
||||
int cur_mark;
|
||||
};
|
||||
|
||||
-void bpf_optimize(compiler_state_t *, struct icode *ic);
|
||||
+void bpf_optimize(compiler_state_t *, struct icode *);
|
||||
void PCAP_NORETURN bpf_syntax_error(compiler_state_t *, const char *);
|
||||
+void bpf_vset_error(compiler_state_t *, const char *, va_list)
|
||||
+ PCAP_PRINTFLIKE(2, 0);
|
||||
+void PCAP_NORETURN bpf_abort_compilation(compiler_state_t *);
|
||||
void PCAP_NORETURN bpf_error(compiler_state_t *, const char *, ...)
|
||||
PCAP_PRINTFLIKE(2, 3);
|
||||
|
||||
diff --git a/optimize.c b/optimize.c
|
||||
index 0d2fcca..2258a3c 100644
|
||||
--- a/optimize.c
|
||||
+++ b/optimize.c
|
||||
@@ -323,6 +323,8 @@ typedef struct {
|
||||
|
||||
static void opt_init(compiler_state_t *, opt_state_t *, struct icode *);
|
||||
static void opt_cleanup(opt_state_t *);
|
||||
+static void PCAP_NORETURN opt_error(compiler_state_t *, opt_state_t *, const char *, ...)
|
||||
+ PCAP_PRINTFLIKE(3, 4);
|
||||
|
||||
static void intern_blocks(opt_state_t *, struct icode *);
|
||||
|
||||
@@ -722,13 +724,13 @@ fold_op(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
|
||||
case BPF_DIV:
|
||||
if (b == 0)
|
||||
- bpf_error(cstate, "division by zero");
|
||||
+ opt_error(cstate, opt_state, "division by zero");
|
||||
a /= b;
|
||||
break;
|
||||
|
||||
case BPF_MOD:
|
||||
if (b == 0)
|
||||
- bpf_error(cstate, "modulus by zero");
|
||||
+ opt_error(cstate, opt_state, "modulus by zero");
|
||||
a %= b;
|
||||
break;
|
||||
|
||||
@@ -1972,6 +1974,22 @@ opt_cleanup(opt_state_t *opt_state)
|
||||
}
|
||||
|
||||
/*
|
||||
+ * Like bpf_error(), but also cleans up the optimizer state.
|
||||
+ */
|
||||
+static void PCAP_NORETURN
|
||||
+opt_error(compiler_state_t *cstate, opt_state_t *opt_state, const char *fmt, ...)
|
||||
+{
|
||||
+ va_list ap;
|
||||
+
|
||||
+ opt_cleanup(opt_state);
|
||||
+ va_start(ap, fmt);
|
||||
+ bpf_vset_error(cstate, fmt, ap);
|
||||
+ va_end(ap);
|
||||
+ bpf_abort_compilation(cstate);
|
||||
+ /* NOTREACHED */
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Return the number of stmts in 's'.
|
||||
*/
|
||||
static u_int
|
||||
@@ -2075,15 +2093,20 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
|
||||
|
||||
opt_state->n_edges = 2 * opt_state->n_blocks;
|
||||
opt_state->edges = (struct edge **)calloc(opt_state->n_edges, sizeof(*opt_state->edges));
|
||||
- if (opt_state->edges == NULL)
|
||||
+ if (opt_state->edges == NULL) {
|
||||
+ free(opt_state->blocks);
|
||||
bpf_error(cstate, "malloc");
|
||||
+ }
|
||||
|
||||
/*
|
||||
* The number of levels is bounded by the number of nodes.
|
||||
*/
|
||||
opt_state->levels = (struct block **)calloc(opt_state->n_blocks, sizeof(*opt_state->levels));
|
||||
- if (opt_state->levels == NULL)
|
||||
+ if (opt_state->levels == NULL) {
|
||||
+ free(opt_state->edges);
|
||||
+ free(opt_state->blocks);
|
||||
bpf_error(cstate, "malloc");
|
||||
+ }
|
||||
|
||||
opt_state->edgewords = opt_state->n_edges / (8 * sizeof(bpf_u_int32)) + 1;
|
||||
opt_state->nodewords = opt_state->n_blocks / (8 * sizeof(bpf_u_int32)) + 1;
|
||||
@@ -2091,8 +2114,12 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
|
||||
/* XXX */
|
||||
opt_state->space = (bpf_u_int32 *)malloc(2 * opt_state->n_blocks * opt_state->nodewords * sizeof(*opt_state->space)
|
||||
+ opt_state->n_edges * opt_state->edgewords * sizeof(*opt_state->space));
|
||||
- if (opt_state->space == NULL)
|
||||
+ if (opt_state->space == NULL) {
|
||||
+ free(opt_state->levels);
|
||||
+ free(opt_state->edges);
|
||||
+ free(opt_state->blocks);
|
||||
bpf_error(cstate, "malloc");
|
||||
+ }
|
||||
p = opt_state->space;
|
||||
opt_state->all_dom_sets = p;
|
||||
for (i = 0; i < n; ++i) {
|
||||
@@ -2129,9 +2156,22 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
|
||||
*/
|
||||
opt_state->maxval = 3 * max_stmts;
|
||||
opt_state->vmap = (struct vmapinfo *)calloc(opt_state->maxval, sizeof(*opt_state->vmap));
|
||||
+ if (opt_state->vmap == NULL) {
|
||||
+ free(opt_state->space);
|
||||
+ free(opt_state->levels);
|
||||
+ free(opt_state->edges);
|
||||
+ free(opt_state->blocks);
|
||||
+ bpf_error(cstate, "malloc");
|
||||
+ }
|
||||
opt_state->vnode_base = (struct valnode *)calloc(opt_state->maxval, sizeof(*opt_state->vnode_base));
|
||||
- if (opt_state->vmap == NULL || opt_state->vnode_base == NULL)
|
||||
+ if (opt_state->vnode_base == NULL) {
|
||||
+ free(opt_state->vmap);
|
||||
+ free(opt_state->space);
|
||||
+ free(opt_state->levels);
|
||||
+ free(opt_state->edges);
|
||||
+ free(opt_state->blocks);
|
||||
bpf_error(cstate, "malloc");
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2143,6 +2183,9 @@ opt_init(compiler_state_t *cstate, opt_state_t *opt_state, struct icode *ic)
|
||||
int bids[NBIDS];
|
||||
#endif
|
||||
|
||||
+static void PCAP_NORETURN conv_error(compiler_state_t *, conv_state_t *, const char *, ...)
|
||||
+ PCAP_PRINTFLIKE(3, 4);
|
||||
+
|
||||
/*
|
||||
* Returns true if successful. Returns false if a branch has
|
||||
* an offset that is too large. If so, we have marked that
|
||||
@@ -2179,7 +2222,7 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
if (slen) {
|
||||
offset = (struct slist **)calloc(slen, sizeof(struct slist *));
|
||||
if (!offset) {
|
||||
- bpf_error(cstate, "not enough core");
|
||||
+ conv_error(cstate, conv_state, "not enough core");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
@@ -2203,7 +2246,8 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
if (BPF_CLASS(src->s.code) != BPF_JMP || src->s.code == (BPF_JMP|BPF_JA)) {
|
||||
#if 0
|
||||
if (src->s.jt || src->s.jf) {
|
||||
- bpf_error(cstate, "illegal jmp destination");
|
||||
+ free(offset);
|
||||
+ conv_error(cstate, conv_state, "illegal jmp destination");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
#endif
|
||||
@@ -2223,7 +2267,8 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
#endif
|
||||
|
||||
if (!src->s.jt || !src->s.jf) {
|
||||
- bpf_error(cstate, ljerr, "no jmp destination", off);
|
||||
+ free(offset);
|
||||
+ conv_error(cstate, conv_state, ljerr, "no jmp destination", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
@@ -2231,12 +2276,14 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
for (i = 0; i < slen; i++) {
|
||||
if (offset[i] == src->s.jt) {
|
||||
if (jt) {
|
||||
- bpf_error(cstate, ljerr, "multiple matches", off);
|
||||
+ free(offset);
|
||||
+ conv_error(cstate, conv_state, ljerr, "multiple matches", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
if (i - off - 1 >= 256) {
|
||||
- bpf_error(cstate, ljerr, "out-of-range jump", off);
|
||||
+ free(offset);
|
||||
+ conv_error(cstate, conv_state, ljerr, "out-of-range jump", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
dst->jt = (u_char)(i - off - 1);
|
||||
@@ -2244,11 +2291,13 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
}
|
||||
if (offset[i] == src->s.jf) {
|
||||
if (jf) {
|
||||
- bpf_error(cstate, ljerr, "multiple matches", off);
|
||||
+ free(offset);
|
||||
+ conv_error(cstate, conv_state, ljerr, "multiple matches", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
if (i - off - 1 >= 256) {
|
||||
- bpf_error(cstate, ljerr, "out-of-range jump", off);
|
||||
+ free(offset);
|
||||
+ conv_error(cstate, conv_state, ljerr, "out-of-range jump", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
dst->jf = (u_char)(i - off - 1);
|
||||
@@ -2256,7 +2305,8 @@ convert_code_r(compiler_state_t *cstate, conv_state_t *conv_state,
|
||||
}
|
||||
}
|
||||
if (!jt || !jf) {
|
||||
- bpf_error(cstate, ljerr, "no destination found", off);
|
||||
+ free(offset);
|
||||
+ conv_error(cstate, conv_state, ljerr, "no destination found", off);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
@@ -2285,7 +2335,7 @@ filled:
|
||||
}
|
||||
/* branch if T to following jump */
|
||||
if (extrajmps >= 256) {
|
||||
- bpf_error(cstate, "too many extra jumps");
|
||||
+ conv_error(cstate, conv_state, "too many extra jumps");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
dst->jt = (u_char)extrajmps;
|
||||
@@ -2306,7 +2356,7 @@ filled:
|
||||
/* branch if F to following jump */
|
||||
/* if two jumps are inserted, F goes to second one */
|
||||
if (extrajmps >= 256) {
|
||||
- bpf_error(cstate, "too many extra jumps");
|
||||
+ conv_error(cstate, conv_state, "too many extra jumps");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
dst->jf = (u_char)extrajmps;
|
||||
@@ -2372,6 +2422,23 @@ icode_to_fcode(compiler_state_t *cstate, struct icode *ic,
|
||||
}
|
||||
|
||||
/*
|
||||
+ * Like bpf_error(), but also frees the array into which we're putting
|
||||
+ * the generated BPF code.
|
||||
+ */
|
||||
+static void PCAP_NORETURN
|
||||
+conv_error(compiler_state_t *cstate, conv_state_t *conv_state, const char *fmt, ...)
|
||||
+{
|
||||
+ va_list ap;
|
||||
+
|
||||
+ free(conv_state->fstart);
|
||||
+ va_start(ap, fmt);
|
||||
+ bpf_vset_error(cstate, fmt, ap);
|
||||
+ va_end(ap);
|
||||
+ bpf_abort_compilation(cstate);
|
||||
+ /* NOTREACHED */
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Make a copy of a BPF program and put it in the "fcode" member of
|
||||
* a "pcap_t".
|
||||
*
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
From 05d67a9f95ca3ed2c2ffaf8bb8e157a8e6194dc0 Mon Sep 17 00:00:00 2001
|
||||
From: Guy Harris <guy@alum.mit.edu>
|
||||
Date: Thu, 14 Feb 2019 13:16:02 -0800
|
||||
Subject: [PATCH 470/470] Plug memory leak.
|
||||
|
||||
If the URL had "file" as the scheme, *and* if we couldn't allocate
|
||||
memory for the path, we'd leak the memory we allocated for the scheme.
|
||||
|
||||
Should address Coverity CID 1442632 (although Coverity misdiagnosed the
|
||||
underlying problem).
|
||||
---
|
||||
pcap.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/pcap.c b/pcap.c
|
||||
index c134cd6..7336260 100644
|
||||
--- a/pcap.c
|
||||
+++ b/pcap.c
|
||||
@@ -1663,13 +1663,14 @@ pcap_parse_source(const char *source, char **schemep, char **userinfop,
|
||||
* the pathname.
|
||||
*/
|
||||
if (pcap_strcasecmp(scheme, "file") == 0) {
|
||||
- *schemep = scheme;
|
||||
*pathp = strdup(colonp + 3);
|
||||
if (*pathp == NULL) {
|
||||
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
|
||||
errno, "malloc");
|
||||
+ free(scheme);
|
||||
return (-1);
|
||||
}
|
||||
+ *schemep = scheme;
|
||||
return (0);
|
||||
}
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,51 +0,0 @@
|
||||
From a463e82f5f0152c3c0d7cf1ebfa56d9b099f7fee Mon Sep 17 00:00:00 2001
|
||||
From: Guy Harris <guy@alum.mit.edu>
|
||||
Date: Thu, 18 Oct 2018 12:04:06 -0700
|
||||
Subject: [PATCH 196/470] Catch another place where we divide by or take a
|
||||
modulus by zero.
|
||||
|
||||
Credit to OSS-Fuzz for finding this issue.
|
||||
---
|
||||
optimize.c | 18 ++++++++++++++++--
|
||||
1 file changed, 16 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/optimize.c b/optimize.c
|
||||
index 2258a3c..4c2a84c 100644
|
||||
--- a/optimize.c
|
||||
+++ b/optimize.c
|
||||
@@ -1144,9 +1144,17 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
op = BPF_OP(s->code);
|
||||
if (alter) {
|
||||
if (s->k == 0) {
|
||||
- /* don't optimize away "sub #0"
|
||||
+ /*
|
||||
+ * Optimize operations where the constant
|
||||
+ * is zero.
|
||||
+ *
|
||||
+ * Don't optimize away "sub #0"
|
||||
* as it may be needed later to
|
||||
- * fixup the generated math code */
|
||||
+ * fixup the generated math code.
|
||||
+ *
|
||||
+ * Fail if we're dividing by zero or taking
|
||||
+ * a modulus by zero.
|
||||
+ */
|
||||
if (op == BPF_ADD ||
|
||||
op == BPF_LSH || op == BPF_RSH ||
|
||||
op == BPF_OR || op == BPF_XOR) {
|
||||
@@ -1158,6 +1166,12 @@ opt_stmt(compiler_state_t *cstate, opt_state_t *opt_state,
|
||||
val[A_ATOM] = K(s->k);
|
||||
break;
|
||||
}
|
||||
+ if (op == BPF_DIV)
|
||||
+ opt_error(cstate, opt_state,
|
||||
+ "division by zero");
|
||||
+ if (op == BPF_MOD)
|
||||
+ opt_error(cstate, opt_state,
|
||||
+ "modulus by zero");
|
||||
}
|
||||
if (opt_state->vmap[val[A_ATOM]].is_const) {
|
||||
fold_op(cstate, opt_state, s, val[A_ATOM], K(s->k));
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
From 6060056e819a5b5b1a222499fe8e4060eaff1934 Mon Sep 17 00:00:00 2001
|
||||
From: Guy Harris <guy@alum.mit.edu>
|
||||
Date: Mon, 15 Oct 2018 13:27:37 -0700
|
||||
Subject: [PATCH 182/470] Don't overflow an int.
|
||||
|
||||
---
|
||||
sf-pcap.c | 9 ++++++++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/sf-pcap.c b/sf-pcap.c
|
||||
index b493f4a..44a43d0 100644
|
||||
--- a/sf-pcap.c
|
||||
+++ b/sf-pcap.c
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
+#include <limits.h> /* for INT_MAX */
|
||||
|
||||
#include "pcap-int.h"
|
||||
|
||||
@@ -369,8 +370,14 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
||||
* length will be misleading if you use it to figure
|
||||
* out why a capture doesn't have all the packet data,
|
||||
* but there's not much we can do to avoid that.
|
||||
+ *
|
||||
+ * But don't grow the snapshot length past the
|
||||
+ * maximum value of an int.
|
||||
*/
|
||||
- p->snapshot += 14;
|
||||
+ if (p->snapshot <= INT_MAX - 14)
|
||||
+ p->snapshot += 14;
|
||||
+ else
|
||||
+ p->snapshot = INT_MAX;
|
||||
}
|
||||
} else
|
||||
ps->hdrsize = sizeof(struct pcap_sf_pkthdr);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
From b3cedb07ac72ac03e552be437149244be12363b7 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Boulain <kevin.boulain@securactive.net>
|
||||
Date: Tue, 16 Oct 2018 15:46:46 +0000
|
||||
Subject: [PATCH 188/470] Fix leak in rpcap
|
||||
|
||||
---
|
||||
pcap-rpcap.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/pcap-rpcap.c b/pcap-rpcap.c
|
||||
index a62296d..8e7e1ad 100644
|
||||
--- a/pcap-rpcap.c
|
||||
+++ b/pcap-rpcap.c
|
||||
@@ -763,6 +763,8 @@ static void pcap_cleanup_rpcap(pcap_t *fp)
|
||||
pr->currentfilter = NULL;
|
||||
}
|
||||
|
||||
+ pcap_cleanup_live_common(fp);
|
||||
+
|
||||
/* To avoid inconsistencies in the number of sock_init() */
|
||||
sock_cleanup();
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,48 +0,0 @@
|
||||
From db833b997d9d825a4bb0e78804d85552b38a562a Mon Sep 17 00:00:00 2001
|
||||
From: Guy Harris <guy@alum.mit.edu>
|
||||
Date: Tue, 16 Oct 2018 23:23:10 -0700
|
||||
Subject: [PATCH 193/470] Fix the semantics of BPF_LSH and BPF_RSH for shifts
|
||||
>= 32 bits.
|
||||
|
||||
Some processors treat shifts greater than the width of the shifted
|
||||
operand as setting the destination to 0, some others treat it as a shift
|
||||
modulo the width.
|
||||
|
||||
C says it's undefined, and most if not all implementations make it work
|
||||
the way the target processor works.
|
||||
|
||||
We treat it as setting the destination to 0, regardless of how the
|
||||
processor on which we're running works.
|
||||
|
||||
Credit to OSS-Fuzz for finding this issue.
|
||||
---
|
||||
bpf_filter.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/bpf_filter.c b/bpf_filter.c
|
||||
index e5c286b..b19b25d 100644
|
||||
--- a/bpf_filter.c
|
||||
+++ b/bpf_filter.c
|
||||
@@ -302,11 +302,17 @@ pcap_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p,
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_LSH|BPF_X:
|
||||
- A <<= X;
|
||||
+ if (X < 32)
|
||||
+ A <<= X;
|
||||
+ else
|
||||
+ A = 0;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_RSH|BPF_X:
|
||||
- A >>= X;
|
||||
+ if (X < 32)
|
||||
+ A >>= X;
|
||||
+ else
|
||||
+ A = 0;
|
||||
continue;
|
||||
|
||||
case BPF_ALU|BPF_ADD|BPF_K:
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
From 2a46edf29049ccf3dcfb7a2f2a2cdb6943a3e142 Mon Sep 17 00:00:00 2001
|
||||
From: Cedric Cellier <rixed@happyleptic.org>
|
||||
Date: Fri, 25 May 2018 15:46:39 +0200
|
||||
Subject: [PATCH 001/470] Fix using uninitialised file descriptor
|
||||
|
||||
Too quick copy-pasta.
|
||||
---
|
||||
pcap-rpcap.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/pcap-rpcap.c b/pcap-rpcap.c
|
||||
index 65e235f..f14a220 100644
|
||||
--- a/pcap-rpcap.c
|
||||
+++ b/pcap-rpcap.c
|
||||
@@ -2276,7 +2276,7 @@ pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags, int read_tim
|
||||
goto error;
|
||||
|
||||
/* Discard the rest of the message, if there is any. */
|
||||
- if (rpcap_discard(pr->rmt_sockctrl, plen, errbuf) == -1)
|
||||
+ if (rpcap_discard(sockctrl, plen, errbuf) == -1)
|
||||
goto error_nodiscard;
|
||||
|
||||
/* Set proper fields into the pcap_t struct */
|
||||
@@ -2314,7 +2314,7 @@ error:
|
||||
* We already reported an error; if this gets an error, just
|
||||
* drive on.
|
||||
*/
|
||||
- (void)rpcap_discard(pr->rmt_sockctrl, plen, NULL);
|
||||
+ (void)rpcap_discard(sockctrl, plen, NULL);
|
||||
|
||||
error_nodiscard:
|
||||
if (!active)
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
From cd512217e570f796ef3e3a7ad67c66d78c83c2dc Mon Sep 17 00:00:00 2001
|
||||
From: Guy Harris <guy@alum.mit.edu>
|
||||
Date: Fri, 26 Oct 2018 13:02:59 -0700
|
||||
Subject: [PATCH 214/470] Make qerr const.
|
||||
|
||||
It's not something we're allowed to modify, as that could fail if two or
|
||||
more threads are all running in pcap_compile(); declare it as const to
|
||||
make sure we don't modify it.
|
||||
---
|
||||
grammar.y | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grammar.y b/grammar.y
|
||||
index e060cde..3eeb135 100644
|
||||
--- a/grammar.y
|
||||
+++ b/grammar.y
|
||||
@@ -237,7 +237,7 @@ str2tok(const char *str, const struct tok *toks)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
-static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
|
||||
+static const struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
|
||||
|
||||
static PCAP_NORETURN_DEF void
|
||||
yyerror(void *yyscanner _U_, compiler_state_t *cstate, const char *msg)
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,26 +0,0 @@
|
||||
From 8107ee96602992924adccc01bb2214d24d389182 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Galanin <al@galanin.nnov.ru>
|
||||
Date: Mon, 3 Dec 2018 16:12:48 +0300
|
||||
Subject: [PATCH 259/470] fix use of sizeof on a pointer
|
||||
|
||||
---
|
||||
pcap-bpf.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/pcap-bpf.c b/pcap-bpf.c
|
||||
index 3b53978..13c1cf2 100644
|
||||
--- a/pcap-bpf.c
|
||||
+++ b/pcap-bpf.c
|
||||
@@ -1366,8 +1366,8 @@ bpf_load(char *errbuf)
|
||||
|
||||
/* Check if the driver is loaded */
|
||||
memset(&cfg_ld, 0x0, sizeof(cfg_ld));
|
||||
+ pcap_snprintf(buf, sizeof(buf), "%s/%s", DRIVER_PATH, BPF_NAME);
|
||||
cfg_ld.path = buf;
|
||||
- pcap_snprintf(cfg_ld.path, sizeof(cfg_ld.path), "%s/%s", DRIVER_PATH, BPF_NAME);
|
||||
if ((sysconfig(SYS_QUERYLOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) ||
|
||||
(cfg_ld.kmid == 0)) {
|
||||
/* Driver isn't loaded, load it now */
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -20,3 +20,4 @@ index 58782ae..b7a813d 100644
|
||||
|
||||
/* ARPHRD_LAPD is unofficial and randomly allocated, if reallocation
|
||||
* is needed, please report it to <daniele@orlandi.com> */
|
||||
|
||||
|
||||
Binary file not shown.
BIN
libpcap-1.9.1.tar.gz
Normal file
BIN
libpcap-1.9.1.tar.gz
Normal file
Binary file not shown.
113
libpcap.spec
113
libpcap.spec
@ -1,103 +1,66 @@
|
||||
Name: libpcap
|
||||
Epoch: 14
|
||||
Version: 1.9.0
|
||||
Release: 4
|
||||
Summary: A library for user-level packet capture
|
||||
License: BSD with advertising
|
||||
URL: http://www.tcpdump.org
|
||||
Source: http://www.tcpdump.org/release/%{name}-%{version}.tar.gz
|
||||
Name: libpcap
|
||||
Epoch: 14
|
||||
Version: 1.9.1
|
||||
Release: 3
|
||||
Summary: A system-independent interface for user-level packet capture
|
||||
License: BSD with advertising
|
||||
URL: http://www.tcpdump.org
|
||||
Source0: http://www.tcpdump.org/release/%{name}-%{version}.tar.gz
|
||||
|
||||
#ptach 1 and 2 are come from fedora
|
||||
Patch0001: 0001-man-tcpdump-and-tcpslice-have-manpages-in-man8.patch
|
||||
Patch0002: 0002-pcap-config-mitigate-multilib-conflict.patch
|
||||
#following patches are come from upstream community
|
||||
Patch6000: ieee80215-arphrd.patch
|
||||
Patch6001: Fix-using-uninitialised-file-descriptor.patch
|
||||
Patch6002: Don-t-overflow-an-int.patch
|
||||
Patch6003: Fix-leak-in-rpcap.patch
|
||||
Patch6004: Fix-the-semantics-of-BPF_LSH-and-BPF_RSH-for-shifts-.patch
|
||||
Patch6005: 0194-Plug-some-memory-leaks.patch
|
||||
Patch6006: 0195-Plug-some-memory-leaks.patch
|
||||
Patch6007: Catch-another-place-where-we-divide-by-or-take-a-mod.patch
|
||||
Patch6008: Make-qerr-const.patch
|
||||
Patch6009: fix-use-of-sizeof-on-a-pointer.patch
|
||||
Patch6010: 0470-Plug-memory-leak.patch
|
||||
Patch6011: 0012-Plug-a-file-descriptor-leak.patch
|
||||
Patch6012: 0036-Use-the-snapshot-length-to-set-the-buffer-size-and-s.patch
|
||||
Patch6013: 0066-Check-for-an-empty-description-by-checking-if-the-fi.patch
|
||||
Patch6014: 0068-Fixed-the-fread-call-in-the-savefile.c-file.patch
|
||||
Patch6015: 0069-Fixed-number-of-elements-returned.patch
|
||||
Patch6016: 0070-Read-the-magic-number-into-a-byte-array.patch
|
||||
Patch6017: 0075-Use-ab-rather-than-rb-for-the-pcap_dump_open_append-.patch
|
||||
Patch6018: 0079-Treat-both-ENXIO-and-EIO-as-device-went-away.patch
|
||||
Patch6019: 0080-Change-the-error-message-for-ENXIO-EIO-to-match-real.patch
|
||||
Patch0001: 0001-man-tcpdump-and-tcpslice-have-manpages-in-man8.patch
|
||||
Patch0002: 0002-pcap-config-mitigate-multilib-conflict.patch
|
||||
Patch0003: 0003-pcap-linux-apparently-ctc-interfaces-on-s390-has-eth.patch
|
||||
Patch0004: ieee80215-arphrd.patch
|
||||
Patch0005: clean-up-signed-vs-unsigned-do-more-error-checking-in-the-parser.patch
|
||||
|
||||
BuildRequires: bison bluez-libs-devel flex glibc-kernheaders >= 2.2.0
|
||||
BuildRequires: bison bluez-libs-devel flex gcc git glibc-kernheaders >= 2.2.0
|
||||
|
||||
%description
|
||||
Libpcap provides functions for user-level packet capture, used in low-level
|
||||
network monitoring.
|
||||
This is the official web site of tcpdump, a powerful command-line
|
||||
packet analyzer; and libpcap, a portable C/C++ library for
|
||||
network traffic capture.
|
||||
|
||||
%package devel
|
||||
Summary: Libraries and files for libpcap
|
||||
Requires: %{name} = %{epoch}:%{version}-%{release}
|
||||
%package devel
|
||||
Summary: header files for libpcap
|
||||
Requires: %{name} = %{epoch}:%{version}-%{release}
|
||||
|
||||
%description devel
|
||||
This package provides files and libraries for
|
||||
developing libpcap applications.
|
||||
%description devel
|
||||
header files for libpcap
|
||||
|
||||
%package help
|
||||
Summary: Help information for libpcap
|
||||
|
||||
%description help
|
||||
This package provides help for libpcap.
|
||||
%package_help
|
||||
|
||||
%prep
|
||||
%autosetup -p1
|
||||
%autosetup -n %{name}-%{version} -S git
|
||||
|
||||
%build
|
||||
export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing"
|
||||
%configure
|
||||
%make_build CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing"
|
||||
%make_build
|
||||
|
||||
%install
|
||||
%make_install
|
||||
%make_install
|
||||
|
||||
%ldconfig_post
|
||||
%ldconfig_postun
|
||||
%delete_la_and_a
|
||||
|
||||
%ldconfig_scriptlets
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%license LICENSE
|
||||
%{_libdir}/libpcap.so.*
|
||||
%exclude %{_libdir}/libpcap.a
|
||||
|
||||
%files devel
|
||||
%files devel
|
||||
%defattr(-,root,root)
|
||||
%{_bindir}/pcap-config
|
||||
%{_includedir}/pcap*.h
|
||||
%{_includedir}/pcap
|
||||
%{_includedir}/*
|
||||
%{_libdir}/libpcap.so
|
||||
%{_libdir}/pkgconfig/libpcap.pc
|
||||
|
||||
%files help
|
||||
%files help
|
||||
%defattr(-,root,root)
|
||||
%doc README.md CHANGES CREDITS
|
||||
%{_mandir}/man1/pcap-config.1*
|
||||
%{_mandir}/man3/pcap*.3*
|
||||
%{_mandir}/man5/pcap*.5*
|
||||
%{_mandir}/man7/pcap*.7*
|
||||
%{_mandir}/man*
|
||||
|
||||
%changelog
|
||||
* Wed Sep 25 2019 openEuler Buildteam <buildteam@openeuler.org> - 14:1.9.0-4
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
- DESC:Plug-a-file-descriptor-leak
|
||||
Use-the-snapshot-length-to-set-the-buffer-size-and-s
|
||||
Check-for-an-empty-description-by-checking-if-the-fi
|
||||
Fixed-the-fread-call-in-the-savefile.c-file
|
||||
Fixed-number-of-elements-returned
|
||||
Read-the-magic-number-into-a-byte-array
|
||||
Use-ab-rather-than-rb-for-the-pcap_dump_open_append
|
||||
Treat-both-ENXIO-and-EIO-as-device-went-away
|
||||
Change-the-error-message-for-ENXIO-EIO-to-match-real
|
||||
|
||||
* Wed Sep 11 2019 liyongqiang<liyongqiang10@huawei.com> - 14:1.9.0-3
|
||||
* Sat Dec 21 2019 openEuler Buildteam <buildteam@openeuler.org> - 14:1.9.1-3
|
||||
- Package init
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user