git: c586ac04eb66 - main - */{wpa_supplicant*,hostapd*}: Fix wpa 100% CPU when USB wlan NIC removed

From: Cy Schubert <cy_at_FreeBSD.org>
Date: Sat, 16 Apr 2022 15:56:09 UTC
The branch main has been updated by cy:

URL: https://cgit.FreeBSD.org/ports/commit/?id=c586ac04eb662dea00ab81b226fa3e41a5110b21

commit c586ac04eb662dea00ab81b226fa3e41a5110b21
Author:     Cy Schubert <cy@FreeBSD.org>
AuthorDate: 2022-04-14 15:42:03 +0000
Commit:     Cy Schubert <cy@FreeBSD.org>
CommitDate: 2022-04-16 15:55:56 +0000

    */{wpa_supplicant*,hostapd*}: Fix wpa 100% CPU when USB wlan NIC removed
    
    hostapd calls pcap_next(3) to read the next packet off the wlan interface.
    pcap_next() returns a pointer to the packet header but does not indicate
    success or failure. Unfortunately this results in an infinite loop (100%
    CPU) when the wlan device disappears, i.e. when a USB wlan device is
    manually removed or a USB error results in the device removal. However
    pcap_next_ex(3) does return success or failure. To resolve this we use
    pcap_next_ex(), forcing hostapd to exit when the error is encountered.
    
    An error message is printed to syslog or stderr when debugging (-d flag)
    is enabled. Unfortunately wpa_printf() only works when debugging is enabled.
    
    PR:             253608
    Reported by:    Damjan Jovanovic <damjan.jov@gmail.com>,
                    bz (privately)
    MFH:            2022Q2
---
 net/hostapd-devel/Makefile                         |  1 +
 .../files/patch-src-l2_packet-l2_packet_freebsd.c  | 37 ++++++++++++++++++++--
 net/hostapd/Makefile                               |  1 +
 .../files/patch-src-l2_packet-l2_packet_freebsd.c  | 37 ++++++++++++++++++++--
 security/wpa_supplicant-devel/Makefile             |  1 +
 .../patch-src_l2__packet_l2__packet__freebsd.c     | 12 ++++---
 security/wpa_supplicant/Makefile                   |  1 +
 .../patch-src_l2__packet_l2__packet__freebsd.c     | 37 ++++++++++++++++++++--
 8 files changed, 116 insertions(+), 11 deletions(-)

diff --git a/net/hostapd-devel/Makefile b/net/hostapd-devel/Makefile
index d824e2b8785f..f65d26658412 100644
--- a/net/hostapd-devel/Makefile
+++ b/net/hostapd-devel/Makefile
@@ -2,6 +2,7 @@
 
 PORTNAME=	hostapd
 PORTVERSION=	${COMMIT_DATE}
+PORTREVISION=	1
 CATEGORIES=	net
 PKGNAMESUFFIX=	-devel
 
diff --git a/net/hostapd-devel/files/patch-src-l2_packet-l2_packet_freebsd.c b/net/hostapd-devel/files/patch-src-l2_packet-l2_packet_freebsd.c
index 8b34e0fbdd89..26ecb22c808c 100644
--- a/net/hostapd-devel/files/patch-src-l2_packet-l2_packet_freebsd.c
+++ b/net/hostapd-devel/files/patch-src-l2_packet-l2_packet_freebsd.c
@@ -1,5 +1,5 @@
---- src/l2_packet/l2_packet_freebsd.c.orig	2014-06-04 13:26:14 UTC
-+++ src/l2_packet/l2_packet_freebsd.c
+--- src/l2_packet/l2_packet_freebsd.c.orig	2022-03-14 01:42:11.000000000 -0700
++++ src/l2_packet/l2_packet_freebsd.c	2022-04-14 07:36:24.999713000 -0700
 @@ -8,7 +8,10 @@
   */
  
@@ -12,3 +12,36 @@
  #include <net/bpf.h>
  #endif /* __APPLE__ */
  #include <pcap.h>
