Package init
This commit is contained in:
commit
81b8d9f850
27
0001-man-tcpdump-and-tcpslice-have-manpages-in-man8.patch
Normal file
27
0001-man-tcpdump-and-tcpslice-have-manpages-in-man8.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From 208bb414553d5444d82601e6fd4ca25fbb192998 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Sekletar <msekleta@redhat.com>
|
||||||
|
Date: Mon, 29 Sep 2014 08:19:05 +0200
|
||||||
|
Subject: [PATCH 1/4] man: tcpdump and tcpslice have manpages in man8
|
||||||
|
|
||||||
|
Both should be run only by root, hence manpages for them should be located in
|
||||||
|
/usr/share/man/man8/
|
||||||
|
---
|
||||||
|
pcap.3pcap.in | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/pcap.3pcap.in b/pcap.3pcap.in
|
||||||
|
index f5a7e0c..f220e68 100644
|
||||||
|
--- a/pcap.3pcap.in
|
||||||
|
+++ b/pcap.3pcap.in
|
||||||
|
@@ -882,7 +882,7 @@ use an
|
||||||
|
script or some other configuration script to check whether the libpcap
|
||||||
|
1.0 APIs are available and use them only if they are.
|
||||||
|
.SH SEE ALSO
|
||||||
|
-autoconf(1), tcpdump(1), tcpslice(1), pcap-filter(@MAN_MISC_INFO@), pfconfig(8),
|
||||||
|
+autoconf(1), tcpdump(8), tcpslice(8), pcap-filter(@MAN_MISC_INFO@), pfconfig(8),
|
||||||
|
usermod(@MAN_ADMIN_COMMANDS@)
|
||||||
|
.SH AUTHORS
|
||||||
|
The original authors of libpcap are:
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
88
0002-pcap-config-mitigate-multilib-conflict.patch
Normal file
88
0002-pcap-config-mitigate-multilib-conflict.patch
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
From 5b80ca39b1f01177e98c78bbc622dfda6f7a7e71 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Sekletar <msekleta@redhat.com>
|
||||||
|
Date: Mon, 29 Sep 2014 08:27:15 +0200
|
||||||
|
Subject: [PATCH 2/4] pcap-config: mitigate multilib conflict
|
||||||
|
|
||||||
|
libdir path is different on 64bit and 32bit arches. Hence when installing both
|
||||||
|
multilib versions on the system yum complains about conflicting pcap-config
|
||||||
|
file.
|
||||||
|
|
||||||
|
Hence remove libdir references from pcap-config, libdir is in dynamic linker
|
||||||
|
path anyway.
|
||||||
|
---
|
||||||
|
pcap-config.in | 27 ++++++++-------------------
|
||||||
|
1 file changed, 8 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/pcap-config.in b/pcap-config.in
|
||||||
|
index 206be3b..75f2c9f 100644
|
||||||
|
--- a/pcap-config.in
|
||||||
|
+++ b/pcap-config.in
|
||||||
|
@@ -7,7 +7,6 @@
|
||||||
|
prefix="@prefix@"
|
||||||
|
exec_prefix="@exec_prefix@"
|
||||||
|
includedir="@includedir@"
|
||||||
|
-libdir="@libdir@"
|
||||||
|
V_RPATH_OPT="@V_RPATH_OPT@"
|
||||||
|
LIBS="@LIBS@"
|
||||||
|
PACKAGE_NAME="@PACKAGE_NAME@"
|
||||||
|
@@ -36,16 +35,6 @@ do
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
-if [ "$V_RPATH_OPT" != "" ]
|
||||||
|
-then
|
||||||
|
- #
|
||||||
|
- # If libdir isn't /usr/lib, add it to the run-time linker path.
|
||||||
|
- #
|
||||||
|
- if [ "$libdir" != "/usr/lib" ]
|
||||||
|
- then
|
||||||
|
- RPATH=$V_RPATH_OPT$libdir
|
||||||
|
- fi
|
||||||
|
-fi
|
||||||
|
if [ "$static" = 1 ]
|
||||||
|
then
|
||||||
|
#
|
||||||
|
@@ -54,16 +43,16 @@ then
|
||||||
|
#
|
||||||
|
if [ "$show_cflags" = 1 -a "$show_libs" = 1 ]
|
||||||
|
then
|
||||||
|
- echo "-I$includedir -L$libdir -lpcap $LIBS"
|
||||||
|
+ echo "-lpcap @LIBS@"
|
||||||
|
elif [ "$show_cflags" = 1 -a "$show_additional_libs" = 1 ]
|
||||||
|
then
|
||||||
|
- echo "-I$includedir -L$libdir $LIBS"
|
||||||
|
+ echo "@LIBS@"
|
||||||
|
elif [ "$show_cflags" = 1 ]
|
||||||
|
then
|
||||||
|
- echo "-I$includedir"
|
||||||
|
+ echo ""
|
||||||
|
elif [ "$show_libs" = 1 ]
|
||||||
|
then
|
||||||
|
- echo "-L$libdir -lpcap $LIBS"
|
||||||
|
+ echo "-lpcap @LIBS@"
|
||||||
|
elif [ "$show_additional_libs" = 1 ]
|
||||||
|
then
|
||||||
|
echo "$LIBS"
|
||||||
|
@@ -75,15 +64,15 @@ else
|
||||||
|
#
|
||||||
|
if [ "$show_cflags" = 1 -a "$show_libs" = 1 ]
|
||||||
|
then
|
||||||
|
- echo "-I$includedir -L$libdir $RPATH -l$PACKAGE_NAME"
|
||||||
|
+ echo "-lpcap"
|
||||||
|
elif [ "$show_cflags" = 1 -a "$show_additional_libs" = 1 ]
|
||||||
|
then
|
||||||
|
- echo "-I$includedir"
|
||||||
|
+ echo ""
|
||||||
|
elif [ "$show_cflags" = 1 ]
|
||||||
|
then
|
||||||
|
- echo "-I$includedir"
|
||||||
|
+ echo ""
|
||||||
|
elif [ "$show_libs" = 1 ]
|
||||||
|
then
|
||||||
|
- echo "-L$libdir $RPATH -l$PACKAGE_NAME"
|
||||||
|
+ echo "-lpcap"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
24
0012-Plug-a-file-descriptor-leak.patch
Normal file
24
0012-Plug-a-file-descriptor-leak.patch
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
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
|
||||||
|
|
||||||
291
0036-Use-the-snapshot-length-to-set-the-buffer-size-and-s.patch
Normal file
291
0036-Use-the-snapshot-length-to-set-the-buffer-size-and-s.patch
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
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
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
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
|
||||||
|
|
||||||
38
0068-Fixed-the-fread-call-in-the-savefile.c-file.patch
Normal file
38
0068-Fixed-the-fread-call-in-the-savefile.c-file.patch
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
25
0069-Fixed-number-of-elements-returned.patch
Normal file
25
0069-Fixed-number-of-elements-returned.patch
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
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
|
||||||
|
|
||||||
212
0070-Read-the-magic-number-into-a-byte-array.patch
Normal file
212
0070-Read-the-magic-number-into-a-byte-array.patch
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
171
0075-Use-ab-rather-than-rb-for-the-pcap_dump_open_append-.patch
Normal file
171
0075-Use-ab-rather-than-rb-for-the-pcap_dump_open_append-.patch
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
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
|
||||||
|
|
||||||
29
0079-Treat-both-ENXIO-and-EIO-as-device-went-away.patch
Normal file
29
0079-Treat-both-ENXIO-and-EIO-as-device-went-away.patch
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
234
0194-Plug-some-memory-leaks.patch
Normal file
234
0194-Plug-some-memory-leaks.patch
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
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
|
||||||
|
|
||||||
319
0195-Plug-some-memory-leaks.patch
Normal file
319
0195-Plug-some-memory-leaks.patch
Normal file
@ -0,0 +1,319 @@
|
|||||||
|
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
|
||||||
|
|
||||||
37
0470-Plug-memory-leak.patch
Normal file
37
0470-Plug-memory-leak.patch
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
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
|
||||||
|
|
||||||
51
Catch-another-place-where-we-divide-by-or-take-a-mod.patch
Normal file
51
Catch-another-place-where-we-divide-by-or-take-a-mod.patch
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
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
|
||||||
|
|
||||||
40
Don-t-overflow-an-int.patch
Normal file
40
Don-t-overflow-an-int.patch
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
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
|
||||||
|
|
||||||
25
Fix-leak-in-rpcap.patch
Normal file
25
Fix-leak-in-rpcap.patch
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
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
|
||||||
|
|
||||||
48
Fix-the-semantics-of-BPF_LSH-and-BPF_RSH-for-shifts-.patch
Normal file
48
Fix-the-semantics-of-BPF_LSH-and-BPF_RSH-for-shifts-.patch
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
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
|
||||||
|
|
||||||
35
Fix-using-uninitialised-file-descriptor.patch
Normal file
35
Fix-using-uninitialised-file-descriptor.patch
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
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
|
||||||
|
|
||||||
28
Make-qerr-const.patch
Normal file
28
Make-qerr-const.patch
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
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
|
||||||
|
|
||||||
26
fix-use-of-sizeof-on-a-pointer.patch
Normal file
26
fix-use-of-sizeof-on-a-pointer.patch
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
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
|
||||||
|
|
||||||
22
ieee80215-arphrd.patch
Normal file
22
ieee80215-arphrd.patch
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
diff --git a/pcap-linux.c b/pcap-linux.c
|
||||||
|
index 58782ae..b7a813d 100644
|
||||||
|
--- a/pcap-linux.c
|
||||||
|
+++ b/pcap-linux.c
|
||||||
|
@@ -3499,6 +3499,17 @@ static void map_arphrd_to_dlt(pcap_t *handle, int sock_fd, int arptype,
|
||||||
|
* XXX - this is handled in activate_new(). */
|
||||||
|
/* handlep->cooked = 1; */
|
||||||
|
break;
|
||||||
|
+#ifndef ARPHRD_IEEE80215
|
||||||
|
+#define ARPHRD_IEEE80215 805
|
||||||
|
+#endif
|
||||||
|
+#ifndef ARPHRD_IEEE80215_PHY
|
||||||
|
+#define ARPHRD_IEEE80215_PHY 806
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ case ARPHRD_IEEE80215:
|
||||||
|
+ case ARPHRD_IEEE80215_PHY:
|
||||||
|
+ handle->linktype = DLT_IEEE802_15_4;
|
||||||
|
+ break;
|
||||||
|
|
||||||
|
/* ARPHRD_LAPD is unofficial and randomly allocated, if reallocation
|
||||||
|
* is needed, please report it to <daniele@orlandi.com> */
|
||||||
BIN
libpcap-1.9.0.tar.gz
Normal file
BIN
libpcap-1.9.0.tar.gz
Normal file
Binary file not shown.
103
libpcap.spec
Normal file
103
libpcap.spec
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
BuildRequires: bison bluez-libs-devel flex glibc-kernheaders >= 2.2.0
|
||||||
|
|
||||||
|
%description
|
||||||
|
Libpcap provides functions for user-level packet capture, used in low-level
|
||||||
|
network monitoring.
|
||||||
|
|
||||||
|
%package devel
|
||||||
|
Summary: Libraries and files for libpcap
|
||||||
|
Requires: %{name} = %{epoch}:%{version}-%{release}
|
||||||
|
|
||||||
|
%description devel
|
||||||
|
This package provides files and libraries for
|
||||||
|
developing libpcap applications.
|
||||||
|
|
||||||
|
%package help
|
||||||
|
Summary: Help information for libpcap
|
||||||
|
|
||||||
|
%description help
|
||||||
|
This package provides help for libpcap.
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%autosetup -p1
|
||||||
|
|
||||||
|
%build
|
||||||
|
%configure
|
||||||
|
%make_build CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing"
|
||||||
|
|
||||||
|
%install
|
||||||
|
%make_install
|
||||||
|
|
||||||
|
%ldconfig_post
|
||||||
|
%ldconfig_postun
|
||||||
|
|
||||||
|
%files
|
||||||
|
%license LICENSE
|
||||||
|
%{_libdir}/libpcap.so.*
|
||||||
|
%exclude %{_libdir}/libpcap.a
|
||||||
|
|
||||||
|
%files devel
|
||||||
|
%{_bindir}/pcap-config
|
||||||
|
%{_includedir}/pcap*.h
|
||||||
|
%{_includedir}/pcap
|
||||||
|
%{_libdir}/libpcap.so
|
||||||
|
%{_libdir}/pkgconfig/libpcap.pc
|
||||||
|
|
||||||
|
%files help
|
||||||
|
%doc README.md CHANGES CREDITS
|
||||||
|
%{_mandir}/man1/pcap-config.1*
|
||||||
|
%{_mandir}/man3/pcap*.3*
|
||||||
|
%{_mandir}/man5/pcap*.5*
|
||||||
|
%{_mandir}/man7/pcap*.7*
|
||||||
|
|
||||||
|
%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
|
||||||
|
- Package init
|
||||||
Loading…
x
Reference in New Issue
Block a user