git: 88b04633c29e - main - libpcap: fix resource leaks and set error messages
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 22 Dec 2025 02:23:52 UTC
The branch main has been updated by glebius:
URL: https://cgit.FreeBSD.org/src/commit/?id=88b04633c29e3a8fd2ac88febd1aedf409ce6925
commit 88b04633c29e3a8fd2ac88febd1aedf409ce6925
Author: Guy Harris <gharris@sonic.net>
AuthorDate: 2025-12-22 01:26:32 +0000
Commit: Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2025-12-22 02:23:28 +0000
libpcap: fix resource leaks and set error messages
In finddevs_bpf() close the BPF device descriptor and free the device list
buffer before returning.
For ioctl() and malloc() errors, use pcapint_fmt_errmsg_for_errno() to
generate an error message.
Fix some comments.
(cherry picked from commit 6870404f35da32d63a0a8789edb010842dd6b208)
---
contrib/libpcap/pcap-bpf.c | 44 +++++++++++++++++++++++++++++++++++++-------
1 file changed, 37 insertions(+), 7 deletions(-)
diff --git a/contrib/libpcap/pcap-bpf.c b/contrib/libpcap/pcap-bpf.c
index 83a363eee0bd..9ca8df156219 100644
--- a/contrib/libpcap/pcap-bpf.c
+++ b/contrib/libpcap/pcap-bpf.c
@@ -45,7 +45,7 @@
#if defined(__FreeBSD__) && __FreeBSD_version < 1600006
/*
- * Add support for capturing on FreeBSD usbusN interfaces.
+ * Add support for creating FreeBSD usbusN interfaces as necessary.
*/
static const char usbus_prefix[] = "usbus";
#define USBUS_PREFIX_LEN (sizeof(usbus_prefix) - 1)
@@ -2039,8 +2039,8 @@ pcap_activate_bpf(pcap_t *p)
#if defined(__FreeBSD__) && __FreeBSD_version < 1600006
/*
- * If this is legacy FreeBSD, and the device name begins with "usbus",
- * try to create the interface if it's not available.
+ * If this is FreeBSD 15 or earlier, and the device name begins
+ * with "usbus", try to create the interface if it's not available.
*/
if (strncmp(p->opt.device, usbus_prefix, USBUS_PREFIX_LEN) == 0) {
/*
@@ -2879,18 +2879,48 @@ finddevs_bpf(pcap_if_list_t *devlistp, char *errbuf)
const char *name;
int fd;
- if ((fd = bpf_open(errbuf)) < 0)
+ if ((fd = bpf_open(errbuf)) < 0) {
+ /*
+ * XXX - this just means we won't have permission to
+ * open any BPF devices, an thus we don't have
+ * permission to capture on network interfaces.
+ */
return (-1);
+ }
memset(&bi, 0, sizeof(bi));
- if (ioctl(fd, BIOCGETIFLIST, (caddr_t)&bi) != 0 || bi.bi_size == 0)
+ if (ioctl(fd, BIOCGETIFLIST, (caddr_t)&bi) != 0) {
+ pcapint_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno, "BIOCGETIFLIST to get buffer size");
+ close(fd);
return (-1);
+ }
+ if (bi.bi_size == 0) {
+ /*
+ * There are no devices attached to BPF.
+ * This means that, in practice, whatever network
+ * interfaces we found don't support packet capture
+ * or injection.
+ */
+ close(fd);
+ return (0);
+ }
- if ((bi.bi_ubuf = malloc(bi.bi_size)) == NULL)
+ if ((bi.bi_ubuf = malloc(bi.bi_size)) == NULL) {
+ pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, errno,
+ "malloc");
+ close(fd);
return (-1);
+ }
- if (ioctl(fd, BIOCGETIFLIST, (caddr_t)&bi) != 0)
+ if (ioctl(fd, BIOCGETIFLIST, (caddr_t)&bi) != 0) {
+ pcapint_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno, "BIOCGETIFLIST to attached devics");
+ free(bi.bi_ubuf);
+ close(fd);
return (-1);
+ }
+ close(fd);
for (name = bi.bi_ubuf; bi.bi_count > 0;
bi.bi_count--, name += strlen(name) + 1)