libpcap/backport-0001-CVE-2023-7256.patch
2024-09-19 12:38:32 +00:00

104 lines
4.3 KiB
Diff

From f72f48a26abdd2eb11a4a8fb3596ee67b8f8cbe6 Mon Sep 17 00:00:00 2001
From: Guy Harris <gharris@sonic.net>
Date: Wed, 21 Jul 2021 23:50:32 -0700
Subject: [PATCH] rpcap: don't do pointless integer->string and then
string->integer conversions.
The string->integer conversion was also broken, as it passed a pointer
to a 16-bit integer to a sscanf() call that used %d rather than %hd.
It'd overwrite 2 bytes past the 16-bit integer; it may set the integer
"correctly" on a little-endian, but wouldn't even do *that* on a
big-endian machine.
(cherry picked from commit efaddfe8eae4dab252bb2d35e004a40e4b72db24)
Conflict:Replacing snprintf with pcap_snprintf
context adapt
Reference:https://github.com/the-tcpdump-group/libpcap/commit/f72f48a26abdd2eb11a4a8fb3596ee67b8f8cbe6
---
pcap-rpcap.c | 34 ++++++++++++++++++++++++----------
1 file changed, 24 insertions(+), 10 deletions(-)
diff --git a/pcap-rpcap.c b/pcap-rpcap.c
index 705f06f..d9609c7 100644
--- a/pcap-rpcap.c
+++ b/pcap-rpcap.c
@@ -1014,7 +1014,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
struct pcap_rpcap *pr = fp->priv; /* structure used when doing a remote live capture */
char sendbuf[RPCAP_NETBUF_SIZE]; /* temporary buffer in which data to be sent is buffered */
int sendbufidx = 0; /* index which keeps the number of bytes currently buffered */
- char portdata[PCAP_BUF_SIZE]; /* temp variable needed to keep the network port for the data connection */
+ uint16 portdata = 0; /* temp variable needed to keep the network port for the data connection */
uint32 plen;
int active = 0; /* '1' if we're in active mode */
struct activehosts *temp; /* temp var needed to scan the host list chain, to detect if we're in active mode */
@@ -1027,6 +1027,8 @@ static int pcap_startcapture_remote(pcap_t *fp)
struct sockaddr_storage saddr; /* temp, needed to retrieve the network data port chosen on the local machine */
socklen_t saddrlen; /* temp, needed to retrieve the network data port chosen on the local machine */
int ai_family; /* temp, keeps the address family used by the control connection */
+ struct sockaddr_in *sin4;
+ struct sockaddr_in6 *sin6;
/* RPCAP-related variables*/
struct rpcap_header header; /* header of the RPCAP packet */
@@ -1121,11 +1123,22 @@ static int pcap_startcapture_remote(pcap_t *fp)
goto error_nodiscard;
}
- /* Get the local port the system picked up */
- if (getnameinfo((struct sockaddr *) &saddr, saddrlen, NULL,
- 0, portdata, sizeof(portdata), NI_NUMERICSERV))
- {
- sock_geterror("getnameinfo()", fp->errbuf, PCAP_ERRBUF_SIZE);
+ switch (saddr.ss_family) {
+
+ case AF_INET:
+ sin4 = (struct sockaddr_in *)&saddr;
+ portdata = sin4->sin_port;
+ break;
+
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *)&saddr;
+ portdata = sin6->sin6_port;
+ break;
+
+ default:
+ pcap_snprintf(fp->errbuf, PCAP_ERRBUF_SIZE,
+ "Local address has unknown address family %u",
+ saddr.ss_family);
goto error_nodiscard;
}
}
@@ -1158,8 +1171,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
/* portdata on the openreq is meaningful only if we're in active mode */
if ((active) || (pr->rmt_flags & PCAP_OPENFLAG_DATATX_UDP))
{
- sscanf(portdata, "%d", (int *)&(startcapreq->portdata)); /* cast to avoid a compiler warning */
- startcapreq->portdata = htons(startcapreq->portdata);
+ startcapreq->portdata = portdata;
}
startcapreq->snaplen = htonl(fp->snapshot);
@@ -1208,13 +1220,15 @@ static int pcap_startcapture_remote(pcap_t *fp)
{
if (!active)
{
+ char portstring[PCAP_BUF_SIZE];
+
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = ai_family; /* Use the same address family of the control socket */
hints.ai_socktype = (pr->rmt_flags & PCAP_OPENFLAG_DATATX_UDP) ? SOCK_DGRAM : SOCK_STREAM;
- pcap_snprintf(portdata, PCAP_BUF_SIZE, "%d", ntohs(startcapreply.portdata));
+ pcap_snprintf(portstring, PCAP_BUF_SIZE, "%d", ntohs(startcapreply.portdata));
/* Let's the server pick up a free network port for us */
- if (sock_initaddress(host, portdata, &hints, &addrinfo, fp->errbuf, PCAP_ERRBUF_SIZE) == -1)
+ if (sock_initaddress(host, portstring, &hints, &addrinfo, fp->errbuf, PCAP_ERRBUF_SIZE) == -1)
goto error;
if ((sockdata = sock_open(addrinfo, SOCKOPEN_CLIENT, 0, fp->errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
--
2.33.0