Skip to content

Commit 70ac1cd

Browse files
[AUTO-CHERRYPICK] Fix CVE-2023-7256 for libpcap :2.0 - branch main (#11121)
Co-authored-by: KavyaSree2610 <92566732+KavyaSree2610@users.noreply.github.com>
1 parent f5e5a7a commit 70ac1cd

2 files changed

Lines changed: 353 additions & 1 deletion

File tree

SPECS/libpcap/CVE-2023-7256.patch

Lines changed: 348 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,348 @@
1+
From 874acb4aa68ef27221b447738e946782e2dac474 Mon Sep 17 00:00:00 2001
2+
From: kavyasree <kkaitepalli@microsoft.com>
3+
Date: Mon, 18 Nov 2024 17:35:25 +0530
4+
Subject: [PATCH] Fix CVE-2023-7256
5+
6+
---
7+
pcap-rpcap.c | 50 ++++++++++++++------------
8+
rpcapd/daemon.c | 8 +++--
9+
rpcapd/rpcapd.c | 8 +++--
10+
sockutils.c | 96 +++++++++++++++++++++++++++++++++++--------------
11+
sockutils.h | 5 ++-
12+
5 files changed, 111 insertions(+), 56 deletions(-)
13+
14+
diff --git a/pcap-rpcap.c b/pcap-rpcap.c
15+
index 0c6c558..720bb67 100644
16+
--- a/pcap-rpcap.c
17+
+++ b/pcap-rpcap.c
18+
@@ -995,7 +995,6 @@ rpcap_remoteact_getsock(const char *host, int *error, char *errbuf)
19+
{
20+
struct activehosts *temp; /* temp var needed to scan the host list chain */
21+
struct addrinfo hints, *addrinfo, *ai_next; /* temp var needed to translate between hostname to its address */
22+
- int retval;
23+
24+
/* retrieve the network address corresponding to 'host' */
25+
addrinfo = NULL;
26+
@@ -1003,9 +1002,9 @@ rpcap_remoteact_getsock(const char *host, int *error, char *errbuf)
27+
hints.ai_family = PF_UNSPEC;
28+
hints.ai_socktype = SOCK_STREAM;
29+
30+
- retval = sock_initaddress(host, "0", &hints, &addrinfo, errbuf,
31+
+ addrinfo = sock_initaddress(host, NULL, &hints, errbuf,
32+
PCAP_ERRBUF_SIZE);
33+
- if (retval != 0)
34+
+ if (addrinfo == NULL)
35+
{
36+
*error = 1;
37+
return NULL;
38+
@@ -1151,7 +1150,9 @@ static int pcap_startcapture_remote(pcap_t *fp)
39+
hints.ai_flags = AI_PASSIVE; /* Data connection is opened by the server toward the client */
40+
41+
/* Let's the server pick up a free network port for us */
42+
- if (sock_initaddress(NULL, "0", &hints, &addrinfo, fp->errbuf, PCAP_ERRBUF_SIZE) == -1)
43+
+ addrinfo = sock_initaddress(NULL, NULL, &hints, fp->errbuf,
44+
+ PCAP_ERRBUF_SIZE);
45+
+ if (addrinfo == NULL)
46+
goto error_nodiscard;
47+
48+
if ((sockdata = sock_open(addrinfo, SOCKOPEN_SERVER,
49+
@@ -1263,7 +1264,9 @@ static int pcap_startcapture_remote(pcap_t *fp)
50+
snprintf(portdata, PCAP_BUF_SIZE, "%d", ntohs(startcapreply.portdata));
51+
52+
/* Let's the server pick up a free network port for us */
53+
- if (sock_initaddress(host, portdata, &hints, &addrinfo, fp->errbuf, PCAP_ERRBUF_SIZE) == -1)
54+
+ addrinfo = sock_initaddress(host, portstring, &hints,
55+
+ fp->errbuf, PCAP_ERRBUF_SIZE);
56+
+ if (addrinfo == NULL)
57+
goto error;
58+
59+
if ((sockdata = sock_open(addrinfo, SOCKOPEN_CLIENT, 0, fp->errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
60+
@@ -2206,16 +2209,16 @@ rpcap_setup_session(const char *source, struct pcap_rmtauth *auth,
61+
if (port[0] == 0)
62+
{
63+
/* the user chose not to specify the port */
64+
- if (sock_initaddress(host, RPCAP_DEFAULT_NETPORT,
65+
- &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
66+
- return -1;
67+
+ addrinfo = sock_initaddress(host, RPCAP_DEFAULT_NETPORT,
68+
+ &hints, errbuf, PCAP_ERRBUF_SIZE);
69+
}
70+
else
71+
{
72+
- if (sock_initaddress(host, port, &hints, &addrinfo,
73+
- errbuf, PCAP_ERRBUF_SIZE) == -1)
74+
- return -1;
75+
+ addrinfo = sock_initaddress(host, port, &hints,
76+
+ errbuf, PCAP_ERRBUF_SIZE);
77+
}
78+
+ if (addrinfo == NULL)
79+
+ return -1;
80+
81+
if ((*sockctrlp = sock_open(addrinfo, SOCKOPEN_CLIENT, 0,
82+
errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
83+
@@ -2811,17 +2814,18 @@ SOCKET pcap_remoteact_accept_ex(const char *address, const char *port, const cha
84+
/* Do the work */
85+
if ((port == NULL) || (port[0] == 0))
86+
{
87+
- if (sock_initaddress(address, RPCAP_DEFAULT_NETPORT_ACTIVE, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
88+
- {
89+
- return (SOCKET)-2;
90+
- }
91+
+ addrinfo = sock_initaddress(address,
92+
+ RPCAP_DEFAULT_NETPORT_ACTIVE, &hints, errbuf,
93+
+ PCAP_ERRBUF_SIZE);
94+
}
95+
else
96+
{
97+
- if (sock_initaddress(address, port, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
98+
- {
99+
- return (SOCKET)-2;
100+
- }
101+
+ addrinfo = sock_initaddress(address, port, &hints, errbuf,
102+
+ PCAP_ERRBUF_SIZE);
103+
+ }
104+
+ if (addrinfo == NULL)
105+
+ {
106+
+ return (SOCKET)-2;
107+
}
108+
109+
110+
@@ -2980,7 +2984,6 @@ int pcap_remoteact_close(const char *host, char *errbuf)
111+
{
112+
struct activehosts *temp, *prev; /* temp var needed to scan the host list chain */
113+
struct addrinfo hints, *addrinfo, *ai_next; /* temp var needed to translate between hostname to its address */
114+
- int retval;
115+
116+
temp = activeHosts;
117+
prev = NULL;
118+
@@ -2990,10 +2993,11 @@ int pcap_remoteact_close(const char *host, char *errbuf)
119+
memset(&hints, 0, sizeof(struct addrinfo));
120+
hints.ai_family = PF_UNSPEC;
121+
hints.ai_socktype = SOCK_STREAM;
122+
-
123+
- retval = sock_initaddress(host, "0", &hints, &addrinfo, errbuf,
124+
+
125+
+ addrinfo = sock_initaddress(host, NULL, &hints, errbuf,
126+
PCAP_ERRBUF_SIZE);
127+
- if (retval != 0)
128+
+
129+
+ if (addrinfo == NULL)
130+
{
131+
return -1;
132+
}
133+
diff --git a/rpcapd/daemon.c b/rpcapd/daemon.c
134+
index e2b20a9..60b5149 100644
135+
--- a/rpcapd/daemon.c
136+
+++ b/rpcapd/daemon.c
137+
@@ -2065,7 +2065,9 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen,
138+
goto error;
139+
}
140+
141+
- if (sock_initaddress(peerhost, portdata, &hints, &addrinfo, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
142+
+ addrinfo = sock_initaddress(peerhost, portdata, &hints,
143+
+ errmsgbuf, PCAP_ERRBUF_SIZE);
144+
+ if (addrinfo == NULL)
145+
goto error;
146+
147+
if ((session->sockdata = sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
148+
@@ -2076,7 +2078,9 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen,
149+
hints.ai_flags = AI_PASSIVE;
150+
151+
// Let's the server socket pick up a free network port for us
152+
- if (sock_initaddress(NULL, "0", &hints, &addrinfo, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
153+
+ addrinfo = sock_initaddress(NULL, NULL, &hints, errmsgbuf,
154+
+ PCAP_ERRBUF_SIZE);
155+
+ if (addrinfo == NULL)
156+
goto error;
157+
158+
if ((session->sockdata = sock_open(addrinfo, SOCKOPEN_SERVER, 1 /* max 1 connection in queue */, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
159+
diff --git a/rpcapd/rpcapd.c b/rpcapd/rpcapd.c
160+
index b91a401..74c138b 100644
161+
--- a/rpcapd/rpcapd.c
162+
+++ b/rpcapd/rpcapd.c
163+
@@ -610,7 +610,9 @@ void main_startup(void)
164+
//
165+
// Get a list of sockets on which to listen.
166+
//
167+
- if (sock_initaddress((address[0]) ? address : NULL, port, &mainhints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
168+
+ addrinfo = sock_initaddress((address[0]) ? address : NULL,
169+
+ port, &mainhints, errbuf, PCAP_ERRBUF_SIZE);
170+
+ if (addrinfo == NULL)
171+
{
172+
rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
173+
return;
174+
@@ -1347,7 +1349,9 @@ main_active(void *ptr)
175+
memset(errbuf, 0, sizeof(errbuf));
176+
177+
// Do the work
178+
- if (sock_initaddress(activepars->address, activepars->port, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
179+
+ addrinfo = sock_initaddress(activepars->address, activepars->port,
180+
+ &hints, errbuf, PCAP_ERRBUF_SIZE);
181+
+ if (addrinfo == NULL)
182+
{
183+
rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
184+
return 0;
185+
diff --git a/sockutils.c b/sockutils.c
186+
index ca16bbf..2cf48da 100644
187+
--- a/sockutils.c
188+
+++ b/sockutils.c
189+
@@ -704,31 +704,75 @@ get_gai_errstring(char *errbuf, int errbuflen, const char *prefix, int err,
190+
* \param errbuflen: length of the buffer that will contains the error. The error message cannot be
191+
* larger than 'errbuflen - 1' because the last char is reserved for the string terminator.
192+
*
193+
- * \return '0' if everything is fine, '-1' if some errors occurred. The error message is returned
194+
- * in the 'errbuf' variable. The addrinfo variable that has to be used in the following sockets calls is
195+
- * returned into the addrinfo parameter.
196+
- *
197+
- * \warning The 'addrinfo' variable has to be deleted by the programmer by calling freeaddrinfo() when
198+
- * it is no longer needed.
199+
- *
200+
+ * \return a pointer to the first element in a list of addrinfo structures
201+
+ * if everything is fine, NULL if some errors occurred. The error message
202+
+ * is returned in the 'errbuf' variable.
203+
+ *
204+
+ * \warning The list of addrinfo structures returned has to be deleted by
205+
+ * the programmer by calling freeaddrinfo() when it is no longer needed.
206+
+ *
207+
* \warning This function requires the 'hints' variable as parameter. The semantic of this variable is the same
208+
* of the one of the corresponding variable used into the standard getaddrinfo() socket function. We suggest
209+
* the programmer to look at that function in order to set the 'hints' variable appropriately.
210+
*/
211+
-int sock_initaddress(const char *host, const char *port,
212+
- struct addrinfo *hints, struct addrinfo **addrinfo, char *errbuf, int errbuflen)
213+
+struct addrinfo *sock_initaddress(const char *host, const char *port,
214+
+ struct addrinfo *hints, char *errbuf, int errbuflen)
215+
{
216+
+ struct addrinfo *addrinfo;
217+
int retval;
218+
-
219+
- retval = getaddrinfo(host, port, hints, addrinfo);
220+
+
221+
+ retval = getaddrinfo(host, port == NULL ? "0" : port, hints, &addrinfo);
222+
if (retval != 0)
223+
{
224+
+ /*
225+
+ * That call failed.
226+
+ * Determine whether the problem is that the host is bad.
227+
+ */
228+
if (errbuf)
229+
{
230+
- get_gai_errstring(errbuf, errbuflen, "", retval,
231+
- host, port);
232+
+ if (host != NULL && port != NULL) {
233+
+ /*
234+
+ * Try with just a host, to distinguish
235+
+ * between "host is bad" and "port is
236+
+ * bad".
237+
+ */
238+
+ int try_retval;
239+
+
240+
+ try_retval = getaddrinfo(host, NULL, hints,
241+
+ &addrinfo);
242+
+ if (try_retval == 0) {
243+
+ /*
244+
+ * Worked with just the host,
245+
+ * so assume the problem is
246+
+ * with the port.
247+
+ *
248+
+ * Free up the address info first.
249+
+ */
250+
+ freeaddrinfo(addrinfo);
251+
+ get_gai_errstring(errbuf, errbuflen,
252+
+ "", retval, NULL, port);
253+
+ } else {
254+
+ /*
255+
+ * Didn't work with just the host,
256+
+ * so assume the problem is
257+
+ * with the host; we assume
258+
+ * the original error indicates
259+
+ * the underlying problem.
260+
+ */
261+
+ get_gai_errstring(errbuf, errbuflen,
262+
+ "", retval, host, NULL);
263+
+ }
264+
+ } else {
265+
+ /*
266+
+ * Either the host or port was null, so
267+
+ * there's nothing to determine; report
268+
+ * the error from the original call.
269+
+ */
270+
+ get_gai_errstring(errbuf, errbuflen, "",
271+
+ retval, host, port);
272+
+ }
273+
}
274+
- return -1;
275+
+ return NULL;
276+
}
277+
/*
278+
* \warning SOCKET: I should check all the accept() in order to bind to all addresses in case
279+
@@ -743,30 +787,28 @@ int sock_initaddress(const char *host, const char *port,
280+
* ignore all addresses that are neither? (What, no IPX
281+
* support? :-))
282+
*/
283+
- if (((*addrinfo)->ai_family != PF_INET) &&
284+
- ((*addrinfo)->ai_family != PF_INET6))
285+
+ if ((addrinfo->ai_family != PF_INET) &&
286+
+ (addrinfo->ai_family != PF_INET6))
287+
{
288+
if (errbuf)
289+
snprintf(errbuf, errbuflen, "getaddrinfo(): socket type not supported");
290+
- freeaddrinfo(*addrinfo);
291+
- *addrinfo = NULL;
292+
- return -1;
293+
+ freeaddrinfo(addrinfo);
294+
+ return NULL;
295+
}
296+
297+
/*
298+
* You can't do multicast (or broadcast) TCP.
299+
*/
300+
- if (((*addrinfo)->ai_socktype == SOCK_STREAM) &&
301+
- (sock_ismcastaddr((*addrinfo)->ai_addr) == 0))
302+
+ if ((addrinfo->ai_socktype == SOCK_STREAM) &&
303+
+ (sock_ismcastaddr(addrinfo->ai_addr) == 0))
304+
{
305+
if (errbuf)
306+
snprintf(errbuf, errbuflen, "getaddrinfo(): multicast addresses are not valid when using TCP streams");
307+
- freeaddrinfo(*addrinfo);
308+
- *addrinfo = NULL;
309+
- return -1;
310+
+ freeaddrinfo(addrinfo);
311+
+ return NULL;
312+
}
313+
314+
- return 0;
315+
+ return addrinfo;
316+
}
317+
318+
/*
319+
@@ -1676,7 +1718,9 @@ int sock_present2network(const char *address, struct sockaddr_storage *sockaddr,
320+
321+
hints.ai_family = addr_family;
322+
323+
- if ((retval = sock_initaddress(address, "22222" /* fake port */, &hints, &addrinfo, errbuf, errbuflen)) == -1)
324+
+ addrinfo = sock_initaddress(address, "22222" /* fake port */, &hints,
325+
+ errbuf, errbuflen);
326+
+ if (addrinfo == NULL)
327+
return 0;
328+
329+
if (addrinfo->ai_family == PF_INET)
330+
diff --git a/sockutils.h b/sockutils.h
331+
index e748662..ede86a1 100644
332+
--- a/sockutils.h
333+
+++ b/sockutils.h
334+
@@ -129,9 +129,8 @@ int sock_init(char *errbuf, int errbuflen);
335+
void sock_cleanup(void);
336+
void sock_fmterror(const char *caller, int errcode, char *errbuf, int errbuflen);
337+
void sock_geterror(const char *caller, char *errbuf, int errbufsize);
338+
-int sock_initaddress(const char *address, const char *port,
339+
- struct addrinfo *hints, struct addrinfo **addrinfo,
340+
- char *errbuf, int errbuflen);
341+
+struct addrinfo *sock_initaddress(const char *address, const char *port,
342+
+ struct addrinfo *hints, char *errbuf, int errbuflen);
343+
int sock_recv(SOCKET sock, SSL *, void *buffer, size_t size, int receiveall,
344+
char *errbuf, int errbuflen);
345+
int sock_recv_dgram(SOCKET sock, SSL *, void *buffer, size_t size,
346+
--
347+
2.34.1
348+

SPECS/libpcap/libpcap.spec

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Summary: C/C++ library for network traffic capture
22
Name: libpcap
33
Version: 1.10.1
4-
Release: 3%{?dist}
4+
Release: 4%{?dist}
55
License: BSD
66
Vendor: Microsoft Corporation
77
Distribution: Mariner
@@ -10,6 +10,7 @@ URL: https://www.tcpdump.org/
1010
#Source0: https://github.com/the-tcpdump-group/%{name}/archive/%{name}-%{version}.tar.gz
1111
Source0: %{name}-%{name}-%{version}.tar.gz
1212
Patch0: CVE-2024-8006.patch
13+
Patch1: CVE-2023-7256.patch
1314

1415
%description
1516
Libpcap provides a portable framework for low-level network
@@ -78,6 +79,9 @@ make DESTDIR=%{buildroot} install
7879
%{_libdir}/*.a
7980

8081
%changelog
82+
* Mon Nov 18 2024 Kavya Sree Kaitepalli <kkaitepalli@microsoft.com> - 1.10.1-4
83+
- Fix CVE-2023-7256
84+
8185
* Mon Oct 21 2024 Sudipta Pandit <sudpandit@microsoft.com> - 1.10.1-3
8286
- Backport patch for CVE-2024-8006
8387

0 commit comments

Comments
 (0)