From: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
To: openembedded-core@lists.openembedded.org
Subject: [wrynose][PATCH 7/7] libpcap: Fix CVE-2026-18238
Date: Thu, 10 Sep 2026 07:11:54 +0200 [thread overview]
Message-ID: <20260910051154.30595-8-jaipaul.cheernam@est.tech> (raw)
In-Reply-To: <20260910051154.30595-1-jaipaul.cheernam@est.tech>
NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-18238
Upstream-commit: https://github.com/the-tcpdump-group/libpcap/commit/b9590d482986d64673712460aae1d48d11fa0473
Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
---
.../libpcap/libpcap/07-CVE-2026-18238.patch | 234 ++++++++++++++++++
.../libpcap/libpcap_1.10.6.bb | 1 +
2 files changed, 235 insertions(+)
create mode 100644 meta/recipes-connectivity/libpcap/libpcap/07-CVE-2026-18238.patch
diff --git a/meta/recipes-connectivity/libpcap/libpcap/07-CVE-2026-18238.patch b/meta/recipes-connectivity/libpcap/libpcap/07-CVE-2026-18238.patch
new file mode 100644
index 0000000000..373e64b1ff
--- /dev/null
+++ b/meta/recipes-connectivity/libpcap/libpcap/07-CVE-2026-18238.patch
@@ -0,0 +1,234 @@
+From 5aa9cfee8eb44967dec96199fde879022e4426d4 Mon Sep 17 00:00:00 2001
+From: Denis Ovsienko <denis@ovsienko.info>
+Date: Sat, 8 Aug 2026 00:31:10 +0100
+Subject: [PATCH] CVE-2026-18238: Fix RPCAP_MSG_PACKET validation.
+
+This vulnerability was originally reported publicly, hence no credit is
+given.
+
+When pcap_read_nocb_remote() validates a received message, it does not
+verify that there is a complete RPCAP_MSG_PACKET header in the rpcap
+general payload, also it uses an incorrect value to validate the length
+declared in the RPCAP_MSG_PACKET header. The latter can lead the
+protocol client to over-read the message buffer by 20 bytes, which in at
+least one scenario can cause a SIGSEGV.
+
+Fix this problem, as well as a potential integer overflow in the UDP
+code path on 32-bit architectures. To make message encoding and
+validation easier to follow, re-jig a few variables and update comments.
+
+(backported from commit 2d67e814e8d3791a8b508c359f94688c5669cce9)
+
+(cherry picked from commit b9590d482986d64673712460aae1d48d11fa0473)
+
+Upstream-Status: Backport [https://github.com/the-tcpdump-group/libpcap/commit/b9590d482986d64673712460aae1d48d11fa0473]
+CVE: CVE-2026-18238
+Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
+---
+ CHANGES | 1 +
+ pcap-rpcap.c | 117 ++++++++++++++++++++++++++++++++++++---------------
+ 2 files changed, 85 insertions(+), 33 deletions(-)
+diff --git a/CHANGES b/CHANGES
+index 4f24f94..8e29fd7 100644
+--- a/CHANGES
++++ b/CHANGES
+@@ -6,6 +6,7 @@
+ CVE-2026-6244: Avoid division by zero via pcap_offline_filter().
+ CVE-2026-6554: Limit "ja L" looping in pcap_offline_filter().
+ CVE-2026-18313: Fix a memory leak in rpcapd.
++ CVE-2026-18238: Fix RPCAP_MSG_PACKET validation.
+
+ Tuesday, December 30, 2025 / The Tcpdump Group
+ Summary for 1.10.6 libpcap release
+diff --git a/pcap-rpcap.c b/pcap-rpcap.c
+index 8f8960b9..b7f54641 100644
+--- a/pcap-rpcap.c
++++ b/pcap-rpcap.c
+@@ -389,10 +389,9 @@ rpcap_deseraddr(struct rpcap_sockaddr *sockaddrin, struct sockaddr **sockaddrout
+ static int pcap_read_nocb_remote(pcap_t *p, struct pcap_pkthdr *pkt_header, u_char **pkt_data)
+ {
+ struct pcap_rpcap *pr = p->priv; /* structure used when doing a remote live capture */
+- struct rpcap_header *header; /* general header according to the RPCAP format */
+- struct rpcap_pkthdr *net_pkt_header; /* header of the packet, from the message */
++ struct rpcap_header *gen_header; /* rpcap general header */
++ struct rpcap_pkthdr *net_pkt_header; /* RPCAP_MSG_PACKET header */
+ u_char *net_pkt_data; /* packet data from the message */
+- uint32 plen;
+ int retval = 0; /* generic return value */
+ int msglen;
+
+@@ -449,13 +448,35 @@ static int pcap_read_nocb_remote(pcap_t *p, struct pcap_pkthdr *pkt_header, u_ch
+ return 0;
+
+ /*
+- * We have to define 'header' as a pointer to a larger buffer,
+- * because in case of UDP we have to read all the message within a single call
++ * pcap_startcapture_remote() has pointed p->buffer to a buffer large
++ * enough to contain all of the following data at once:
++ *
++ * - a fixed-size rpcap general header
++ * - a fixed-size RPCAP_MSG_PACKET header
++ * - p->snapshot worth of bytes of a captured packet
++ *
++ * This is sufficient for all code paths below.
+ */
+- header = (struct rpcap_header *) p->buffer;
++ gen_header = (struct rpcap_header *)p->buffer;
+ net_pkt_header = (struct rpcap_pkthdr *) ((char *)p->buffer + sizeof(struct rpcap_header));
+ net_pkt_data = (u_char *)p->buffer + sizeof(struct rpcap_header) + sizeof(struct rpcap_pkthdr);
+
++ /*
++ * Step 1: to receive a message that does not immediately look
++ * malformed, consider it as a fixed-size rpcap general header followed
++ * by a variable-size rpcap general payload and require:
++ *
++ * - a complete rpcap general header to land in the buffer, and
++ * - the header to declare an rpcap general payload length that fits
++ * in the buffer after the header, and
++ * - the complete declared payload to land in the buffer after the
++ * header.
++ *
++ * Since this step loosely corresponds to rpcap_process_msg_header(),
++ * which among other things converts rpcap_header.plen to host byte
++ * order, mimic that as well to produce a valid argument for
++ * rpcap_check_msg_ver() later on.
++ */
+ if (pr->rmt_flags & PCAP_OPENFLAG_DATATX_UDP)
+ {
+ /* Read the entire message from the network */
+@@ -471,6 +492,8 @@ static int pcap_read_nocb_remote(pcap_t *p, struct pcap_pkthdr *pkt_header, u_ch
+ /* Interrupted receive. */
+ return 0;
+ }
++
++ // Require a complete rpcap general header to be present.
+ if ((size_t)msglen < sizeof(struct rpcap_header))
+ {
+ /*
+@@ -480,8 +503,18 @@ static int pcap_read_nocb_remote(pcap_t *p, struct pcap_pkthdr *pkt_header, u_ch
+ "UDP packet message is shorter than an rpcap header");
+ return -1;
+ }
+- plen = ntohl(header->plen);
+- if ((size_t)msglen < sizeof(struct rpcap_header) + plen)
++ gen_header->plen = ntohl(gen_header->plen);
++
++ /*
++ * Validate the rpcap general payload length declared in the
++ * rpcap general header. Use subtraction to avoid an integer
++ * overflow:
++ *
++ * 0 <= gen_header->plen <= UINT32_MAX
++ * sizeof(struct rpcap_header) <= msglen <= p->bufsize
++ * p->bufsize is significantly less than UINT32_MAX
++ */
++ if (gen_header->plen > (size_t)msglen - sizeof(struct rpcap_header))
+ {
+ /*
+ * Message is shorter than the header claims it
+@@ -496,6 +529,7 @@ static int pcap_read_nocb_remote(pcap_t *p, struct pcap_pkthdr *pkt_header, u_ch
+ {
+ int status;
+
++ // Receive a complete rpcap general header from the network.
+ if ((size_t)p->cc < sizeof(struct rpcap_header))
+ {
+ /*
+@@ -515,27 +549,35 @@ static int pcap_read_nocb_remote(pcap_t *p, struct pcap_pkthdr *pkt_header, u_ch
+ return 0;
+ }
+ }
++ gen_header->plen = ntohl(gen_header->plen);
+
+ /*
+- * We have the header, so we know how long the
+- * message payload is. The size we should get
+- * is the size of the packet header plus the
+- * size of the payload.
++ * Validate the rpcap general payload length declared in the
++ * rpcap general header. Use subtraction to avoid an integer
++ * overflow:
++ *
++ * 0 <= gen_header->plen <= UINT32_MAX
++ * sizeof(struct rpcap_header) < p->bufsize
++ * p->bufsize is significantly less than UINT32_MAX
+ */
+- plen = ntohl(header->plen);
+- if (plen > p->bufsize - sizeof(struct rpcap_header))
++ if (gen_header->plen > p->bufsize - sizeof(struct rpcap_header))
+ {
+ /*
+ * This is bigger than the largest
+- * record we'd expect. (We do it by
+- * subtracting in order to avoid an
+- * overflow.)
++ * record we'd expect.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Server sent us a message larger than the largest expected packet message");
+ return -1;
+ }
+- status = rpcap_read_packet_msg(pr, p, sizeof(struct rpcap_header) + plen);
++
++ /*
++ * Receive the declared rpcap general payload from the network.
++ *
++ * p->cc == sizeof(struct rpcap_header)
++ * p->bp == p->buffer + sizeof(struct rpcap_header)
++ */
++ status = rpcap_read_packet_msg(pr, p, sizeof(struct rpcap_header) + gen_header->plen);
+ if (status == -1)
+ {
+ /* Network error. */
+@@ -558,27 +600,36 @@ static int pcap_read_nocb_remote(pcap_t *p, struct pcap_pkthdr *pkt_header, u_ch
+
+ /*
+ * We have the entire message.
+- */
+- header->plen = plen;
+-
+- /*
+- * Did the server specify the version we negotiated?
++ * Step 2: to validate the received message further, require:
++ *
++ * - the rpcap general header to have the correct version and type, and
++ * - the rpcap general payload to be large enough to contain at least a
++ * complete RPCAP_MSG_PACKET header, and
++ * - the RPCAP_MSG_PACKET header to declare an RPCAP_MSG_PACKET payload
++ * (i.e. the captured packet) length that fits in the rpcap general
++ * payload (not the entire buffer) after the RPCAP_MSG_PACKET header.
+ */
+ if (rpcap_check_msg_ver(pr->rmt_sockdata, pr->data_ssl, pr->protocol_version,
+- header, p->errbuf) == -1)
+- {
++ gen_header, p->errbuf) == -1)
++ return 0; /* Return 'no packets received' */
++ if (gen_header->type != RPCAP_MSG_PACKET)
+ return 0; /* Return 'no packets received' */
++ if (gen_header->plen < sizeof(struct rpcap_pkthdr))
++ {
++ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
++ "Received an incomplete RPCAP_MSG_PACKET header.");
++ return -1;
+ }
+-
+ /*
+- * Is this a RPCAP_MSG_PACKET message?
++ * Validate the RPCAP_MSG_PACKET payload length declared in the
++ * RPCAP_MSG_PACKET header. Use subtraction to avoid an integer
++ * overflow:
++ *
++ * 0 <= ntohl(net_pkt_header->caplen) <= UINT32_MAX
++ * sizeof(struct rpcap_pkthdr) <= gen_header->plen
++ * gen_header->plen is significantly less than UINT32_MAX
+ */
+- if (header->type != RPCAP_MSG_PACKET)
+- {
+- return 0; /* Return 'no packets received' */
+- }
+-
+- if (ntohl(net_pkt_header->caplen) > plen)
++ if (ntohl(net_pkt_header->caplen) > gen_header->plen - sizeof(struct rpcap_pkthdr))
+ {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Packet's captured data goes past the end of the received packet message.");
diff --git a/meta/recipes-connectivity/libpcap/libpcap_1.10.6.bb b/meta/recipes-connectivity/libpcap/libpcap_1.10.6.bb
index 859897acc5..2844f4b2a9 100644
--- a/meta/recipes-connectivity/libpcap/libpcap_1.10.6.bb
+++ b/meta/recipes-connectivity/libpcap/libpcap_1.10.6.bb
@@ -18,6 +18,7 @@ SRC_URI = "https://www.tcpdump.org/release/${BP}.tar.xz \
file://04-CVE-2026-6244.patch \
file://05-CVE-2026-6554.patch \
file://06-CVE-2026-18313.patch \
+ file://07-CVE-2026-18238.patch \
"
SRC_URI[sha256sum] = "ec97d1206bdd19cb6bdd043eaa9f0037aa732262ec68e070fd7c7b5f834d5dfc"
prev parent reply other threads:[~2026-09-10 5:12 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-10 5:11 [wrynose][PATCH 0/7] libpcap: backport seven CVE fixes from 1.10.7 Jaipaul Cheernam
2026-09-10 5:11 ` [wrynose][PATCH 1/7] libpcap: Fix CVE-2026-0799 Jaipaul Cheernam
2026-09-10 5:11 ` [wrynose][PATCH 2/7] libpcap: Fix CVE-2026-31912 Jaipaul Cheernam
2026-09-10 5:11 ` [wrynose][PATCH 3/7] libpcap: Fix CVE-2026-31911 Jaipaul Cheernam
2026-09-10 5:11 ` [wrynose][PATCH 4/7] libpcap: Fix CVE-2026-6244 Jaipaul Cheernam
2026-09-10 5:11 ` [wrynose][PATCH 5/7] libpcap: Fix CVE-2026-6554 Jaipaul Cheernam
2026-09-10 5:11 ` [wrynose][PATCH 6/7] libpcap: Fix CVE-2026-18313 Jaipaul Cheernam
2026-09-10 5:11 ` Jaipaul Cheernam [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260910051154.30595-8-jaipaul.cheernam@est.tech \
--to=jaipaul.cheernam@est.tech \
--cc=openembedded-core@lists.openembedded.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.