commit 81b8d9f850b2caf9487c433596e8ae4e5cc0efcf Author: overweight <5324761+overweight@user.noreply.gitee.com> Date: Mon Sep 30 10:57:32 2019 -0400 Package init diff --git a/0001-man-tcpdump-and-tcpslice-have-manpages-in-man8.patch b/0001-man-tcpdump-and-tcpslice-have-manpages-in-man8.patch new file mode 100644 index 0000000..888bb9a --- /dev/null +++ b/0001-man-tcpdump-and-tcpslice-have-manpages-in-man8.patch @@ -0,0 +1,27 @@ +From 208bb414553d5444d82601e6fd4ca25fbb192998 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +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 + diff --git a/0002-pcap-config-mitigate-multilib-conflict.patch b/0002-pcap-config-mitigate-multilib-conflict.patch new file mode 100644 index 0000000..8b6b420 --- /dev/null +++ b/0002-pcap-config-mitigate-multilib-conflict.patch @@ -0,0 +1,88 @@ +From 5b80ca39b1f01177e98c78bbc622dfda6f7a7e71 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +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 + diff --git a/0012-Plug-a-file-descriptor-leak.patch b/0012-Plug-a-file-descriptor-leak.patch new file mode 100644 index 0000000..878dc4c --- /dev/null +++ b/0012-Plug-a-file-descriptor-leak.patch @@ -0,0 +1,24 @@ +From 40fe5f21bae1847a92f18efdcc8ad061db8f6cce Mon Sep 17 00:00:00 2001 +From: Guy Harris +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 + diff --git a/0036-Use-the-snapshot-length-to-set-the-buffer-size-and-s.patch b/0036-Use-the-snapshot-length-to-set-the-buffer-size-and-s.patch new file mode 100644 index 0000000..7344551 --- /dev/null +++ b/0036-Use-the-snapshot-length-to-set-the-buffer-size-and-s.patch @@ -0,0 +1,291 @@ +From 4ccdc8a3cbf5195a7c089002136e53db541b36ba Mon Sep 17 00:00:00 2001 +From: Guy Harris +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; immapbuf[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 diff --git a/0066-Check-for-an-empty-description-by-checking-if-the-fi.patch b/0066-Check-for-an-empty-description-by-checking-if-the-fi.patch new file mode 100644 index 0000000..28e4a86 --- /dev/null +++ b/0066-Check-for-an-empty-description-by-checking-if-the-fi.patch @@ -0,0 +1,26 @@ +From 593769c3637583653bafa924fe348115016618c3 Mon Sep 17 00:00:00 2001 +From: Guy Harris +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 + diff --git a/0068-Fixed-the-fread-call-in-the-savefile.c-file.patch b/0068-Fixed-the-fread-call-in-the-savefile.c-file.patch new file mode 100644 index 0000000..788f121 --- /dev/null +++ b/0068-Fixed-the-fread-call-in-the-savefile.c-file.patch @@ -0,0 +1,38 @@ +From 9157a663d9e845e23697f598994f53f67cfef799 Mon Sep 17 00:00:00 2001 +From: Tymoteusz Blazejczyk +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 + + diff --git a/0069-Fixed-number-of-elements-returned.patch b/0069-Fixed-number-of-elements-returned.patch new file mode 100644 index 0000000..4dc9f6f --- /dev/null +++ b/0069-Fixed-number-of-elements-returned.patch @@ -0,0 +1,25 @@ +From b0e790519df4ec8204c843987fdfa4aa18e2a3cd Mon Sep 17 00:00:00 2001 +From: Tymoteusz Blazejczyk +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 + diff --git a/0070-Read-the-magic-number-into-a-byte-array.patch b/0070-Read-the-magic-number-into-a-byte-array.patch new file mode 100644 index 0000000..23917bf --- /dev/null +++ b/0070-Read-the-magic-number-into-a-byte-array.patch @@ -0,0 +1,212 @@ +From 2e9d0ae34ece4d6f67f4d66a4c3628febf0b13dd Mon Sep 17 00:00:00 2001 +From: Guy Harris +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 + + diff --git a/0075-Use-ab-rather-than-rb-for-the-pcap_dump_open_append-.patch b/0075-Use-ab-rather-than-rb-for-the-pcap_dump_open_append-.patch new file mode 100644 index 0000000..e96f969 --- /dev/null +++ b/0075-Use-ab-rather-than-rb-for-the-pcap_dump_open_append-.patch @@ -0,0 +1,171 @@ +From f542342e5e232c9ed522b99897cf7aedccc89fe8 Mon Sep 17 00:00:00 2001 +From: Guy Harris +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 + diff --git a/0079-Treat-both-ENXIO-and-EIO-as-device-went-away.patch b/0079-Treat-both-ENXIO-and-EIO-as-device-went-away.patch new file mode 100644 index 0000000..58523f7 --- /dev/null +++ b/0079-Treat-both-ENXIO-and-EIO-as-device-went-away.patch @@ -0,0 +1,29 @@ +From f22bd1264917671c87bb98e9c66c5734676f3150 Mon Sep 17 00:00:00 2001 +From: Guy Harris +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 + + diff --git a/0080-Change-the-error-message-for-ENXIO-EIO-to-match-real.patch b/0080-Change-the-error-message-for-ENXIO-EIO-to-match-real.patch new file mode 100644 index 0000000..27da597 --- /dev/null +++ b/0080-Change-the-error-message-for-ENXIO-EIO-to-match-real.patch @@ -0,0 +1,47 @@ +From 8072538381d3f8f80c6ec643ce52a8355ac5fa65 Mon Sep 17 00:00:00 2001 +From: Guy Harris +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 + + diff --git a/0194-Plug-some-memory-leaks.patch b/0194-Plug-some-memory-leaks.patch new file mode 100644 index 0000000..05fa39c --- /dev/null +++ b/0194-Plug-some-memory-leaks.patch @@ -0,0 +1,234 @@ +From bcbef226ca11662342b5e267e7f12066bcfd60d0 Mon Sep 17 00:00:00 2001 +From: Guy Harris +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 ID +-%type EID +-%type AID ++%type ID EID AID + %type HID HID6 + %type NUM action reason type subtype type_subtype dir + +@@ -437,24 +434,8 @@ nid: ID { $$.b = gen_scode(cstate, $1, $$.q = $0.q); } + "in this configuration"); + #endif /*INET6*/ + } +- | EID { +- $$.b = gen_ecode(cstate, $1, $$.q = $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 = $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 = $0.q); } ++ | AID { $$.b = gen_acode(cstate, $1, $$.q = $0.q); } + | not id { gen_not($2.b); $$ = $2; } + ; + not: '!' { $$ = $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 + diff --git a/0195-Plug-some-memory-leaks.patch b/0195-Plug-some-memory-leaks.patch new file mode 100644 index 0000000..2db130a --- /dev/null +++ b/0195-Plug-some-memory-leaks.patch @@ -0,0 +1,319 @@ +From 947f2be1e0345bbd6f66f6c945ad51eb7f074e8a Mon Sep 17 00:00:00 2001 +From: Guy Harris +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 + diff --git a/0470-Plug-memory-leak.patch b/0470-Plug-memory-leak.patch new file mode 100644 index 0000000..e7a13ae --- /dev/null +++ b/0470-Plug-memory-leak.patch @@ -0,0 +1,37 @@ +From 05d67a9f95ca3ed2c2ffaf8bb8e157a8e6194dc0 Mon Sep 17 00:00:00 2001 +From: Guy Harris +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 + diff --git a/Catch-another-place-where-we-divide-by-or-take-a-mod.patch b/Catch-another-place-where-we-divide-by-or-take-a-mod.patch new file mode 100644 index 0000000..b968a67 --- /dev/null +++ b/Catch-another-place-where-we-divide-by-or-take-a-mod.patch @@ -0,0 +1,51 @@ +From a463e82f5f0152c3c0d7cf1ebfa56d9b099f7fee Mon Sep 17 00:00:00 2001 +From: Guy Harris +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 + diff --git a/Don-t-overflow-an-int.patch b/Don-t-overflow-an-int.patch new file mode 100644 index 0000000..88acd8e --- /dev/null +++ b/Don-t-overflow-an-int.patch @@ -0,0 +1,40 @@ +From 6060056e819a5b5b1a222499fe8e4060eaff1934 Mon Sep 17 00:00:00 2001 +From: Guy Harris +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 + #include + #include ++#include /* 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 + diff --git a/Fix-leak-in-rpcap.patch b/Fix-leak-in-rpcap.patch new file mode 100644 index 0000000..fe7da43 --- /dev/null +++ b/Fix-leak-in-rpcap.patch @@ -0,0 +1,25 @@ +From b3cedb07ac72ac03e552be437149244be12363b7 Mon Sep 17 00:00:00 2001 +From: Kevin Boulain +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 + diff --git a/Fix-the-semantics-of-BPF_LSH-and-BPF_RSH-for-shifts-.patch b/Fix-the-semantics-of-BPF_LSH-and-BPF_RSH-for-shifts-.patch new file mode 100644 index 0000000..155226c --- /dev/null +++ b/Fix-the-semantics-of-BPF_LSH-and-BPF_RSH-for-shifts-.patch @@ -0,0 +1,48 @@ +From db833b997d9d825a4bb0e78804d85552b38a562a Mon Sep 17 00:00:00 2001 +From: Guy Harris +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 + diff --git a/Fix-using-uninitialised-file-descriptor.patch b/Fix-using-uninitialised-file-descriptor.patch new file mode 100644 index 0000000..27dc791 --- /dev/null +++ b/Fix-using-uninitialised-file-descriptor.patch @@ -0,0 +1,35 @@ +From 2a46edf29049ccf3dcfb7a2f2a2cdb6943a3e142 Mon Sep 17 00:00:00 2001 +From: Cedric Cellier +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 + diff --git a/Make-qerr-const.patch b/Make-qerr-const.patch new file mode 100644 index 0000000..19820de --- /dev/null +++ b/Make-qerr-const.patch @@ -0,0 +1,28 @@ +From cd512217e570f796ef3e3a7ad67c66d78c83c2dc Mon Sep 17 00:00:00 2001 +From: Guy Harris +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 + diff --git a/fix-use-of-sizeof-on-a-pointer.patch b/fix-use-of-sizeof-on-a-pointer.patch new file mode 100644 index 0000000..26c5b52 --- /dev/null +++ b/fix-use-of-sizeof-on-a-pointer.patch @@ -0,0 +1,26 @@ +From 8107ee96602992924adccc01bb2214d24d389182 Mon Sep 17 00:00:00 2001 +From: Alexander Galanin +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 + diff --git a/ieee80215-arphrd.patch b/ieee80215-arphrd.patch new file mode 100644 index 0000000..45f24c4 --- /dev/null +++ b/ieee80215-arphrd.patch @@ -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 */ diff --git a/libpcap-1.9.0.tar.gz b/libpcap-1.9.0.tar.gz new file mode 100644 index 0000000..32ab5c6 Binary files /dev/null and b/libpcap-1.9.0.tar.gz differ diff --git a/libpcap.spec b/libpcap.spec new file mode 100644 index 0000000..af71249 --- /dev/null +++ b/libpcap.spec @@ -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 - 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 - 14:1.9.0-3 +- Package init