+@@ -76,24 +79,27 @@
+ {
+ 	struct l2_packet_data *l2 = eloop_ctx;
+ 	pcap_t *pcap = sock_ctx;
+-	struct pcap_pkthdr hdr;
++	struct pcap_pkthdr *hdr;
+ 	const u_char *packet;
+ 	struct l2_ethhdr *ethhdr;
+ 	unsigned char *buf;
+ 	size_t len;
+ 
+-	packet = pcap_next(pcap, &hdr);
++	if (pcap_next_ex(pcap, &hdr, &packet) == -1) {
++		wpa_printf(MSG_ERROR, "Error reading packet, has device disappeared?");
++		eloop_terminate();
++	}
+ 
+-	if (!l2->rx_callback || !packet || hdr.caplen < sizeof(*ethhdr))
++	if (!l2->rx_callback || !packet || hdr->caplen < sizeof(*ethhdr))
+ 		return;
+ 
+ 	ethhdr = (struct l2_ethhdr *) packet;
+ 	if (l2->l2_hdr) {
+ 		buf = (unsigned char *) ethhdr;
+-		len = hdr.caplen;
++		len = hdr->caplen;
+ 	} else {
+ 		buf = (unsigned char *) (ethhdr + 1);
+-		len = hdr.caplen - sizeof(*ethhdr);
++		len = hdr->caplen - sizeof(*ethhdr);
+ 	}
+ 	l2->rx_callback(l2->rx_callback_ctx, ethhdr->h_source, buf, len);
+ }
diff --git a/net/hostapd/Makefile b/net/hostapd/Makefile
index 97e774f07b94..26b97a5fd502 100644
--- a/net/hostapd/Makefile
+++ b/net/hostapd/Makefile
@@ -2,6 +2,7 @@
 
 PORTNAME=	hostapd
 PORTVERSION=	2.10
+PORTREVISION=	1
 CATEGORIES=	net
 MASTER_SITES=	https://w1.fi/releases/
 
diff --git a/net/hostapd/files/patch-src-l2_packet-l2_packet_freebsd.c b/net/hostapd/files/patch-src-l2_packet-l2_packet_freebsd.c
index 8b34e0fbdd89..c8be8a1c9c12 100644
--- a/net/hostapd/files/patch-src-l2_packet-l2_packet_freebsd.c
+++ b/net/hostapd/files/patch-src-l2_packet-l2_packet_freebsd.c
@@ -1,5 +1,5 @@
---- src/l2_packet/l2_packet_freebsd.c.orig	2014-06-04 13:26:14 UTC
-+++ src/l2_packet/l2_packet_freebsd.c
+--- src/l2_packet/l2_packet_freebsd.c.orig	2022-01-16 12:51:29.000000000 -0800
++++ src/l2_packet/l2_packet_freebsd.c	2022-04-14 07:35:30.668820000 -0700
 @@ -8,7 +8,10 @@
   */
  
@@ -12,3 +12,36 @@
  #include <net/bpf.h>
  #endif /* __APPLE__ */
  #include <pcap.h>
+@@ -76,24 +79,27 @@
+ {
+ 	struct l2_packet_data *l2 = eloop_ctx;
+ 	pcap_t *pcap = sock_ctx;
+-	struct pcap_pkthdr hdr;
++	struct pcap_pkthdr *hdr;
+ 	const u_char *packet;
+ 	struct l2_ethhdr *ethhdr;
+ 	unsigned char *buf;
+ 	size_t len;
+ 
+-	packet = pcap_next(pcap, &hdr);
++	if (pcap_next_ex(pcap, &hdr, &packet) == -1) {
++		wpa_printf(MSG_ERROR, "Error reading packet, has device disappeared?");
++		eloop_terminate();
++	}
+ 
+-	if (!l2->rx_callback || !packet || hdr.caplen < sizeof(*ethhdr))
++	if (!l2->rx_callback || !packet || hdr->caplen < sizeof(*ethhdr))
+ 		return;
+ 
+ 	ethhdr = (struct l2_ethhdr *) packet;
+ 	if (l2->l2_hdr) {
+ 		buf = (unsigned char *) ethhdr;
+-		len = hdr.caplen;
++		len = hdr->caplen;
+ 	} else {
+ 		buf = (unsigned char *) (ethhdr + 1);
+-		len = hdr.caplen - sizeof(*ethhdr);
++		len = hdr->caplen - sizeof(*ethhdr);
+ 	}
+ 	l2->rx_callback(l2->rx_callback_ctx, ethhdr->h_source, buf, len);
+ }
diff --git a/security/wpa_supplicant-devel/Makefile b/security/wpa_supplicant-devel/Makefile
index a876ab9e9631..f2b41fe32440 100644
--- a/security/wpa_supplicant-devel/Makefile
+++ b/security/wpa_supplicant-devel/Makefile
@@ -1,5 +1,6 @@
 PORTNAME=	wpa_supplicant
 PORTVERSION=	${COMMIT_DATE}
+PORTREVISION=	1
 CATEGORIES=	security net
 PKGNAMESUFFIX=	-devel
 
diff --git a/security/wpa_supplicant-devel/files/patch-src_l2__packet_l2__packet__freebsd.c b/security/wpa_supplicant-devel/files/patch-src_l2__packet_l2__packet__freebsd.c
index 5bce58b36950..e256ee3860e1 100644
--- a/security/wpa_supplicant-devel/files/patch-src_l2__packet_l2__packet__freebsd.c
+++ b/security/wpa_supplicant-devel/files/patch-src_l2__packet_l2__packet__freebsd.c
@@ -1,12 +1,14 @@
---- src/l2_packet/l2_packet_freebsd.c.orig	2018-12-02 11:34:59.000000000 -0800
-+++ src/l2_packet/l2_packet_freebsd.c	2018-12-05 23:18:27.612433000 -0800
-@@ -8,7 +8,8 @@
+--- src/l2_packet/l2_packet_freebsd.c.orig	2022-01-16 12:51:29.000000000 -0800
++++ src/l2_packet/l2_packet_freebsd.c	2022-04-14 07:23:26.534960000 -0700
+@@ -8,7 +8,10 @@
   */
  
  #include "includes.h"
 -#if defined(__APPLE__) || defined(__GLIBC__)
-+#include <sys/param.h>
-+#if defined(__APPLE__) || defined(__GLIBC__) || defined(__FreeBSD_version)
++#if defined(__FreeBSD__) \
++ || defined(__DragonFly__) \
++ || defined(__APPLE__) \
++ || defined(__GLIBC__)
  #include <net/bpf.h>
  #endif /* __APPLE__ */
  #include <pcap.h>
diff --git a/security/wpa_supplicant/Makefile b/security/wpa_supplicant/Makefile
index 31acd83f3c14..aaeda909f826 100644
--- a/security/wpa_supplicant/Makefile
+++ b/security/wpa_supplicant/Makefile
@@ -1,5 +1,6 @@
 PORTNAME=	wpa_supplicant
 PORTVERSION=	2.10
+PORTREVISION=	1
 CATEGORIES=	security net
 MASTER_SITES=	https://w1.fi/releases/
 
diff --git a/security/wpa_supplicant/files/patch-src_l2__packet_l2__packet__freebsd.c b/security/wpa_supplicant/files/patch-src_l2__packet_l2__packet__freebsd.c
index 5bce58b36950..5a55ec96fc90 100644
--- a/security/wpa_supplicant/files/patch-src_l2__packet_l2__packet__freebsd.c
+++ b/security/wpa_supplicant/files/patch-src_l2__packet_l2__packet__freebsd.c
@@ -1,5 +1,5 @@
---- src/l2_packet/l2_packet_freebsd.c.orig	2018-12-02 11:34:59.000000000 -0800
-+++ src/l2_packet/l2_packet_freebsd.c	2018-12-05 23:18:27.612433000 -0800
+--- src/l2_packet/l2_packet_freebsd.c.orig	2022-01-16 12:51:29.000000000 -0800
++++ src/l2_packet/l2_packet_freebsd.c	2022-04-14 07:21:15.259934000 -0700
 @@ -8,7 +8,8 @@
   */
  
@@ -10,3 +10,36 @@
  #include <net/bpf.h>
  #endif /* __APPLE__ */
  #include <pcap.h>
+@@ -76,24 +77,27 @@
+ {
+ 	struct l2_packet_data *l2 = eloop_ctx;
+ 	pcap_t *pcap = sock_ctx;
+-	struct pcap_pkthdr hdr;
++	struct pcap_pkthdr *hdr;
+ 	const u_char *packet;
+ 	struct l2_ethhdr *ethhdr;
+ 	unsigned char *buf;
+ 	size_t len;
+ 
+-	packet = pcap_next(pcap, &hdr);
++	if (pcap_next_ex(pcap, &hdr, &packet) == -1) {
++		wpa_printf(MSG_ERROR, "Error reading packet, has device disappeared?");
++		eloop_terminate();
++	}
+ 
+-	if (!l2->rx_callback || !packet || hdr.caplen < sizeof(*ethhdr))
++	if (!l2->rx_callback || !packet || hdr->caplen < sizeof(*ethhdr))
+ 		return;
+ 
+ 	ethhdr = (struct l2_ethhdr *) packet;
+ 	if (l2->l2_hdr) {
+ 		buf = (unsigned char *) ethhdr;
+-		len = hdr.caplen;
++		len = hdr->caplen;
+ 	} else {
+ 		buf = (unsigned char *) (ethhdr + 1);
+-		len = hdr.caplen - sizeof(*ethhdr);
++		len = hdr->caplen - sizeof(*ethhdr);
+ 	}
+ 	l2->rx_callback(l2->rx_callback_ctx, ethhdr->h_source, buf, len);
+ }