* [scarthgap][PATCH 0/7] libpcap: backport seven CVE fixes from 1.10.7
@ 2026-09-15 19:45 Jaipaul Cheernam
2026-09-15 19:45 ` [scarthgap][PATCH 1/7] libpcap: Fix CVE-2026-0799 Jaipaul Cheernam
` (7 more replies)
0 siblings, 8 replies; 17+ messages in thread
From: Jaipaul Cheernam @ 2026-09-15 19:45 UTC (permalink / raw)
To: openembedded-core
This series backports the seven security fixes that were released in
libpcap 1.10.7 to the 1.10.4 recipe.
The same set of fixes has already been addressed on master by upgrading
libpcap to 1.10.7.
CVEs addressed (see the upstream 1.10.7 CHANGES):
CVE-2026-0799 - Access M[] safely in the BPF interpreter.
CVE-2026-31912 - Mind the program bounds in pcap_offline_filter().
CVE-2026-31911 - Fail opcodes safely in the BPF interpreter.
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.
Each CVE is a separate file:// patch, ordered so they apply on top of each
other. Where a fix touches the BPF filter interpreter it is translated to
the 1.10.4 pcap_filter naming (the pcapint_* rename is newer), and
prerequisites that are not part of these CVEs (the pcap_filter refactor's
neighbouring changes, the "bogus" -> "invalid" rewording, the low-snaplen
fixes) were dropped. The pcap-haiku.c hunk does not apply since 1.10.4's
Haiku module does not yet call the filter. The upstream CHANGES/changelog
hunk is not backported. Patches note the relevant adjustments.
Verified by applying all seven patches in order onto a pristine libpcap
1.10.4 tree and building successfully, including with --enable-remote
(rpcapd).
Jaipaul Cheernam (7):
libpcap: Fix CVE-2026-0799
libpcap: Fix CVE-2026-31912
libpcap: Fix CVE-2026-31911
libpcap: Fix CVE-2026-6244
libpcap: Fix CVE-2026-6554
libpcap: Fix CVE-2026-18313
libpcap: Fix CVE-2026-18238
.../libpcap/libpcap/01-CVE-2026-0799.patch | 64 +++
.../libpcap/libpcap/02-CVE-2026-31912.patch | 520 ++++++++++++++++++
.../libpcap/libpcap/03-CVE-2026-31911.patch | 42 ++
.../libpcap/libpcap/04-CVE-2026-6244.patch | 46 ++
.../libpcap/libpcap/05-CVE-2026-6554.patch | 87 +++
.../libpcap/libpcap/06-CVE-2026-18313.patch | 81 +++
.../libpcap/libpcap/07-CVE-2026-18238.patch | 219 ++++++++
.../libpcap/libpcap_1.10.4.bb | 7 +
8 files changed, 1066 insertions(+)
create mode 100644 meta/recipes-connectivity/libpcap/libpcap/01-CVE-2026-0799.patch
create mode 100644 meta/recipes-connectivity/libpcap/libpcap/02-CVE-2026-31912.patch
create mode 100644 meta/recipes-connectivity/libpcap/libpcap/03-CVE-2026-31911.patch
create mode 100644 meta/recipes-connectivity/libpcap/libpcap/04-CVE-2026-6244.patch
create mode 100644 meta/recipes-connectivity/libpcap/libpcap/05-CVE-2026-6554.patch
create mode 100644 meta/recipes-connectivity/libpcap/libpcap/06-CVE-2026-18313.patch
create mode 100644 meta/recipes-connectivity/libpcap/libpcap/07-CVE-2026-18238.patch
^ permalink raw reply [flat|nested] 17+ messages in thread* [scarthgap][PATCH 1/7] libpcap: Fix CVE-2026-0799 2026-09-15 19:45 [scarthgap][PATCH 0/7] libpcap: backport seven CVE fixes from 1.10.7 Jaipaul Cheernam @ 2026-09-15 19:45 ` Jaipaul Cheernam 2026-09-15 19:45 ` [scarthgap][PATCH 2/7] libpcap: Fix CVE-2026-31912 Jaipaul Cheernam ` (6 subsequent siblings) 7 siblings, 0 replies; 17+ messages in thread From: Jaipaul Cheernam @ 2026-09-15 19:45 UTC (permalink / raw) To: openembedded-core NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-0799 Upstream-commit: https://github.com/the-tcpdump-group/libpcap/commit/48e8960a7108e9e828f9d7bdc7e97bdab841aec7 Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> --- .../libpcap/libpcap/01-CVE-2026-0799.patch | 64 +++++++++++++++++++ .../libpcap/libpcap_1.10.4.bb | 1 + 2 files changed, 65 insertions(+) create mode 100644 meta/recipes-connectivity/libpcap/libpcap/01-CVE-2026-0799.patch diff --git a/meta/recipes-connectivity/libpcap/libpcap/01-CVE-2026-0799.patch b/meta/recipes-connectivity/libpcap/libpcap/01-CVE-2026-0799.patch new file mode 100644 index 0000000000..8651079d0f --- /dev/null +++ b/meta/recipes-connectivity/libpcap/libpcap/01-CVE-2026-0799.patch @@ -0,0 +1,64 @@ +From 48e8960a7108e9e828f9d7bdc7e97bdab841aec7 Mon Sep 17 00:00:00 2001 +From: Denis Ovsienko <denis@ovsienko.info> +Date: Thu, 30 Jul 2026 13:33:41 +0100 +Subject: [PATCH] CVE-2026-0799: Access M[] safely in the BPF interpreter. + +Include Security identified and reported this problem as a potential +vulnerability in 2018 (case reference "I7"). Their work was sponsored +by Mozilla under the Secure Open Source program. The vulnerability has +been independently confirmed only recently. + +The current revision of pcapint_filter_with_aux_data() can, but does not +check whether a scratch memory register index is valid in the "ld M[k]", +"ldx M[k]", "st M[k]" and "stx M[k]" BPF instructions, and assumes this +is always the case. This holds for programs that have been generated or +validated by libpcap. + +However, this does not necessarily hold for programs that come via +pcap_offline_filter() or [deprecated] bpf_filter() from an external +source and have not been explicitly validated. If the interpreter +executes such a program with an invalid index, it will read/write the +process memory at arbitrary locations starting at the current stack +frame. Depending on the address, the memory layout and the OS, this can +result in stack buffer overflow, SIGSEGV, SIGBUS or other effects. To +fix this, in the interpreter reject the packet if the index is invalid. + +(backported from commit 569f8fd3524192acbabf93c9cd704471bb38f84a) + +(cherry picked from commit 48e8960a7108e9e828f9d7bdc7e97bdab841aec7) + +Upstream-Status: Backport [https://github.com/the-tcpdump-group/libpcap/commit/48e8960a7108e9e828f9d7bdc7e97bdab841aec7] +CVE: CVE-2026-0799 +Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> +--- +diff --git a/bpf_filter.c b/bpf_filter.c +index 8691d0d1..fa82d1d0 100644 +--- a/bpf_filter.c ++++ b/bpf_filter.c +@@ -219,18 +219,26 @@ DIAG_ON_DEFAULT_ONLY_SWITCH + continue; + + case BPF_LD|BPF_MEM: ++ if (pc->k >= BPF_MEMWORDS) ++ return 0; + A = mem[pc->k]; + continue; + + case BPF_LDX|BPF_MEM: ++ if (pc->k >= BPF_MEMWORDS) ++ return 0; + X = mem[pc->k]; + continue; + + case BPF_ST: ++ if (pc->k >= BPF_MEMWORDS) ++ return 0; + mem[pc->k] = A; + continue; + + case BPF_STX: ++ if (pc->k >= BPF_MEMWORDS) ++ return 0; + mem[pc->k] = X; + continue; + diff --git a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb index ee7d7540f6..692fdf606c 100644 --- a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb +++ b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb @@ -17,6 +17,7 @@ SRC_URI = "https://www.tcpdump.org/release/${BP}.tar.gz \ file://CVE-2025-11961-01.patch \ file://CVE-2025-11961-02.patch \ file://CVE-2025-11964.patch \ + file://01-CVE-2026-0799.patch \ " SRC_URI[sha256sum] = "ed19a0383fad72e3ad435fd239d7cd80d64916b87269550159d20e47160ebe5f" ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [scarthgap][PATCH 2/7] libpcap: Fix CVE-2026-31912 2026-09-15 19:45 [scarthgap][PATCH 0/7] libpcap: backport seven CVE fixes from 1.10.7 Jaipaul Cheernam 2026-09-15 19:45 ` [scarthgap][PATCH 1/7] libpcap: Fix CVE-2026-0799 Jaipaul Cheernam @ 2026-09-15 19:45 ` Jaipaul Cheernam 2026-09-15 19:45 ` [scarthgap][PATCH 3/7] libpcap: Fix CVE-2026-31911 Jaipaul Cheernam ` (5 subsequent siblings) 7 siblings, 0 replies; 17+ messages in thread From: Jaipaul Cheernam @ 2026-09-15 19:45 UTC (permalink / raw) To: openembedded-core NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-31912 Upstream-commit: https://github.com/the-tcpdump-group/libpcap/commit/d3f358d3cffbe1ecb94d5284b3e81f052a0adcb9 Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> --- .../libpcap/libpcap/02-CVE-2026-31912.patch | 520 ++++++++++++++++++ .../libpcap/libpcap_1.10.4.bb | 1 + 2 files changed, 521 insertions(+) create mode 100644 meta/recipes-connectivity/libpcap/libpcap/02-CVE-2026-31912.patch diff --git a/meta/recipes-connectivity/libpcap/libpcap/02-CVE-2026-31912.patch b/meta/recipes-connectivity/libpcap/libpcap/02-CVE-2026-31912.patch new file mode 100644 index 0000000000..1173a4f9d7 --- /dev/null +++ b/meta/recipes-connectivity/libpcap/libpcap/02-CVE-2026-31912.patch @@ -0,0 +1,520 @@ +From d3f358d3cffbe1ecb94d5284b3e81f052a0adcb9 Mon Sep 17 00:00:00 2001 +From: Denis Ovsienko <denis@ovsienko.info> +Date: Thu, 30 Jul 2026 13:33:55 +0100 +Subject: [PATCH] CVE-2026-31912: Mind the program bounds in pcap_offline_filter(). + +The current revision of pcapint_filter_with_aux_data() does not know the +number of instructions in the filter program, it assumes the program +counter always remains within the bounds of the provided filter program +and always reaches a return instruction. This holds for programs that +have been generated or validated by libpcap. + +However, this does not necessarily hold for programs that come from an +external source via pcap_offline_filter() or [deprecated] bpf_filter() +and have not been explicitly validated. If the interpreter executes +such a program and advances the program counter beyond the last +instruction, it will be interpreting memory space after the filter +program as BPF instructions, which in the current implementation will +eventually cause either abort() (another commit addresses that) or +SIGSEGV. + +To fix the latter problem, in pcapint_filter_with_aux_data() add a +parameter for the number of instructions in the program and reject the +packet as soon as (or just before) the program counter goes out of +bounds. Update all incoming code paths to specify the length; also in +pcap_offline_filter(3PCAP) make it clear the function now requires the +'bf_len' member to be set correctly and uses it. + +(backported from commit d1209988c74dd9330659898d3b676ee6bbe1c551) + +(cherry picked from commit d3f358d3cffbe1ecb94d5284b3e81f052a0adcb9) + +Upstream-Status: Backport [https://github.com/the-tcpdump-group/libpcap/commit/d3f358d3cffbe1ecb94d5284b3e81f052a0adcb9] +CVE: CVE-2026-31912 +Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> +--- +diff --git a/bpf_filter.c b/bpf_filter.c +index fa82d1d0..dec336ea 100644 +--- a/bpf_filter.c ++++ b/bpf_filter.c +@@ -72,6 +72,24 @@ enum { + BPF_S_ANC_VLAN_TAG_PRESENT, + }; + ++/* ++ * Kernel BPF implementations tend to define BPF_MAXINSNS to 512 or 4096, the ++ * userland interpreter in libpcap is meant to support much longer filter ++ * programs. In the latter case it is important that BPF_MAXINSNS does not ++ * interfere with the safety checks in the validator and the interpreter: ++ * (BPF_MAXINSNS + UINT8_MAX) * sizeof(struct bpf_insn) < UINT32_MAX ++ * It makes the most sense to be able to interpret as many instructions as ++ * pcap_compile() can produce, without optimization, for a valid filter ++ * expression before it consumes as much memory as the current definitions of ++ * NCHUNKS and CHUNKSIZE() allow. For some expressions this can be almost ++ * 1.53 million instructions on a 64-bit machine and twice as many on a 32-bit ++ * machine. ++ */ ++#ifdef BPF_MAXINSNS ++#undef BPF_MAXINSNS ++#endif ++#define BPF_MAXINSNS 3060000U ++ + /* + * Execute the filter program starting at pc on the packet p + * wirelen is the length of the original packet +@@ -86,12 +104,14 @@ enum { + */ + #if defined(SKF_AD_VLAN_TAG_PRESENT) + u_int +-pcap_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p, +- u_int wirelen, u_int buflen, const struct pcap_bpf_aux_data *aux_data) ++pcap_filter_with_aux_data(const struct bpf_insn *pc, const u_int proglen, ++ const u_char *p, const u_int wirelen, const u_int buflen, ++ const struct pcap_bpf_aux_data *aux_data) + #else + u_int +-pcap_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p, +- u_int wirelen, u_int buflen, const struct pcap_bpf_aux_data *aux_data _U_) ++pcap_filter_with_aux_data(const struct bpf_insn *pc, const u_int proglen, ++ const u_char *p, const u_int wirelen, const u_int buflen, ++ const struct pcap_bpf_aux_data *aux_data _U_) + #endif + { + register uint32_t A, X; +@@ -101,13 +121,36 @@ pcap_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p, + if (pc == 0) + /* + * No filter means accept all. ++ * In this case the value of 'proglen' is irrelevant. + */ + return (u_int)-1; ++ if (proglen < 1 || proglen > BPF_MAXINSNS) ++ return 0; ++ ++ /* ++ * Require the current instruction pointer not to overflow for both the ++ * filter program (where the pointer will be dereferenced) and an ++ * immediately following margin (where it will be not). So long as the ++ * margin is large enough to represent the destination of any single ++ * conditional [forward] jump from within the filter program, a single ++ * guard prevents all filter program over-read attempts that result ++ * from the program running out of instructions before a BPF_RET or a ++ * conditional jump directing the interpreter beyond the program end. ++ * Unconditional jumps mean a larger problem space, which the BPF_JA ++ * case below addresses separately. ++ */ ++ const struct bpf_insn *pcend = pc + proglen; ++ if (pcend + UINT8_MAX < pc) ++ return 0; ++ + A = 0; + X = 0; ++ const struct bpf_insn *pc0 = pc; + --pc; + for (;;) { + ++pc; ++ if (pc >= pcend) ++ return 0; + switch (pc->code) { + + default: +@@ -243,6 +286,40 @@ DIAG_ON_DEFAULT_ONLY_SWITCH + continue; + + case BPF_JMP|BPF_JA: ++ /* ++ * The pointer (pc) decrements and increments in units ++ * of sizeof(struct bpf_insn) == 8 bytes. The number ++ * of units is in the [INT32_MIN, INT32_MAX] interval, ++ * hence the result can point before the beginning or ++ * beyond the end of the filter program and can under- ++ * or overflow; also on 32-bit architectures it can ++ * under- or overflow more than once and can test ++ * negative for underflow, overflow and out-of-range ++ * conditions after under- or overflowing at least ++ * once. ++ * ++ * However, it has been verified above that the program ++ * length is sufficiently small and the pointer does ++ * not wrap within the bounds of the filter program, so ++ * there is a one-to-one correspondence between BPF ++ * program counter values [0, proglen) and all valid ++ * values of the pointer. In other words, after this ++ * unconditional jump the pointer arithmetic result ++ * will be valid iff BPF program counter value will be ++ * valid. For the latter problem the solution is ++ * almost the same as in the validator. ++ * ++ * The main difference is that here the current value ++ * of BPF program counter is not a 32-bit unsigned ++ * variable, but a ptrdiff_t expression, which is ++ * 64-bit signed on 64-bit architectures and 32-bit ++ * signed on 32-bit architectures. However, the cast ++ * to 32-bit unsigned is safe in both cases because: ++ * pc0 <= pc < pc0 + proglen, therefore: ++ * 0 <= pc - pc0 < proglen <= BPF_MAXINSNS < INT32_MAX ++ */ ++ if ((bpf_u_int32)(pc - pc0) + 1 + pc->k >= proglen) ++ return 0; + /* + * XXX - we currently implement "ip6 protochain" + * with backward jumps, so sign-extend pc->k. +@@ -396,10 +473,10 @@ DIAG_ON_DEFAULT_ONLY_SWITCH + } + + u_int +-pcap_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen, +- u_int buflen) ++pcap_filter(const struct bpf_insn *pc, const u_int proglen, const u_char *p, ++ u_int wirelen, u_int buflen) + { +- return pcap_filter_with_aux_data(pc, p, wirelen, buflen, NULL); ++ return pcap_filter_with_aux_data(pc, proglen, p, wirelen, buflen, NULL); + } + + /* +@@ -419,7 +496,7 @@ pcap_validate_filter(const struct bpf_insn *f, int len) + u_int i, from; + const struct bpf_insn *p; + +- if (len < 1) ++ if (len < 1 || (u_int)len > BPF_MAXINSNS || f + len < f) + return 0; + + for (i = 0; i < (u_int)len; ++i) { +@@ -485,33 +562,45 @@ pcap_validate_filter(const struct bpf_insn *f, int len) + case BPF_JMP: + /* + * Check that jumps are within the code block, +- * and that unconditional branches don't go +- * backwards as a result of an overflow. ++ * regardless of the direction. libpcap uses ++ * backward jumps to implement the "protochain" ++ * primitive. All offsets that mean a backward ++ * jump in libpcap (whether in-range or not) in ++ * kernel BPF implementations mean out-of-range ++ * or overflow forward jumps -- kernel ++ * implementations must reject that. ++ * + * Unconditional branches have a 32-bit offset, + * so they could overflow; we check to make + * sure they don't. Conditional branches have + * an 8-bit offset, and the from address is <= +- * BPF_MAXINSNS, and we assume that BPF_MAXINSNS ++ * BPF_MAXINSNS, and we know that BPF_MAXINSNS + * is sufficiently small that adding 255 to it + * won't overflow. + * + * We know that len is <= BPF_MAXINSNS, and we +- * assume that BPF_MAXINSNS is < the maximum size ++ * know that BPF_MAXINSNS is < the maximum value + * of a u_int, so that i + 1 doesn't overflow. +- * +- * For userland, we don't know that the from +- * or len are <= BPF_MAXINSNS, but we know that +- * from <= len, and, except on a 64-bit system, +- * it's unlikely that len, if it truly reflects +- * the size of the program we've been handed, +- * will be anywhere near the maximum size of +- * a u_int. We also don't check for backward +- * branches, as we currently support them in +- * userland for the protochain operation. + */ + from = i + 1; + switch (BPF_OP(p->code)) { + case BPF_JA: ++ /* ++ * So long as both 'from' and bpf_insn.k are ++ * 32-bit unsigned, this check rejects any jump ++ * offset that points outside of the valid BPF ++ * address space of the filter program no ++ * matter whether signed interpretation of the ++ * offset is positive or negative. ++ * ++ * Note that this condition is necessary, but ++ * not sufficient to get correct results from ++ * respective pointer arithmetic in the process ++ * address space. Other necessary conditions ++ * are that BPF_MAXINSNS is correctly defined ++ * and enforced, and that the pointer does not ++ * overflow. ++ */ + if (from + p->k >= (u_int)len) + return 0; + break; +@@ -539,12 +628,14 @@ pcap_validate_filter(const struct bpf_insn *f, int len) + + /* + * Exported because older versions of libpcap exported them. ++ * This function is deprecated and unsafe, use pcap_offline_filter() instead. + */ + u_int + bpf_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen, + u_int buflen) + { +- return pcap_filter(pc, p, wirelen, buflen); ++ // The actual length of the filter program is not known. ++ return pcap_filter(pc, BPF_MAXINSNS, p, wirelen, buflen); + } + + int +diff --git a/dlpisubs.c b/dlpisubs.c +index 6815b0ec..790acf28 100644 +--- a/dlpisubs.c ++++ b/dlpisubs.c +@@ -195,7 +195,8 @@ pcap_process_pkts(pcap_t *p, pcap_handler callback, u_char *user, + bufp += caplen; + #endif + ++pd->stat.ps_recv; +- if (pcap_filter(p->fcode.bf_insns, pk, origlen, caplen)) { ++ if (pcap_filter(p->fcode.bf_insns, p->fcode.bf_len, ++ pk, origlen, caplen)) { + #ifdef HAVE_SYS_BUFMOD_H + pkthdr.ts.tv_sec = sbp->sbh_timestamp.tv_sec; + pkthdr.ts.tv_usec = sbp->sbh_timestamp.tv_usec; +diff --git a/pcap-bpf.c b/pcap-bpf.c +index 2898e598..04b5620d 100644 +--- a/pcap-bpf.c ++++ b/pcap-bpf.c +@@ -1255,7 +1255,8 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) + #endif + */ + if (pb->filtering_in_kernel || +- pcap_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) { ++ pcap_filter(p->fcode.bf_insns, p->fcode.bf_len, ++ datap, bhp->bh_datalen, caplen)) { + struct pcap_pkthdr pkthdr; + #ifdef BIOCSTSTAMP + struct bintime bt; +diff --git a/pcap-bt-linux.c b/pcap-bt-linux.c +index c7bfef1d..dcf3b575 100644 +--- a/pcap-bt-linux.c ++++ b/pcap-bt-linux.c +@@ -394,7 +394,8 @@ bt_read_linux(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char + pkth.caplen+=sizeof(pcap_bluetooth_h4_header); + pkth.len = pkth.caplen; + if (handle->fcode.bf_insns == NULL || +- pcap_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) { ++ pcap_filter(handle->fcode.bf_insns, handle->fcode.bf_len, ++ pktd, pkth.len, pkth.caplen)) { + callback(user, &pkth, pktd); + return 1; + } +diff --git a/pcap-bt-monitor-linux.c b/pcap-bt-monitor-linux.c +index 206e65b5..3f9d5b49 100644 +--- a/pcap-bt-monitor-linux.c ++++ b/pcap-bt-monitor-linux.c +@@ -151,7 +151,8 @@ bt_monitor_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_ch + bthdr->opcode = htons(hdr.opcode); + + if (handle->fcode.bf_insns == NULL || +- pcap_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) { ++ pcap_filter(handle->fcode.bf_insns, handle->fcode.bf_len, ++ pktd, pkth.len, pkth.caplen)) { + callback(user, &pkth, pktd); + return 1; + } +diff --git a/pcap-dag.c b/pcap-dag.c +index f261ead0..c3fe1dbd 100644 +--- a/pcap-dag.c ++++ b/pcap-dag.c +@@ -668,8 +668,9 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) + caplen = p->snapshot; + + /* Run the packet filter if there is one. */ +- if ((p->fcode.bf_insns == NULL) || pcap_filter(p->fcode.bf_insns, dp, packet_len, caplen)) { +- ++ if (p->fcode.bf_insns == NULL || ++ pcap_filter(p->fcode.bf_insns, p->fcode.bf_len, ++ dp, packet_len, caplen)) { + /* convert between timestamp formats */ + register unsigned long long ts; + +diff --git a/pcap-dbus.c b/pcap-dbus.c +index 506f150f..760bb9ba 100644 +--- a/pcap-dbus.c ++++ b/pcap-dbus.c +@@ -91,7 +91,8 @@ dbus_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *us + + gettimeofday(&pkth.ts, NULL); + if (handle->fcode.bf_insns == NULL || +- pcap_filter(handle->fcode.bf_insns, (u_char *)raw_msg, pkth.len, pkth.caplen)) { ++ pcap_filter(handle->fcode.bf_insns, handle->fcode.bf_len, ++ (u_char *)raw_msg, pkth.len, pkth.caplen)) { + handlep->packets_read++; + callback(user, &pkth, (u_char *)raw_msg); + count++; +diff --git a/pcap-dpdk.c b/pcap-dpdk.c +index 025a6748..cc31d2f2 100644 +--- a/pcap-dpdk.c ++++ b/pcap-dpdk.c +@@ -407,7 +407,9 @@ static int pcap_dpdk_dispatch(pcap_t *p, int max_cnt, pcap_handler cb, u_char *c + + } + if (bp){ +- if (p->fcode.bf_insns==NULL || pcap_filter(p->fcode.bf_insns, bp, pcap_header.len, pcap_header.caplen)){ ++ if (p->fcode.bf_insns==NULL || ++ pcap_filter(p->fcode.bf_insns, p->fcode.bf_len, ++ bp, pcap_header.len, pcap_header.caplen)){ + cb(cb_arg, &pcap_header, bp); + }else{ + pd->bpf_drop++; +diff --git a/pcap-int.h b/pcap-int.h +index 894e74af..11ca3c56 100644 +--- a/pcap-int.h ++++ b/pcap-int.h +@@ -619,13 +619,15 @@ struct pcap_bpf_aux_data { + * Filtering routine that takes the auxiliary data as an additional + * argument. + */ +-u_int pcap_filter_with_aux_data(const struct bpf_insn *, +- const u_char *, u_int, u_int, const struct pcap_bpf_aux_data *); ++u_int pcap_filter_with_aux_data(const struct bpf_insn *, const u_int, ++ const u_char *, const u_int, const u_int, ++ const struct pcap_bpf_aux_data *); + + /* + * Filtering routine that doesn't. + */ +-u_int pcap_filter(const struct bpf_insn *, const u_char *, u_int, u_int); ++u_int pcap_filter(const struct bpf_insn *, const u_int, const u_char *, ++ u_int, u_int); + + /* + * Routine to validate a BPF program. +diff --git a/pcap-linux.c b/pcap-linux.c +index 13bd8529..b2b2ca70 100644 +--- a/pcap-linux.c ++++ b/pcap-linux.c +@@ -3993,6 +3993,7 @@ static int pcap_handle_packet_mmap( + aux_data.vlan_tag = tp_vlan_tci & 0x0fff; + + if (pcap_filter_with_aux_data(handle->fcode.bf_insns, ++ handle->fcode.bf_len, + bp, + tp_len, + snaplen, +diff --git a/pcap-netfilter-linux.c b/pcap-netfilter-linux.c +index 2eb0fc8c..5b5f5c18 100644 +--- a/pcap-netfilter-linux.c ++++ b/pcap-netfilter-linux.c +@@ -259,8 +259,8 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c + + gettimeofday(&pkth.ts, NULL); + if (handle->fcode.bf_insns == NULL || +- pcap_filter(handle->fcode.bf_insns, payload, pkth.len, pkth.caplen)) +- { ++ pcap_filter(handle->fcode.bf_insns, handle->fcode.bf_len, ++ payload, pkth.len, pkth.caplen)) { + handlep->packets_read++; + callback(user, &pkth, payload); + count++; +diff --git a/pcap-netmap.c b/pcap-netmap.c +index 27d36e5b..bcfd6e93 100644 +--- a/pcap-netmap.c ++++ b/pcap-netmap.c +@@ -81,7 +81,8 @@ pcap_netmap_filter(u_char *arg, struct pcap_pkthdr *h, const u_char *buf) + const struct bpf_insn *pc = p->fcode.bf_insns; + + ++pn->rx_pkts; +- if (pc == NULL || pcap_filter(pc, buf, h->len, h->caplen)) ++ if (pc == NULL || ++ pcap_filter(pc, p->fcode.bf_len, buf, h->len, h->caplen)) + pn->cb(pn->cb_arg, h, buf); + } + +diff --git a/pcap-npf.c b/pcap-npf.c +index 99b5981e..a4364353 100644 +--- a/pcap-npf.c ++++ b/pcap-npf.c +@@ -682,7 +682,8 @@ pcap_read_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) + */ + if (pw->filtering_in_kernel || + p->fcode.bf_insns == NULL || +- pcap_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) { ++ pcap_filter(p->fcode.bf_insns, p->fcode.bf_len, ++ datap, bhp->bh_datalen, caplen)) { + #ifdef ENABLE_REMOTE + switch (p->rmt_samp.method) { + +diff --git a/pcap-rdmasniff.c b/pcap-rdmasniff.c +index d63ca898..c8763b33 100644 +--- a/pcap-rdmasniff.c ++++ b/pcap-rdmasniff.c +@@ -172,7 +172,8 @@ rdmasniff_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u + pktd = (u_char *) handle->buffer + wc.wr_id * RDMASNIFF_RECEIVE_SIZE; + + if (handle->fcode.bf_insns == NULL || +- pcap_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) { ++ pcap_filter(handle->fcode.bf_insns, handle->fcode.bf_len, ++ pktd, pkth.len, pkth.caplen)) { + callback(user, &pkth, pktd); + ++priv->packets_recv; + ++count; +diff --git a/pcap-snf.c b/pcap-snf.c +index fe9cc9c8..16ce9c8e 100644 +--- a/pcap-snf.c ++++ b/pcap-snf.c +@@ -192,7 +192,8 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) + caplen = p->snapshot; + + if ((p->fcode.bf_insns == NULL) || +- pcap_filter(p->fcode.bf_insns, req.pkt_addr, req.length, caplen)) { ++ pcap_filter(p->fcode.bf_insns, p->fcode.bf_len, ++ req.pkt_addr, req.length, caplen)) { + hdr.ts = snf_timestamp_to_timeval(req.timestamp, p->opt.tstamp_precision); + hdr.caplen = caplen; + hdr.len = req.length; +diff --git a/pcap-usb-linux.c b/pcap-usb-linux.c +index 726e4a8a..44b2bf30 100644 +--- a/pcap-usb-linux.c ++++ b/pcap-usb-linux.c +@@ -735,8 +735,8 @@ usb_read_linux_bin(pcap_t *handle, int max_packets _U_, pcap_handler callback, u + pkth.ts.tv_usec = info.hdr->ts_usec; + + if (handle->fcode.bf_insns == NULL || +- pcap_filter(handle->fcode.bf_insns, handle->buffer, +- pkth.len, pkth.caplen)) { ++ pcap_filter(handle->fcode.bf_insns, handle->fcode.bf_len, ++ handle->buffer, pkth.len, pkth.caplen)) { + handlep->packets_read++; + callback(user, &pkth, handle->buffer); + return 1; +@@ -904,8 +904,8 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch + pkth.ts.tv_usec = hdr->ts_usec; + + if (handle->fcode.bf_insns == NULL || +- pcap_filter(handle->fcode.bf_insns, (u_char*) hdr, +- pkth.len, pkth.caplen)) { ++ pcap_filter(handle->fcode.bf_insns, handle->fcode.bf_len, ++ (u_char*) hdr, pkth.len, pkth.caplen)) { + handlep->packets_read++; + callback(user, &pkth, (u_char*) hdr); + packets++; +diff --git a/pcap.c b/pcap.c +index ef1bbb71..9ee83f98 100644 +--- a/pcap.c ++++ b/pcap.c +@@ -4179,7 +4179,7 @@ pcap_offline_filter(const struct bpf_program *fp, const struct pcap_pkthdr *h, + const struct bpf_insn *fcode = fp->bf_insns; + + if (fcode != NULL) +- return (pcap_filter(fcode, pkt, h->len, h->caplen)); ++ return (pcap_filter(fcode, fp->bf_len, pkt, h->len, h->caplen)); + else + return (0); + } +diff --git a/savefile.c b/savefile.c +index db8a3aa0..e9708b23 100644 +--- a/savefile.c ++++ b/savefile.c +@@ -687,7 +687,8 @@ pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) + * and, if it passes, process it. + */ + if ((fcode = p->fcode.bf_insns) == NULL || +- pcap_filter(fcode, data, h.len, h.caplen)) { ++ pcap_filter(fcode, p->fcode.bf_len, ++ data, h.len, h.caplen)) { + (*callback)(user, &h, data); + n++; /* count the packet */ + if (n >= cnt) diff --git a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb index 692fdf606c..323cca3d98 100644 --- a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb +++ b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb @@ -18,6 +18,7 @@ SRC_URI = "https://www.tcpdump.org/release/${BP}.tar.gz \ file://CVE-2025-11961-02.patch \ file://CVE-2025-11964.patch \ file://01-CVE-2026-0799.patch \ + file://02-CVE-2026-31912.patch \ " SRC_URI[sha256sum] = "ed19a0383fad72e3ad435fd239d7cd80d64916b87269550159d20e47160ebe5f" ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [scarthgap][PATCH 3/7] libpcap: Fix CVE-2026-31911 2026-09-15 19:45 [scarthgap][PATCH 0/7] libpcap: backport seven CVE fixes from 1.10.7 Jaipaul Cheernam 2026-09-15 19:45 ` [scarthgap][PATCH 1/7] libpcap: Fix CVE-2026-0799 Jaipaul Cheernam 2026-09-15 19:45 ` [scarthgap][PATCH 2/7] libpcap: Fix CVE-2026-31912 Jaipaul Cheernam @ 2026-09-15 19:45 ` Jaipaul Cheernam 2026-09-15 19:45 ` [scarthgap][PATCH 4/7] libpcap: Fix CVE-2026-6244 Jaipaul Cheernam ` (4 subsequent siblings) 7 siblings, 0 replies; 17+ messages in thread From: Jaipaul Cheernam @ 2026-09-15 19:45 UTC (permalink / raw) To: openembedded-core NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-31911 Upstream-commit: https://github.com/the-tcpdump-group/libpcap/commit/a715bcdde830299cba4171514385cb17ec19b6e9 Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> --- .../libpcap/libpcap/03-CVE-2026-31911.patch | 42 +++++++++++++++++++ .../libpcap/libpcap_1.10.4.bb | 1 + 2 files changed, 43 insertions(+) create mode 100644 meta/recipes-connectivity/libpcap/libpcap/03-CVE-2026-31911.patch diff --git a/meta/recipes-connectivity/libpcap/libpcap/03-CVE-2026-31911.patch b/meta/recipes-connectivity/libpcap/libpcap/03-CVE-2026-31911.patch new file mode 100644 index 0000000000..ccd470ef7e --- /dev/null +++ b/meta/recipes-connectivity/libpcap/libpcap/03-CVE-2026-31911.patch @@ -0,0 +1,42 @@ +From a715bcdde830299cba4171514385cb17ec19b6e9 Mon Sep 17 00:00:00 2001 +From: Denis Ovsienko <denis@ovsienko.info> +Date: Thu, 30 Jul 2026 13:34:08 +0100 +Subject: [PATCH] CVE-2026-31911: Fail opcodes safely in the BPF interpreter. + +This vulnerability has been discovered by FuzzAnything Organization. + +The current revision of pcapint_filter_with_aux_data() calls abort() if +the current instruction opcode is invalid, and assumes this never to be +the case. This holds for programs that have been generated by libpcap. + +However, this does not necessarily hold for programs that come from an +external source via pcap_offline_filter() or [deprecated] bpf_filter(). +Furthermore, this does not necessarily hold for programs that have been +validated by libpcap because the current revision of the validator has +gaps in the checks and accepts a number of invalid opcodes (another +commit addresses that). + +Thus in pcapint_filter_with_aux_data(), when the instruction opcode is +invalid, just reject the packet. + +(backported from commit 4ccb54bf4946d31a248ec93bdbeaabd97fb9d8f7) + +(cherry picked from commit a715bcdde830299cba4171514385cb17ec19b6e9) + +Upstream-Status: Backport [https://github.com/the-tcpdump-group/libpcap/commit/a715bcdde830299cba4171514385cb17ec19b6e9] +CVE: CVE-2026-31911 +Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> +--- +diff --git a/bpf_filter.c b/bpf_filter.c +index 2ea11d46..d6e4b019 100644 +--- a/bpf_filter.c ++++ b/bpf_filter.c +@@ -146,7 +146,7 @@ pcap_filter_with_aux_data(const struct bpf_insn *pc, const u_int proglen, + switch (pc->code) { + + default: +- abort(); ++ return 0; + case BPF_RET|BPF_K: + return (u_int)pc->k; + diff --git a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb index 323cca3d98..5b97c14e85 100644 --- a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb +++ b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb @@ -19,6 +19,7 @@ SRC_URI = "https://www.tcpdump.org/release/${BP}.tar.gz \ file://CVE-2025-11964.patch \ file://01-CVE-2026-0799.patch \ file://02-CVE-2026-31912.patch \ + file://03-CVE-2026-31911.patch \ " SRC_URI[sha256sum] = "ed19a0383fad72e3ad435fd239d7cd80d64916b87269550159d20e47160ebe5f" ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [scarthgap][PATCH 4/7] libpcap: Fix CVE-2026-6244 2026-09-15 19:45 [scarthgap][PATCH 0/7] libpcap: backport seven CVE fixes from 1.10.7 Jaipaul Cheernam ` (2 preceding siblings ...) 2026-09-15 19:45 ` [scarthgap][PATCH 3/7] libpcap: Fix CVE-2026-31911 Jaipaul Cheernam @ 2026-09-15 19:45 ` Jaipaul Cheernam 2026-09-15 19:45 ` [scarthgap][PATCH 5/7] libpcap: Fix CVE-2026-6554 Jaipaul Cheernam ` (3 subsequent siblings) 7 siblings, 0 replies; 17+ messages in thread From: Jaipaul Cheernam @ 2026-09-15 19:45 UTC (permalink / raw) To: openembedded-core NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-6244 Upstream-commit: https://github.com/the-tcpdump-group/libpcap/commit/98bb921b141aa642faedbf2ac510541c76499a19 Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> --- .../libpcap/libpcap/04-CVE-2026-6244.patch | 46 +++++++++++++++++++ .../libpcap/libpcap_1.10.4.bb | 1 + 2 files changed, 47 insertions(+) create mode 100644 meta/recipes-connectivity/libpcap/libpcap/04-CVE-2026-6244.patch diff --git a/meta/recipes-connectivity/libpcap/libpcap/04-CVE-2026-6244.patch b/meta/recipes-connectivity/libpcap/libpcap/04-CVE-2026-6244.patch new file mode 100644 index 0000000000..bb9ab04255 --- /dev/null +++ b/meta/recipes-connectivity/libpcap/libpcap/04-CVE-2026-6244.patch @@ -0,0 +1,46 @@ +From 98bb921b141aa642faedbf2ac510541c76499a19 Mon Sep 17 00:00:00 2001 +From: Denis Ovsienko <denis@ovsienko.info> +Date: Thu, 30 Jul 2026 13:34:21 +0100 +Subject: [PATCH] CVE-2026-6244: Avoid division by zero via pcap_offline_filter(). + +The current revision of pcapint_filter_with_aux_data() for "div x" and +"mod x" correctly rejects the packet if X is zero, but for "div #k" and +"mod #k" it assumes that k is never zero. This holds for programs that +have been generated or validated by libpcap. + +However, this does not necessarily hold for programs that come from an +external source via pcap_offline_filter() or [deprecated] bpf_filter() +and have not been explicitly validated. If the interpreter executes +such a program, it can attempt a division by zero, which will typically +terminate the process via SIGFPE. + +To fix this problem, in pcapint_filter_with_aux_data() treat "div #k" +and "mod #k" the same way as "div x" and "mod x". + +(backported from commit 0b2b1ad4a1796513613ff68e9dc09049cc8e0af4) + +(cherry picked from commit 98bb921b141aa642faedbf2ac510541c76499a19) + +Upstream-Status: Backport [https://github.com/the-tcpdump-group/libpcap/commit/98bb921b141aa642faedbf2ac510541c76499a19] +CVE: CVE-2026-6244 +Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> +--- +diff --git a/bpf_filter.c b/bpf_filter.c +index 497b1586..df92c433 100644 +--- a/bpf_filter.c ++++ b/bpf_filter.c +@@ -422,10 +422,14 @@ DIAG_ON_DEFAULT_ONLY_SWITCH + continue; + + case BPF_ALU|BPF_DIV|BPF_K: ++ if (pc->k == 0) ++ return 0; + A /= pc->k; + continue; + + case BPF_ALU|BPF_MOD|BPF_K: ++ if (pc->k == 0) ++ return 0; + A %= pc->k; + continue; + diff --git a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb index 5b97c14e85..d23a018a95 100644 --- a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb +++ b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb @@ -20,6 +20,7 @@ SRC_URI = "https://www.tcpdump.org/release/${BP}.tar.gz \ file://01-CVE-2026-0799.patch \ file://02-CVE-2026-31912.patch \ file://03-CVE-2026-31911.patch \ + file://04-CVE-2026-6244.patch \ " SRC_URI[sha256sum] = "ed19a0383fad72e3ad435fd239d7cd80d64916b87269550159d20e47160ebe5f" ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [scarthgap][PATCH 5/7] libpcap: Fix CVE-2026-6554 2026-09-15 19:45 [scarthgap][PATCH 0/7] libpcap: backport seven CVE fixes from 1.10.7 Jaipaul Cheernam ` (3 preceding siblings ...) 2026-09-15 19:45 ` [scarthgap][PATCH 4/7] libpcap: Fix CVE-2026-6244 Jaipaul Cheernam @ 2026-09-15 19:45 ` Jaipaul Cheernam 2026-09-15 19:45 ` [scarthgap][PATCH 6/7] libpcap: Fix CVE-2026-18313 Jaipaul Cheernam ` (2 subsequent siblings) 7 siblings, 0 replies; 17+ messages in thread From: Jaipaul Cheernam @ 2026-09-15 19:45 UTC (permalink / raw) To: openembedded-core NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-6554 Upstream-commit: https://github.com/the-tcpdump-group/libpcap/commit/ff3c83475ac303c6b681c52ad0b6e14795a8e0ce Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> --- .../libpcap/libpcap/05-CVE-2026-6554.patch | 87 +++++++++++++++++++ .../libpcap/libpcap_1.10.4.bb | 1 + 2 files changed, 88 insertions(+) create mode 100644 meta/recipes-connectivity/libpcap/libpcap/05-CVE-2026-6554.patch diff --git a/meta/recipes-connectivity/libpcap/libpcap/05-CVE-2026-6554.patch b/meta/recipes-connectivity/libpcap/libpcap/05-CVE-2026-6554.patch new file mode 100644 index 0000000000..539aa7c446 --- /dev/null +++ b/meta/recipes-connectivity/libpcap/libpcap/05-CVE-2026-6554.patch @@ -0,0 +1,87 @@ +From ff3c83475ac303c6b681c52ad0b6e14795a8e0ce Mon Sep 17 00:00:00 2001 +From: Denis Ovsienko <denis@ovsienko.info> +Date: Thu, 30 Jul 2026 13:34:33 +0100 +Subject: [PATCH] CVE-2026-6554: Limit "ja L" looping in pcap_offline_filter(). + +This vulnerability has been discovered by Kaixuan LI. + +The current revision of pcapint_filter_with_aux_data() assumes that any +"ja L" instruction in a filter program does not jump to itself or to a +prior instruction that is guaranteed to reach the same "ja L" again. +This holds for programs that have been generated by libpcap. + +However, this does not necessarily hold for programs that come from an +external source via pcap_offline_filter() or [deprecated] bpf_filter(). +If the interpreter executes such a program, upon reaching such an +instruction it will begin looping infinitely. + +To mitigate this problem, in pcapint_filter_with_aux_data() enforce a +hard-coded limit on the number of backward jumps per packet. Ibid., and +in pcapint_validate_filter() as well, reject the only immediately +detectable case of an infinite loop. + +(backported from commit 63c005c25aeabf1404968add49fc885da3e127e0) + +(cherry picked from commit ff3c83475ac303c6b681c52ad0b6e14795a8e0ce) + +Upstream-Status: Backport [https://github.com/the-tcpdump-group/libpcap/commit/ff3c83475ac303c6b681c52ad0b6e14795a8e0ce] +CVE: CVE-2026-6554 +Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> +--- +diff --git a/bpf_filter.c b/bpf_filter.c +index df92c433..ae8a3a36 100644 +--- a/bpf_filter.c ++++ b/bpf_filter.c +@@ -72,6 +72,8 @@ enum { + BPF_S_ANC_VLAN_TAG_PRESENT, + }; + ++#define MAX_BACKWARD_JUMPS 64U ++ + /* + * Kernel BPF implementations tend to define BPF_MAXINSNS to 512 or 4096, the + * userland interpreter in libpcap is meant to support much longer filter +@@ -146,6 +148,7 @@ pcap_filter_with_aux_data(const struct bpf_insn *pc, const u_int proglen, + A = 0; + X = 0; + const struct bpf_insn *pc0 = pc; ++ unsigned backward_jumps = 0; + --pc; + for (;;) { + ++pc; +@@ -320,6 +323,17 @@ DIAG_ON_DEFAULT_ONLY_SWITCH + */ + if ((bpf_u_int32)(pc - pc0) + 1 + pc->k >= proglen) + return 0; ++ /* ++ * Terminate the program if this is a non-forward jump ++ * and is: ++ * - a guaranteed infinite loop because it jumps to ++ * itself (exactly the same as in the validator), or ++ * - a backward jump after many enough backward jumps ++ * already made for this packet. ++ */ ++ if ((bpf_int32)pc->k < 0 && ((bpf_int32)pc->k == -1 || ++ backward_jumps++ >= MAX_BACKWARD_JUMPS)) ++ return 0; + /* + * XXX - we currently implement "ip6 protochain" + * with backward jumps, so sign-extend pc->k. +@@ -607,6 +621,17 @@ pcap_validate_filter(const struct bpf_insn *f, int len) + */ + if (from + p->k >= (u_int)len) + return 0; ++ /* ++ * The only type of infinite loop that can be ++ * detected in this function is a "ja L" that ++ * jumps to itself. For this only k == -1 ++ * needs to be tested because the check above ++ * has already rejected all other values that ++ * would wrap the pointer equivalently on ++ * 32-bit architectures. ++ */ ++ if ((bpf_int32)p->k == -1) ++ return 0; + break; + case BPF_JEQ: + case BPF_JGT: diff --git a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb index d23a018a95..f7ba1bf3ea 100644 --- a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb +++ b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb @@ -21,6 +21,7 @@ SRC_URI = "https://www.tcpdump.org/release/${BP}.tar.gz \ file://02-CVE-2026-31912.patch \ file://03-CVE-2026-31911.patch \ file://04-CVE-2026-6244.patch \ + file://05-CVE-2026-6554.patch \ " SRC_URI[sha256sum] = "ed19a0383fad72e3ad435fd239d7cd80d64916b87269550159d20e47160ebe5f" ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [scarthgap][PATCH 6/7] libpcap: Fix CVE-2026-18313 2026-09-15 19:45 [scarthgap][PATCH 0/7] libpcap: backport seven CVE fixes from 1.10.7 Jaipaul Cheernam ` (4 preceding siblings ...) 2026-09-15 19:45 ` [scarthgap][PATCH 5/7] libpcap: Fix CVE-2026-6554 Jaipaul Cheernam @ 2026-09-15 19:45 ` Jaipaul Cheernam 2026-09-15 19:45 ` [scarthgap][PATCH 7/7] libpcap: Fix CVE-2026-18238 Jaipaul Cheernam 2026-09-21 20:17 ` [scarthgap][PATCH v2 0/7] libpcap: backport seven CVE fixes from 1.10.7 Jaipaul Cheernam 7 siblings, 0 replies; 17+ messages in thread From: Jaipaul Cheernam @ 2026-09-15 19:45 UTC (permalink / raw) To: openembedded-core NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-18313 Upstream-commit: https://github.com/the-tcpdump-group/libpcap/commit/f9775af1a0ec76db60c7213241e6b48f1be10ac7 Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> --- .../libpcap/libpcap/06-CVE-2026-18313.patch | 81 +++++++++++++++++++ .../libpcap/libpcap_1.10.4.bb | 1 + 2 files changed, 82 insertions(+) create mode 100644 meta/recipes-connectivity/libpcap/libpcap/06-CVE-2026-18313.patch diff --git a/meta/recipes-connectivity/libpcap/libpcap/06-CVE-2026-18313.patch b/meta/recipes-connectivity/libpcap/libpcap/06-CVE-2026-18313.patch new file mode 100644 index 0000000000..a2f2a5fd4e --- /dev/null +++ b/meta/recipes-connectivity/libpcap/libpcap/06-CVE-2026-18313.patch @@ -0,0 +1,81 @@ +From f9775af1a0ec76db60c7213241e6b48f1be10ac7 Mon Sep 17 00:00:00 2001 +From: Denis Ovsienko <denis@ovsienko.info> +Date: Sat, 1 Aug 2026 18:24:48 +0100 +Subject: [PATCH] CVE-2026-18313: Fix a memory leak in rpcapd. + +This vulnerability was originally reported publicly, hence no credit is +given. + +daemon_unpackapplyfilter() can allocate a temporary buffer for up to +RPCAP_BPF_MAXINSNS (8192) BPF instructions (65536 bytes) per each +received RPCAP_MSG_UPDATEFILTER_REQ or RPCAP_MSG_STARTCAP_REQ message. +It never frees the memory, so repeated messages from a client will +eventually leak enough memory on the server to cause problems. This +holds for all connections that pass the validation and some connections +that do not. + +48 bytes in 1 blocks are definitely lost in loss record 2 of 2 + at 0x4844818: malloc (vg_replace_malloc.c:446) + by 0x111AAB: daemon_unpackapplyfilter (daemon.c:2372) + by 0x113279: daemon_msg_startcap_req.constprop.0 (daemon.c:2139) + by 0x114808: daemon_serviceloop (daemon.c:901) + by 0x115BC7: accept_connection (rpcapd.c:1321) + by 0x115BC7: accept_connections (rpcapd.c:1118) + by 0x115BC7: main_startup (rpcapd.c:709) + by 0x1112BD: main (rpcapd.c:567) + +To fix this, after a successful malloc() return exactly once, after the +free() call. + +(backported from commit 26a1c75702b105ac8788014f35f1b5c57fa6043b) + +(cherry picked from commit f9775af1a0ec76db60c7213241e6b48f1be10ac7) + +Upstream-Status: Backport [https://github.com/the-tcpdump-group/libpcap/commit/f9775af1a0ec76db60c7213241e6b48f1be10ac7] +CVE: CVE-2026-18313 +Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> +--- +diff --git a/rpcapd/daemon.c b/rpcapd/daemon.c +index 9b0f8285..b0268688 100644 +--- a/rpcapd/daemon.c ++++ b/rpcapd/daemon.c +@@ -2378,14 +2378,8 @@ daemon_unpackapplyfilter(SOCKET sockctrl, SSL *ctrl_ssl, struct session *session + { + status = rpcapd_recv(sockctrl, ctrl_ssl, (char *) &insn, + sizeof(struct rpcap_filterbpf_insn), plenp, errmsgbuf); +- if (status == -1) +- { +- return -1; +- } +- if (status == -2) +- { +- return -2; +- } ++ if (status == -1 || status == -2) ++ goto free_and_return_status; + + bf_insn->code = ntohs(insn.code); + bf_insn->jf = insn.jf; +@@ -2401,16 +2395,19 @@ daemon_unpackapplyfilter(SOCKET sockctrl, SSL *ctrl_ssl, struct session *session + if (bpf_validate(bf_prog.bf_insns, bf_prog.bf_len) == 0) + { + snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "The filter contains bogus instructions"); +- return -2; ++ status = -2; ++ goto free_and_return_status; + } + + if (pcap_setfilter(session->fp, &bf_prog)) + { + snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "RPCAP error: %s", pcap_geterr(session->fp)); +- return -2; ++ status = -2; + } + +- return 0; ++free_and_return_status: ++ free(bf_prog.bf_insns); ++ return status; + } + + static int diff --git a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb index f7ba1bf3ea..5f1506f8fc 100644 --- a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb +++ b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb @@ -22,6 +22,7 @@ SRC_URI = "https://www.tcpdump.org/release/${BP}.tar.gz \ file://03-CVE-2026-31911.patch \ file://04-CVE-2026-6244.patch \ file://05-CVE-2026-6554.patch \ + file://06-CVE-2026-18313.patch \ " SRC_URI[sha256sum] = "ed19a0383fad72e3ad435fd239d7cd80d64916b87269550159d20e47160ebe5f" ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [scarthgap][PATCH 7/7] libpcap: Fix CVE-2026-18238 2026-09-15 19:45 [scarthgap][PATCH 0/7] libpcap: backport seven CVE fixes from 1.10.7 Jaipaul Cheernam ` (5 preceding siblings ...) 2026-09-15 19:45 ` [scarthgap][PATCH 6/7] libpcap: Fix CVE-2026-18313 Jaipaul Cheernam @ 2026-09-15 19:45 ` Jaipaul Cheernam 2026-09-21 20:17 ` [scarthgap][PATCH v2 0/7] libpcap: backport seven CVE fixes from 1.10.7 Jaipaul Cheernam 7 siblings, 0 replies; 17+ messages in thread From: Jaipaul Cheernam @ 2026-09-15 19:45 UTC (permalink / raw) To: openembedded-core 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 | 219 ++++++++++++++++++ .../libpcap/libpcap_1.10.4.bb | 1 + 2 files changed, 220 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..c981fa8ff1 --- /dev/null +++ b/meta/recipes-connectivity/libpcap/libpcap/07-CVE-2026-18238.patch @@ -0,0 +1,219 @@ +From b9590d482986d64673712460aae1d48d11fa0473 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> +--- +diff --git a/pcap-rpcap.c b/pcap-rpcap.c +index 22fc7363..30fbd6d6 100644 +--- a/pcap-rpcap.c ++++ b/pcap-rpcap.c +@@ -388,10 +388,9 @@ rpcap_deseraddr(struct rpcap_sockaddr *sockaddrin, struct sockaddr_storage **soc + 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; + +@@ -448,13 +447,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 */ +@@ -470,6 +491,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)) + { + /* +@@ -479,8 +502,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 +@@ -495,6 +528,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)) + { + /* +@@ -514,27 +548,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. */ +@@ -557,27 +599,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.4.bb b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb index 5f1506f8fc..3892454a40 100644 --- a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb +++ b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb @@ -23,6 +23,7 @@ SRC_URI = "https://www.tcpdump.org/release/${BP}.tar.gz \ 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] = "ed19a0383fad72e3ad435fd239d7cd80d64916b87269550159d20e47160ebe5f" ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [scarthgap][PATCH v2 0/7] libpcap: backport seven CVE fixes from 1.10.7 2026-09-15 19:45 [scarthgap][PATCH 0/7] libpcap: backport seven CVE fixes from 1.10.7 Jaipaul Cheernam ` (6 preceding siblings ...) 2026-09-15 19:45 ` [scarthgap][PATCH 7/7] libpcap: Fix CVE-2026-18238 Jaipaul Cheernam @ 2026-09-21 20:17 ` Jaipaul Cheernam 2026-09-21 20:17 ` [scarthgap][PATCH v2 1/7] libpcap: Fix CVE-2026-0799 Jaipaul Cheernam ` (6 more replies) 7 siblings, 7 replies; 17+ messages in thread From: Jaipaul Cheernam @ 2026-09-21 20:17 UTC (permalink / raw) To: openembedded-core This series backports the seven security fixes that were released in libpcap 1.10.7 to the 1.10.4 recipe. The same set of fixes has already been addressed on master by upgrading libpcap to 1.10.7. CVEs addressed (see the upstream 1.10.7 CHANGES): CVE-2026-0799 - Access M[] safely in the BPF interpreter. CVE-2026-31912 - Mind the program bounds in pcap_offline_filter(). CVE-2026-31911 - Fail opcodes safely in the BPF interpreter. 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. Each CVE is a separate file:// patch, ordered so they apply on top of each other. Where a fix touches the BPF filter interpreter it is adapted to the 1.10.4 pcap_filter*() names (renamed to pcapint_*() after 1.10.4). Verified by applying all seven patches in order onto a pristine libpcap 1.10.4 tree and building successfully, including with --enable-remote (rpcapd). Changes since v1: - 0003 (CVE-2026-31911): dropped the inaccurate "Adapted to the 1.10.4" Jaipaul Cheernam (7): libpcap: Fix CVE-2026-0799 libpcap: Fix CVE-2026-31912 libpcap: Fix CVE-2026-31911 libpcap: Fix CVE-2026-6244 libpcap: Fix CVE-2026-6554 libpcap: Fix CVE-2026-18313 libpcap: Fix CVE-2026-18238 .../libpcap/libpcap/01-CVE-2026-0799.patch | 67 +++ .../libpcap/libpcap/02-CVE-2026-31912.patch | 525 ++++++++++++++++++ .../libpcap/libpcap/03-CVE-2026-31911.patch | 45 ++ .../libpcap/libpcap/04-CVE-2026-6244.patch | 49 ++ .../libpcap/libpcap/05-CVE-2026-6554.patch | 92 +++ .../libpcap/libpcap/06-CVE-2026-18313.patch | 84 +++ .../libpcap/libpcap/07-CVE-2026-18238.patch | 222 ++++++++ .../libpcap/libpcap_1.10.4.bb | 7 + 8 files changed, 1091 insertions(+) create mode 100644 meta/recipes-connectivity/libpcap/libpcap/01-CVE-2026-0799.patch create mode 100644 meta/recipes-connectivity/libpcap/libpcap/02-CVE-2026-31912.patch create mode 100644 meta/recipes-connectivity/libpcap/libpcap/03-CVE-2026-31911.patch create mode 100644 meta/recipes-connectivity/libpcap/libpcap/04-CVE-2026-6244.patch create mode 100644 meta/recipes-connectivity/libpcap/libpcap/05-CVE-2026-6554.patch create mode 100644 meta/recipes-connectivity/libpcap/libpcap/06-CVE-2026-18313.patch create mode 100644 meta/recipes-connectivity/libpcap/libpcap/07-CVE-2026-18238.patch ^ permalink raw reply [flat|nested] 17+ messages in thread
* [scarthgap][PATCH v2 1/7] libpcap: Fix CVE-2026-0799 2026-09-21 20:17 ` [scarthgap][PATCH v2 0/7] libpcap: backport seven CVE fixes from 1.10.7 Jaipaul Cheernam @ 2026-09-21 20:17 ` Jaipaul Cheernam 2026-09-21 20:17 ` [scarthgap][PATCH v2 2/7] libpcap: Fix CVE-2026-31912 Jaipaul Cheernam ` (5 subsequent siblings) 6 siblings, 0 replies; 17+ messages in thread From: Jaipaul Cheernam @ 2026-09-21 20:17 UTC (permalink / raw) To: openembedded-core NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-0799 Upstream-commit: https://github.com/the-tcpdump-group/libpcap/commit/48e8960a7108e9e828f9d7bdc7e97bdab841aec7 Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> --- .../libpcap/libpcap/01-CVE-2026-0799.patch | 67 +++++++++++++++++++ .../libpcap/libpcap_1.10.4.bb | 1 + 2 files changed, 68 insertions(+) create mode 100644 meta/recipes-connectivity/libpcap/libpcap/01-CVE-2026-0799.patch diff --git a/meta/recipes-connectivity/libpcap/libpcap/01-CVE-2026-0799.patch b/meta/recipes-connectivity/libpcap/libpcap/01-CVE-2026-0799.patch new file mode 100644 index 0000000000..a4dfea4236 --- /dev/null +++ b/meta/recipes-connectivity/libpcap/libpcap/01-CVE-2026-0799.patch @@ -0,0 +1,67 @@ +From 48e8960a7108e9e828f9d7bdc7e97bdab841aec7 Mon Sep 17 00:00:00 2001 +From: Denis Ovsienko <denis@ovsienko.info> +Date: Thu, 30 Jul 2026 13:33:41 +0100 +Subject: [PATCH] CVE-2026-0799: Access M[] safely in the BPF interpreter. + +Include Security identified and reported this problem as a potential +vulnerability in 2018 (case reference "I7"). Their work was sponsored +by Mozilla under the Secure Open Source program. The vulnerability has +been independently confirmed only recently. + +The current revision of pcapint_filter_with_aux_data() can, but does not +check whether a scratch memory register index is valid in the "ld M[k]", +"ldx M[k]", "st M[k]" and "stx M[k]" BPF instructions, and assumes this +is always the case. This holds for programs that have been generated or +validated by libpcap. + +However, this does not necessarily hold for programs that come via +pcap_offline_filter() or [deprecated] bpf_filter() from an external +source and have not been explicitly validated. If the interpreter +executes such a program with an invalid index, it will read/write the +process memory at arbitrary locations starting at the current stack +frame. Depending on the address, the memory layout and the OS, this can +result in stack buffer overflow, SIGSEGV, SIGBUS or other effects. To +fix this, in the interpreter reject the packet if the index is invalid. + +(backported from commit 569f8fd3524192acbabf93c9cd704471bb38f84a) + +(cherry picked from commit 48e8960a7108e9e828f9d7bdc7e97bdab841aec7) + +Notes on backporting to 1.10.4: + - The upstream CHANGES/changelog hunk is not backported. + +Upstream-Status: Backport [https://github.com/the-tcpdump-group/libpcap/commit/48e8960a7108e9e828f9d7bdc7e97bdab841aec7] +CVE: CVE-2026-0799 +Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> +--- +diff --git a/bpf_filter.c b/bpf_filter.c +index 8691d0d1..fa82d1d0 100644 +--- a/bpf_filter.c ++++ b/bpf_filter.c +@@ -219,18 +219,26 @@ DIAG_ON_DEFAULT_ONLY_SWITCH + continue; + + case BPF_LD|BPF_MEM: ++ if (pc->k >= BPF_MEMWORDS) ++ return 0; + A = mem[pc->k]; + continue; + + case BPF_LDX|BPF_MEM: ++ if (pc->k >= BPF_MEMWORDS) ++ return 0; + X = mem[pc->k]; + continue; + + case BPF_ST: ++ if (pc->k >= BPF_MEMWORDS) ++ return 0; + mem[pc->k] = A; + continue; + + case BPF_STX: ++ if (pc->k >= BPF_MEMWORDS) ++ return 0; + mem[pc->k] = X; + continue; + diff --git a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb index ee7d7540f6..692fdf606c 100644 --- a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb +++ b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb @@ -17,6 +17,7 @@ SRC_URI = "https://www.tcpdump.org/release/${BP}.tar.gz \ file://CVE-2025-11961-01.patch \ file://CVE-2025-11961-02.patch \ file://CVE-2025-11964.patch \ + file://01-CVE-2026-0799.patch \ " SRC_URI[sha256sum] = "ed19a0383fad72e3ad435fd239d7cd80d64916b87269550159d20e47160ebe5f" ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [scarthgap][PATCH v2 2/7] libpcap: Fix CVE-2026-31912 2026-09-21 20:17 ` [scarthgap][PATCH v2 0/7] libpcap: backport seven CVE fixes from 1.10.7 Jaipaul Cheernam 2026-09-21 20:17 ` [scarthgap][PATCH v2 1/7] libpcap: Fix CVE-2026-0799 Jaipaul Cheernam @ 2026-09-21 20:17 ` Jaipaul Cheernam 2026-10-02 8:30 ` [OE-core] " Yoann Congal 2026-09-21 20:17 ` [scarthgap][PATCH v2 3/7] libpcap: Fix CVE-2026-31911 Jaipaul Cheernam ` (4 subsequent siblings) 6 siblings, 1 reply; 17+ messages in thread From: Jaipaul Cheernam @ 2026-09-21 20:17 UTC (permalink / raw) To: openembedded-core NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-31912 Upstream-commit: https://github.com/the-tcpdump-group/libpcap/commit/d3f358d3cffbe1ecb94d5284b3e81f052a0adcb9 Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> --- .../libpcap/libpcap/02-CVE-2026-31912.patch | 525 ++++++++++++++++++ .../libpcap/libpcap_1.10.4.bb | 1 + 2 files changed, 526 insertions(+) create mode 100644 meta/recipes-connectivity/libpcap/libpcap/02-CVE-2026-31912.patch diff --git a/meta/recipes-connectivity/libpcap/libpcap/02-CVE-2026-31912.patch b/meta/recipes-connectivity/libpcap/libpcap/02-CVE-2026-31912.patch new file mode 100644 index 0000000000..d9fda1ec48 --- /dev/null +++ b/meta/recipes-connectivity/libpcap/libpcap/02-CVE-2026-31912.patch @@ -0,0 +1,525 @@ +From d3f358d3cffbe1ecb94d5284b3e81f052a0adcb9 Mon Sep 17 00:00:00 2001 +From: Denis Ovsienko <denis@ovsienko.info> +Date: Thu, 30 Jul 2026 13:33:55 +0100 +Subject: [PATCH] CVE-2026-31912: Mind the program bounds in pcap_offline_filter(). + +The current revision of pcapint_filter_with_aux_data() does not know the +number of instructions in the filter program, it assumes the program +counter always remains within the bounds of the provided filter program +and always reaches a return instruction. This holds for programs that +have been generated or validated by libpcap. + +However, this does not necessarily hold for programs that come from an +external source via pcap_offline_filter() or [deprecated] bpf_filter() +and have not been explicitly validated. If the interpreter executes +such a program and advances the program counter beyond the last +instruction, it will be interpreting memory space after the filter +program as BPF instructions, which in the current implementation will +eventually cause either abort() (another commit addresses that) or +SIGSEGV. + +To fix the latter problem, in pcapint_filter_with_aux_data() add a +parameter for the number of instructions in the program and reject the +packet as soon as (or just before) the program counter goes out of +bounds. Update all incoming code paths to specify the length; also in +pcap_offline_filter(3PCAP) make it clear the function now requires the +'bf_len' member to be set correctly and uses it. + +(backported from commit d1209988c74dd9330659898d3b676ee6bbe1c551) + +(cherry picked from commit d3f358d3cffbe1ecb94d5284b3e81f052a0adcb9) + +Notes on backporting to 1.10.4: + - Adapted to the 1.10.4 pcap_filter*() names (renamed to pcapint_*() + after 1.10.4). + - The upstream CHANGES/changelog hunk is not backported. + +Upstream-Status: Backport [https://github.com/the-tcpdump-group/libpcap/commit/d3f358d3cffbe1ecb94d5284b3e81f052a0adcb9] +CVE: CVE-2026-31912 +Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> +--- +diff --git a/bpf_filter.c b/bpf_filter.c +index fa82d1d0..dec336ea 100644 +--- a/bpf_filter.c ++++ b/bpf_filter.c +@@ -72,6 +72,24 @@ enum { + BPF_S_ANC_VLAN_TAG_PRESENT, + }; + ++/* ++ * Kernel BPF implementations tend to define BPF_MAXINSNS to 512 or 4096, the ++ * userland interpreter in libpcap is meant to support much longer filter ++ * programs. In the latter case it is important that BPF_MAXINSNS does not ++ * interfere with the safety checks in the validator and the interpreter: ++ * (BPF_MAXINSNS + UINT8_MAX) * sizeof(struct bpf_insn) < UINT32_MAX ++ * It makes the most sense to be able to interpret as many instructions as ++ * pcap_compile() can produce, without optimization, for a valid filter ++ * expression before it consumes as much memory as the current definitions of ++ * NCHUNKS and CHUNKSIZE() allow. For some expressions this can be almost ++ * 1.53 million instructions on a 64-bit machine and twice as many on a 32-bit ++ * machine. ++ */ ++#ifdef BPF_MAXINSNS ++#undef BPF_MAXINSNS ++#endif ++#define BPF_MAXINSNS 3060000U ++ + /* + * Execute the filter program starting at pc on the packet p + * wirelen is the length of the original packet +@@ -86,12 +104,14 @@ enum { + */ + #if defined(SKF_AD_VLAN_TAG_PRESENT) + u_int +-pcap_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p, +- u_int wirelen, u_int buflen, const struct pcap_bpf_aux_data *aux_data) ++pcap_filter_with_aux_data(const struct bpf_insn *pc, const u_int proglen, ++ const u_char *p, const u_int wirelen, const u_int buflen, ++ const struct pcap_bpf_aux_data *aux_data) + #else + u_int +-pcap_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p, +- u_int wirelen, u_int buflen, const struct pcap_bpf_aux_data *aux_data _U_) ++pcap_filter_with_aux_data(const struct bpf_insn *pc, const u_int proglen, ++ const u_char *p, const u_int wirelen, const u_int buflen, ++ const struct pcap_bpf_aux_data *aux_data _U_) + #endif + { + register uint32_t A, X; +@@ -101,13 +121,36 @@ pcap_filter_with_aux_data(const struct bpf_insn *pc, const u_char *p, + if (pc == 0) + /* + * No filter means accept all. ++ * In this case the value of 'proglen' is irrelevant. + */ + return (u_int)-1; ++ if (proglen < 1 || proglen > BPF_MAXINSNS) ++ return 0; ++ ++ /* ++ * Require the current instruction pointer not to overflow for both the ++ * filter program (where the pointer will be dereferenced) and an ++ * immediately following margin (where it will be not). So long as the ++ * margin is large enough to represent the destination of any single ++ * conditional [forward] jump from within the filter program, a single ++ * guard prevents all filter program over-read attempts that result ++ * from the program running out of instructions before a BPF_RET or a ++ * conditional jump directing the interpreter beyond the program end. ++ * Unconditional jumps mean a larger problem space, which the BPF_JA ++ * case below addresses separately. ++ */ ++ const struct bpf_insn *pcend = pc + proglen; ++ if (pcend + UINT8_MAX < pc) ++ return 0; ++ + A = 0; + X = 0; ++ const struct bpf_insn *pc0 = pc; + --pc; + for (;;) { + ++pc; ++ if (pc >= pcend) ++ return 0; + switch (pc->code) { + + default: +@@ -243,6 +286,40 @@ DIAG_ON_DEFAULT_ONLY_SWITCH + continue; + + case BPF_JMP|BPF_JA: ++ /* ++ * The pointer (pc) decrements and increments in units ++ * of sizeof(struct bpf_insn) == 8 bytes. The number ++ * of units is in the [INT32_MIN, INT32_MAX] interval, ++ * hence the result can point before the beginning or ++ * beyond the end of the filter program and can under- ++ * or overflow; also on 32-bit architectures it can ++ * under- or overflow more than once and can test ++ * negative for underflow, overflow and out-of-range ++ * conditions after under- or overflowing at least ++ * once. ++ * ++ * However, it has been verified above that the program ++ * length is sufficiently small and the pointer does ++ * not wrap within the bounds of the filter program, so ++ * there is a one-to-one correspondence between BPF ++ * program counter values [0, proglen) and all valid ++ * values of the pointer. In other words, after this ++ * unconditional jump the pointer arithmetic result ++ * will be valid iff BPF program counter value will be ++ * valid. For the latter problem the solution is ++ * almost the same as in the validator. ++ * ++ * The main difference is that here the current value ++ * of BPF program counter is not a 32-bit unsigned ++ * variable, but a ptrdiff_t expression, which is ++ * 64-bit signed on 64-bit architectures and 32-bit ++ * signed on 32-bit architectures. However, the cast ++ * to 32-bit unsigned is safe in both cases because: ++ * pc0 <= pc < pc0 + proglen, therefore: ++ * 0 <= pc - pc0 < proglen <= BPF_MAXINSNS < INT32_MAX ++ */ ++ if ((bpf_u_int32)(pc - pc0) + 1 + pc->k >= proglen) ++ return 0; + /* + * XXX - we currently implement "ip6 protochain" + * with backward jumps, so sign-extend pc->k. +@@ -396,10 +473,10 @@ DIAG_ON_DEFAULT_ONLY_SWITCH + } + + u_int +-pcap_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen, +- u_int buflen) ++pcap_filter(const struct bpf_insn *pc, const u_int proglen, const u_char *p, ++ u_int wirelen, u_int buflen) + { +- return pcap_filter_with_aux_data(pc, p, wirelen, buflen, NULL); ++ return pcap_filter_with_aux_data(pc, proglen, p, wirelen, buflen, NULL); + } + + /* +@@ -419,7 +496,7 @@ pcap_validate_filter(const struct bpf_insn *f, int len) + u_int i, from; + const struct bpf_insn *p; + +- if (len < 1) ++ if (len < 1 || (u_int)len > BPF_MAXINSNS || f + len < f) + return 0; + + for (i = 0; i < (u_int)len; ++i) { +@@ -485,33 +562,45 @@ pcap_validate_filter(const struct bpf_insn *f, int len) + case BPF_JMP: + /* + * Check that jumps are within the code block, +- * and that unconditional branches don't go +- * backwards as a result of an overflow. ++ * regardless of the direction. libpcap uses ++ * backward jumps to implement the "protochain" ++ * primitive. All offsets that mean a backward ++ * jump in libpcap (whether in-range or not) in ++ * kernel BPF implementations mean out-of-range ++ * or overflow forward jumps -- kernel ++ * implementations must reject that. ++ * + * Unconditional branches have a 32-bit offset, + * so they could overflow; we check to make + * sure they don't. Conditional branches have + * an 8-bit offset, and the from address is <= +- * BPF_MAXINSNS, and we assume that BPF_MAXINSNS ++ * BPF_MAXINSNS, and we know that BPF_MAXINSNS + * is sufficiently small that adding 255 to it + * won't overflow. + * + * We know that len is <= BPF_MAXINSNS, and we +- * assume that BPF_MAXINSNS is < the maximum size ++ * know that BPF_MAXINSNS is < the maximum value + * of a u_int, so that i + 1 doesn't overflow. +- * +- * For userland, we don't know that the from +- * or len are <= BPF_MAXINSNS, but we know that +- * from <= len, and, except on a 64-bit system, +- * it's unlikely that len, if it truly reflects +- * the size of the program we've been handed, +- * will be anywhere near the maximum size of +- * a u_int. We also don't check for backward +- * branches, as we currently support them in +- * userland for the protochain operation. + */ + from = i + 1; + switch (BPF_OP(p->code)) { + case BPF_JA: ++ /* ++ * So long as both 'from' and bpf_insn.k are ++ * 32-bit unsigned, this check rejects any jump ++ * offset that points outside of the valid BPF ++ * address space of the filter program no ++ * matter whether signed interpretation of the ++ * offset is positive or negative. ++ * ++ * Note that this condition is necessary, but ++ * not sufficient to get correct results from ++ * respective pointer arithmetic in the process ++ * address space. Other necessary conditions ++ * are that BPF_MAXINSNS is correctly defined ++ * and enforced, and that the pointer does not ++ * overflow. ++ */ + if (from + p->k >= (u_int)len) + return 0; + break; +@@ -539,12 +628,14 @@ pcap_validate_filter(const struct bpf_insn *f, int len) + + /* + * Exported because older versions of libpcap exported them. ++ * This function is deprecated and unsafe, use pcap_offline_filter() instead. + */ + u_int + bpf_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen, + u_int buflen) + { +- return pcap_filter(pc, p, wirelen, buflen); ++ // The actual length of the filter program is not known. ++ return pcap_filter(pc, BPF_MAXINSNS, p, wirelen, buflen); + } + + int +diff --git a/dlpisubs.c b/dlpisubs.c +index 6815b0ec..790acf28 100644 +--- a/dlpisubs.c ++++ b/dlpisubs.c +@@ -195,7 +195,8 @@ pcap_process_pkts(pcap_t *p, pcap_handler callback, u_char *user, + bufp += caplen; + #endif + ++pd->stat.ps_recv; +- if (pcap_filter(p->fcode.bf_insns, pk, origlen, caplen)) { ++ if (pcap_filter(p->fcode.bf_insns, p->fcode.bf_len, ++ pk, origlen, caplen)) { + #ifdef HAVE_SYS_BUFMOD_H + pkthdr.ts.tv_sec = sbp->sbh_timestamp.tv_sec; + pkthdr.ts.tv_usec = sbp->sbh_timestamp.tv_usec; +diff --git a/pcap-bpf.c b/pcap-bpf.c +index 2898e598..04b5620d 100644 +--- a/pcap-bpf.c ++++ b/pcap-bpf.c +@@ -1255,7 +1255,8 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) + #endif + */ + if (pb->filtering_in_kernel || +- pcap_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) { ++ pcap_filter(p->fcode.bf_insns, p->fcode.bf_len, ++ datap, bhp->bh_datalen, caplen)) { + struct pcap_pkthdr pkthdr; + #ifdef BIOCSTSTAMP + struct bintime bt; +diff --git a/pcap-bt-linux.c b/pcap-bt-linux.c +index c7bfef1d..dcf3b575 100644 +--- a/pcap-bt-linux.c ++++ b/pcap-bt-linux.c +@@ -394,7 +394,8 @@ bt_read_linux(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char + pkth.caplen+=sizeof(pcap_bluetooth_h4_header); + pkth.len = pkth.caplen; + if (handle->fcode.bf_insns == NULL || +- pcap_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) { ++ pcap_filter(handle->fcode.bf_insns, handle->fcode.bf_len, ++ pktd, pkth.len, pkth.caplen)) { + callback(user, &pkth, pktd); + return 1; + } +diff --git a/pcap-bt-monitor-linux.c b/pcap-bt-monitor-linux.c +index 206e65b5..3f9d5b49 100644 +--- a/pcap-bt-monitor-linux.c ++++ b/pcap-bt-monitor-linux.c +@@ -151,7 +151,8 @@ bt_monitor_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_ch + bthdr->opcode = htons(hdr.opcode); + + if (handle->fcode.bf_insns == NULL || +- pcap_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) { ++ pcap_filter(handle->fcode.bf_insns, handle->fcode.bf_len, ++ pktd, pkth.len, pkth.caplen)) { + callback(user, &pkth, pktd); + return 1; + } +diff --git a/pcap-dag.c b/pcap-dag.c +index f261ead0..c3fe1dbd 100644 +--- a/pcap-dag.c ++++ b/pcap-dag.c +@@ -668,8 +668,9 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) + caplen = p->snapshot; + + /* Run the packet filter if there is one. */ +- if ((p->fcode.bf_insns == NULL) || pcap_filter(p->fcode.bf_insns, dp, packet_len, caplen)) { +- ++ if (p->fcode.bf_insns == NULL || ++ pcap_filter(p->fcode.bf_insns, p->fcode.bf_len, ++ dp, packet_len, caplen)) { + /* convert between timestamp formats */ + register unsigned long long ts; + +diff --git a/pcap-dbus.c b/pcap-dbus.c +index 506f150f..760bb9ba 100644 +--- a/pcap-dbus.c ++++ b/pcap-dbus.c +@@ -91,7 +91,8 @@ dbus_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *us + + gettimeofday(&pkth.ts, NULL); + if (handle->fcode.bf_insns == NULL || +- pcap_filter(handle->fcode.bf_insns, (u_char *)raw_msg, pkth.len, pkth.caplen)) { ++ pcap_filter(handle->fcode.bf_insns, handle->fcode.bf_len, ++ (u_char *)raw_msg, pkth.len, pkth.caplen)) { + handlep->packets_read++; + callback(user, &pkth, (u_char *)raw_msg); + count++; +diff --git a/pcap-dpdk.c b/pcap-dpdk.c +index 025a6748..cc31d2f2 100644 +--- a/pcap-dpdk.c ++++ b/pcap-dpdk.c +@@ -407,7 +407,9 @@ static int pcap_dpdk_dispatch(pcap_t *p, int max_cnt, pcap_handler cb, u_char *c + + } + if (bp){ +- if (p->fcode.bf_insns==NULL || pcap_filter(p->fcode.bf_insns, bp, pcap_header.len, pcap_header.caplen)){ ++ if (p->fcode.bf_insns==NULL || ++ pcap_filter(p->fcode.bf_insns, p->fcode.bf_len, ++ bp, pcap_header.len, pcap_header.caplen)){ + cb(cb_arg, &pcap_header, bp); + }else{ + pd->bpf_drop++; +diff --git a/pcap-int.h b/pcap-int.h +index 894e74af..11ca3c56 100644 +--- a/pcap-int.h ++++ b/pcap-int.h +@@ -619,13 +619,15 @@ struct pcap_bpf_aux_data { + * Filtering routine that takes the auxiliary data as an additional + * argument. + */ +-u_int pcap_filter_with_aux_data(const struct bpf_insn *, +- const u_char *, u_int, u_int, const struct pcap_bpf_aux_data *); ++u_int pcap_filter_with_aux_data(const struct bpf_insn *, const u_int, ++ const u_char *, const u_int, const u_int, ++ const struct pcap_bpf_aux_data *); + + /* + * Filtering routine that doesn't. + */ +-u_int pcap_filter(const struct bpf_insn *, const u_char *, u_int, u_int); ++u_int pcap_filter(const struct bpf_insn *, const u_int, const u_char *, ++ u_int, u_int); + + /* + * Routine to validate a BPF program. +diff --git a/pcap-linux.c b/pcap-linux.c +index 13bd8529..b2b2ca70 100644 +--- a/pcap-linux.c ++++ b/pcap-linux.c +@@ -3993,6 +3993,7 @@ static int pcap_handle_packet_mmap( + aux_data.vlan_tag = tp_vlan_tci & 0x0fff; + + if (pcap_filter_with_aux_data(handle->fcode.bf_insns, ++ handle->fcode.bf_len, + bp, + tp_len, + snaplen, +diff --git a/pcap-netfilter-linux.c b/pcap-netfilter-linux.c +index 2eb0fc8c..5b5f5c18 100644 +--- a/pcap-netfilter-linux.c ++++ b/pcap-netfilter-linux.c +@@ -259,8 +259,8 @@ netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_c + + gettimeofday(&pkth.ts, NULL); + if (handle->fcode.bf_insns == NULL || +- pcap_filter(handle->fcode.bf_insns, payload, pkth.len, pkth.caplen)) +- { ++ pcap_filter(handle->fcode.bf_insns, handle->fcode.bf_len, ++ payload, pkth.len, pkth.caplen)) { + handlep->packets_read++; + callback(user, &pkth, payload); + count++; +diff --git a/pcap-netmap.c b/pcap-netmap.c +index 27d36e5b..bcfd6e93 100644 +--- a/pcap-netmap.c ++++ b/pcap-netmap.c +@@ -81,7 +81,8 @@ pcap_netmap_filter(u_char *arg, struct pcap_pkthdr *h, const u_char *buf) + const struct bpf_insn *pc = p->fcode.bf_insns; + + ++pn->rx_pkts; +- if (pc == NULL || pcap_filter(pc, buf, h->len, h->caplen)) ++ if (pc == NULL || ++ pcap_filter(pc, p->fcode.bf_len, buf, h->len, h->caplen)) + pn->cb(pn->cb_arg, h, buf); + } + +diff --git a/pcap-npf.c b/pcap-npf.c +index 99b5981e..a4364353 100644 +--- a/pcap-npf.c ++++ b/pcap-npf.c +@@ -682,7 +682,8 @@ pcap_read_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) + */ + if (pw->filtering_in_kernel || + p->fcode.bf_insns == NULL || +- pcap_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) { ++ pcap_filter(p->fcode.bf_insns, p->fcode.bf_len, ++ datap, bhp->bh_datalen, caplen)) { + #ifdef ENABLE_REMOTE + switch (p->rmt_samp.method) { + +diff --git a/pcap-rdmasniff.c b/pcap-rdmasniff.c +index d63ca898..c8763b33 100644 +--- a/pcap-rdmasniff.c ++++ b/pcap-rdmasniff.c +@@ -172,7 +172,8 @@ rdmasniff_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u + pktd = (u_char *) handle->buffer + wc.wr_id * RDMASNIFF_RECEIVE_SIZE; + + if (handle->fcode.bf_insns == NULL || +- pcap_filter(handle->fcode.bf_insns, pktd, pkth.len, pkth.caplen)) { ++ pcap_filter(handle->fcode.bf_insns, handle->fcode.bf_len, ++ pktd, pkth.len, pkth.caplen)) { + callback(user, &pkth, pktd); + ++priv->packets_recv; + ++count; +diff --git a/pcap-snf.c b/pcap-snf.c +index fe9cc9c8..16ce9c8e 100644 +--- a/pcap-snf.c ++++ b/pcap-snf.c +@@ -192,7 +192,8 @@ snf_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) + caplen = p->snapshot; + + if ((p->fcode.bf_insns == NULL) || +- pcap_filter(p->fcode.bf_insns, req.pkt_addr, req.length, caplen)) { ++ pcap_filter(p->fcode.bf_insns, p->fcode.bf_len, ++ req.pkt_addr, req.length, caplen)) { + hdr.ts = snf_timestamp_to_timeval(req.timestamp, p->opt.tstamp_precision); + hdr.caplen = caplen; + hdr.len = req.length; +diff --git a/pcap-usb-linux.c b/pcap-usb-linux.c +index 726e4a8a..44b2bf30 100644 +--- a/pcap-usb-linux.c ++++ b/pcap-usb-linux.c +@@ -735,8 +735,8 @@ usb_read_linux_bin(pcap_t *handle, int max_packets _U_, pcap_handler callback, u + pkth.ts.tv_usec = info.hdr->ts_usec; + + if (handle->fcode.bf_insns == NULL || +- pcap_filter(handle->fcode.bf_insns, handle->buffer, +- pkth.len, pkth.caplen)) { ++ pcap_filter(handle->fcode.bf_insns, handle->fcode.bf_len, ++ handle->buffer, pkth.len, pkth.caplen)) { + handlep->packets_read++; + callback(user, &pkth, handle->buffer); + return 1; +@@ -904,8 +904,8 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch + pkth.ts.tv_usec = hdr->ts_usec; + + if (handle->fcode.bf_insns == NULL || +- pcap_filter(handle->fcode.bf_insns, (u_char*) hdr, +- pkth.len, pkth.caplen)) { ++ pcap_filter(handle->fcode.bf_insns, handle->fcode.bf_len, ++ (u_char*) hdr, pkth.len, pkth.caplen)) { + handlep->packets_read++; + callback(user, &pkth, (u_char*) hdr); + packets++; +diff --git a/pcap.c b/pcap.c +index ef1bbb71..9ee83f98 100644 +--- a/pcap.c ++++ b/pcap.c +@@ -4179,7 +4179,7 @@ pcap_offline_filter(const struct bpf_program *fp, const struct pcap_pkthdr *h, + const struct bpf_insn *fcode = fp->bf_insns; + + if (fcode != NULL) +- return (pcap_filter(fcode, pkt, h->len, h->caplen)); ++ return (pcap_filter(fcode, fp->bf_len, pkt, h->len, h->caplen)); + else + return (0); + } +diff --git a/savefile.c b/savefile.c +index db8a3aa0..e9708b23 100644 +--- a/savefile.c ++++ b/savefile.c +@@ -687,7 +687,8 @@ pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) + * and, if it passes, process it. + */ + if ((fcode = p->fcode.bf_insns) == NULL || +- pcap_filter(fcode, data, h.len, h.caplen)) { ++ pcap_filter(fcode, p->fcode.bf_len, ++ data, h.len, h.caplen)) { + (*callback)(user, &h, data); + n++; /* count the packet */ + if (n >= cnt) diff --git a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb index 692fdf606c..323cca3d98 100644 --- a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb +++ b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb @@ -18,6 +18,7 @@ SRC_URI = "https://www.tcpdump.org/release/${BP}.tar.gz \ file://CVE-2025-11961-02.patch \ file://CVE-2025-11964.patch \ file://01-CVE-2026-0799.patch \ + file://02-CVE-2026-31912.patch \ " SRC_URI[sha256sum] = "ed19a0383fad72e3ad435fd239d7cd80d64916b87269550159d20e47160ebe5f" ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [OE-core] [scarthgap][PATCH v2 2/7] libpcap: Fix CVE-2026-31912 2026-09-21 20:17 ` [scarthgap][PATCH v2 2/7] libpcap: Fix CVE-2026-31912 Jaipaul Cheernam @ 2026-10-02 8:30 ` Yoann Congal 0 siblings, 0 replies; 17+ messages in thread From: Yoann Congal @ 2026-10-02 8:30 UTC (permalink / raw) To: jaipaul.cheernam, openembedded-core On Mon Sep 21, 2026 at 10:17 PM CEST, Jaipaul Cheernam via lists.openembedded.org wrote: > NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-31912 > Upstream-commit: https://github.com/the-tcpdump-group/libpcap/commit/d3f358d3cffbe1ecb94d5284b3e81f052a0adcb9 > > Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> > --- > .../libpcap/libpcap/02-CVE-2026-31912.patch | 525 ++++++++++++++++++ > .../libpcap/libpcap_1.10.4.bb | 1 + > 2 files changed, 526 insertions(+) > create mode 100644 meta/recipes-connectivity/libpcap/libpcap/02-CVE-2026-31912.patch > > diff --git a/meta/recipes-connectivity/libpcap/libpcap/02-CVE-2026-31912.patch b/meta/recipes-connectivity/libpcap/libpcap/02-CVE-2026-31912.patch > new file mode 100644 > index 0000000000..d9fda1ec48 > --- /dev/null > +++ b/meta/recipes-connectivity/libpcap/libpcap/02-CVE-2026-31912.patch > @@ -0,0 +1,525 @@ > +From d3f358d3cffbe1ecb94d5284b3e81f052a0adcb9 Mon Sep 17 00:00:00 2001 > +From: Denis Ovsienko <denis@ovsienko.info> > +Date: Thu, 30 Jul 2026 13:33:55 +0100 > +Subject: [PATCH] CVE-2026-31912: Mind the program bounds in pcap_offline_filter(). > + > +The current revision of pcapint_filter_with_aux_data() does not know the > +number of instructions in the filter program, it assumes the program > +counter always remains within the bounds of the provided filter program > +and always reaches a return instruction. This holds for programs that > +have been generated or validated by libpcap. > + > +However, this does not necessarily hold for programs that come from an > +external source via pcap_offline_filter() or [deprecated] bpf_filter() > +and have not been explicitly validated. If the interpreter executes > +such a program and advances the program counter beyond the last > +instruction, it will be interpreting memory space after the filter > +program as BPF instructions, which in the current implementation will > +eventually cause either abort() (another commit addresses that) or > +SIGSEGV. > + > +To fix the latter problem, in pcapint_filter_with_aux_data() add a > +parameter for the number of instructions in the program and reject the > +packet as soon as (or just before) the program counter goes out of > +bounds. Update all incoming code paths to specify the length; also in > +pcap_offline_filter(3PCAP) make it clear the function now requires the > +'bf_len' member to be set correctly and uses it. > + > +(backported from commit d1209988c74dd9330659898d3b676ee6bbe1c551) > + > +(cherry picked from commit d3f358d3cffbe1ecb94d5284b3e81f052a0adcb9) > + Hello, > +Notes on backporting to 1.10.4: > + - Adapted to the 1.10.4 pcap_filter*() names (renamed to pcapint_*() > + after 1.10.4). > + - The upstream CHANGES/changelog hunk is not backported. > > +Upstream-Status: Backport [https://github.com/the-tcpdump-group/libpcap/commit/d3f358d3cffbe1ecb94d5284b3e81f052a0adcb9] This also drop a pcap-haiku.c hunk. Should'nt we patch pcap-haiku.cpp? This was before it was rewriten in C. I may have missed it for the wrynose patch but if a patch is needed, could you send a fix for wrynose as well? Also, please check that the backport notes are exhaustive (e.g. there is also a missing man patch for which a note would have been appreciated) > +CVE: CVE-2026-31912 > +Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> I'll hold the series for now. Can you check the above issues for the whole series? Regards, -- Yoann Congal Smile ECS ^ permalink raw reply [flat|nested] 17+ messages in thread
* [scarthgap][PATCH v2 3/7] libpcap: Fix CVE-2026-31911 2026-09-21 20:17 ` [scarthgap][PATCH v2 0/7] libpcap: backport seven CVE fixes from 1.10.7 Jaipaul Cheernam 2026-09-21 20:17 ` [scarthgap][PATCH v2 1/7] libpcap: Fix CVE-2026-0799 Jaipaul Cheernam 2026-09-21 20:17 ` [scarthgap][PATCH v2 2/7] libpcap: Fix CVE-2026-31912 Jaipaul Cheernam @ 2026-09-21 20:17 ` Jaipaul Cheernam 2026-09-21 20:17 ` [scarthgap][PATCH v2 4/7] libpcap: Fix CVE-2026-6244 Jaipaul Cheernam ` (3 subsequent siblings) 6 siblings, 0 replies; 17+ messages in thread From: Jaipaul Cheernam @ 2026-09-21 20:17 UTC (permalink / raw) To: openembedded-core NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-31911 Upstream-commit: https://github.com/the-tcpdump-group/libpcap/commit/a715bcdde830299cba4171514385cb17ec19b6e9 Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> --- .../libpcap/libpcap/03-CVE-2026-31911.patch | 45 +++++++++++++++++++ .../libpcap/libpcap_1.10.4.bb | 1 + 2 files changed, 46 insertions(+) create mode 100644 meta/recipes-connectivity/libpcap/libpcap/03-CVE-2026-31911.patch diff --git a/meta/recipes-connectivity/libpcap/libpcap/03-CVE-2026-31911.patch b/meta/recipes-connectivity/libpcap/libpcap/03-CVE-2026-31911.patch new file mode 100644 index 0000000000..a2d00d8c53 --- /dev/null +++ b/meta/recipes-connectivity/libpcap/libpcap/03-CVE-2026-31911.patch @@ -0,0 +1,45 @@ +From a715bcdde830299cba4171514385cb17ec19b6e9 Mon Sep 17 00:00:00 2001 +From: Denis Ovsienko <denis@ovsienko.info> +Date: Thu, 30 Jul 2026 13:34:08 +0100 +Subject: [PATCH] CVE-2026-31911: Fail opcodes safely in the BPF interpreter. + +This vulnerability has been discovered by FuzzAnything Organization. + +The current revision of pcapint_filter_with_aux_data() calls abort() if +the current instruction opcode is invalid, and assumes this never to be +the case. This holds for programs that have been generated by libpcap. + +However, this does not necessarily hold for programs that come from an +external source via pcap_offline_filter() or [deprecated] bpf_filter(). +Furthermore, this does not necessarily hold for programs that have been +validated by libpcap because the current revision of the validator has +gaps in the checks and accepts a number of invalid opcodes (another +commit addresses that). + +Thus in pcapint_filter_with_aux_data(), when the instruction opcode is +invalid, just reject the packet. + +(backported from commit 4ccb54bf4946d31a248ec93bdbeaabd97fb9d8f7) + +(cherry picked from commit a715bcdde830299cba4171514385cb17ec19b6e9) + +Notes on backporting to 1.10.4: + - The upstream CHANGES/changelog hunk is not backported. + +Upstream-Status: Backport [https://github.com/the-tcpdump-group/libpcap/commit/a715bcdde830299cba4171514385cb17ec19b6e9] +CVE: CVE-2026-31911 +Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> +--- +diff --git a/bpf_filter.c b/bpf_filter.c +index 2ea11d46..d6e4b019 100644 +--- a/bpf_filter.c ++++ b/bpf_filter.c +@@ -146,7 +146,7 @@ pcap_filter_with_aux_data(const struct bpf_insn *pc, const u_int proglen, + switch (pc->code) { + + default: +- abort(); ++ return 0; + case BPF_RET|BPF_K: + return (u_int)pc->k; + diff --git a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb index 323cca3d98..5b97c14e85 100644 --- a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb +++ b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb @@ -19,6 +19,7 @@ SRC_URI = "https://www.tcpdump.org/release/${BP}.tar.gz \ file://CVE-2025-11964.patch \ file://01-CVE-2026-0799.patch \ file://02-CVE-2026-31912.patch \ + file://03-CVE-2026-31911.patch \ " SRC_URI[sha256sum] = "ed19a0383fad72e3ad435fd239d7cd80d64916b87269550159d20e47160ebe5f" ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [scarthgap][PATCH v2 4/7] libpcap: Fix CVE-2026-6244 2026-09-21 20:17 ` [scarthgap][PATCH v2 0/7] libpcap: backport seven CVE fixes from 1.10.7 Jaipaul Cheernam ` (2 preceding siblings ...) 2026-09-21 20:17 ` [scarthgap][PATCH v2 3/7] libpcap: Fix CVE-2026-31911 Jaipaul Cheernam @ 2026-09-21 20:17 ` Jaipaul Cheernam 2026-09-21 20:17 ` [scarthgap][PATCH v2 5/7] libpcap: Fix CVE-2026-6554 Jaipaul Cheernam ` (2 subsequent siblings) 6 siblings, 0 replies; 17+ messages in thread From: Jaipaul Cheernam @ 2026-09-21 20:17 UTC (permalink / raw) To: openembedded-core NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-6244 Upstream-commit: https://github.com/the-tcpdump-group/libpcap/commit/98bb921b141aa642faedbf2ac510541c76499a19 Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> --- .../libpcap/libpcap/04-CVE-2026-6244.patch | 49 +++++++++++++++++++ .../libpcap/libpcap_1.10.4.bb | 1 + 2 files changed, 50 insertions(+) create mode 100644 meta/recipes-connectivity/libpcap/libpcap/04-CVE-2026-6244.patch diff --git a/meta/recipes-connectivity/libpcap/libpcap/04-CVE-2026-6244.patch b/meta/recipes-connectivity/libpcap/libpcap/04-CVE-2026-6244.patch new file mode 100644 index 0000000000..5215b12ffb --- /dev/null +++ b/meta/recipes-connectivity/libpcap/libpcap/04-CVE-2026-6244.patch @@ -0,0 +1,49 @@ +From 98bb921b141aa642faedbf2ac510541c76499a19 Mon Sep 17 00:00:00 2001 +From: Denis Ovsienko <denis@ovsienko.info> +Date: Thu, 30 Jul 2026 13:34:21 +0100 +Subject: [PATCH] CVE-2026-6244: Avoid division by zero via pcap_offline_filter(). + +The current revision of pcapint_filter_with_aux_data() for "div x" and +"mod x" correctly rejects the packet if X is zero, but for "div #k" and +"mod #k" it assumes that k is never zero. This holds for programs that +have been generated or validated by libpcap. + +However, this does not necessarily hold for programs that come from an +external source via pcap_offline_filter() or [deprecated] bpf_filter() +and have not been explicitly validated. If the interpreter executes +such a program, it can attempt a division by zero, which will typically +terminate the process via SIGFPE. + +To fix this problem, in pcapint_filter_with_aux_data() treat "div #k" +and "mod #k" the same way as "div x" and "mod x". + +(backported from commit 0b2b1ad4a1796513613ff68e9dc09049cc8e0af4) + +(cherry picked from commit 98bb921b141aa642faedbf2ac510541c76499a19) + +Notes on backporting to 1.10.4: + - The upstream CHANGES/changelog hunk is not backported. + +Upstream-Status: Backport [https://github.com/the-tcpdump-group/libpcap/commit/98bb921b141aa642faedbf2ac510541c76499a19] +CVE: CVE-2026-6244 +Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> +--- +diff --git a/bpf_filter.c b/bpf_filter.c +index 497b1586..df92c433 100644 +--- a/bpf_filter.c ++++ b/bpf_filter.c +@@ -422,10 +422,14 @@ DIAG_ON_DEFAULT_ONLY_SWITCH + continue; + + case BPF_ALU|BPF_DIV|BPF_K: ++ if (pc->k == 0) ++ return 0; + A /= pc->k; + continue; + + case BPF_ALU|BPF_MOD|BPF_K: ++ if (pc->k == 0) ++ return 0; + A %= pc->k; + continue; + diff --git a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb index 5b97c14e85..d23a018a95 100644 --- a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb +++ b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb @@ -20,6 +20,7 @@ SRC_URI = "https://www.tcpdump.org/release/${BP}.tar.gz \ file://01-CVE-2026-0799.patch \ file://02-CVE-2026-31912.patch \ file://03-CVE-2026-31911.patch \ + file://04-CVE-2026-6244.patch \ " SRC_URI[sha256sum] = "ed19a0383fad72e3ad435fd239d7cd80d64916b87269550159d20e47160ebe5f" ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [scarthgap][PATCH v2 5/7] libpcap: Fix CVE-2026-6554 2026-09-21 20:17 ` [scarthgap][PATCH v2 0/7] libpcap: backport seven CVE fixes from 1.10.7 Jaipaul Cheernam ` (3 preceding siblings ...) 2026-09-21 20:17 ` [scarthgap][PATCH v2 4/7] libpcap: Fix CVE-2026-6244 Jaipaul Cheernam @ 2026-09-21 20:17 ` Jaipaul Cheernam 2026-09-21 20:17 ` [scarthgap][PATCH v2 6/7] libpcap: Fix CVE-2026-18313 Jaipaul Cheernam 2026-09-21 20:17 ` [scarthgap][PATCH v2 7/7] libpcap: Fix CVE-2026-18238 Jaipaul Cheernam 6 siblings, 0 replies; 17+ messages in thread From: Jaipaul Cheernam @ 2026-09-21 20:17 UTC (permalink / raw) To: openembedded-core NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-6554 Upstream-commit: https://github.com/the-tcpdump-group/libpcap/commit/ff3c83475ac303c6b681c52ad0b6e14795a8e0ce Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> --- .../libpcap/libpcap/05-CVE-2026-6554.patch | 92 +++++++++++++++++++ .../libpcap/libpcap_1.10.4.bb | 1 + 2 files changed, 93 insertions(+) create mode 100644 meta/recipes-connectivity/libpcap/libpcap/05-CVE-2026-6554.patch diff --git a/meta/recipes-connectivity/libpcap/libpcap/05-CVE-2026-6554.patch b/meta/recipes-connectivity/libpcap/libpcap/05-CVE-2026-6554.patch new file mode 100644 index 0000000000..9c44294d1f --- /dev/null +++ b/meta/recipes-connectivity/libpcap/libpcap/05-CVE-2026-6554.patch @@ -0,0 +1,92 @@ +From ff3c83475ac303c6b681c52ad0b6e14795a8e0ce Mon Sep 17 00:00:00 2001 +From: Denis Ovsienko <denis@ovsienko.info> +Date: Thu, 30 Jul 2026 13:34:33 +0100 +Subject: [PATCH] CVE-2026-6554: Limit "ja L" looping in pcap_offline_filter(). + +This vulnerability has been discovered by Kaixuan LI. + +The current revision of pcapint_filter_with_aux_data() assumes that any +"ja L" instruction in a filter program does not jump to itself or to a +prior instruction that is guaranteed to reach the same "ja L" again. +This holds for programs that have been generated by libpcap. + +However, this does not necessarily hold for programs that come from an +external source via pcap_offline_filter() or [deprecated] bpf_filter(). +If the interpreter executes such a program, upon reaching such an +instruction it will begin looping infinitely. + +To mitigate this problem, in pcapint_filter_with_aux_data() enforce a +hard-coded limit on the number of backward jumps per packet. Ibid., and +in pcapint_validate_filter() as well, reject the only immediately +detectable case of an infinite loop. + +(backported from commit 63c005c25aeabf1404968add49fc885da3e127e0) + +(cherry picked from commit ff3c83475ac303c6b681c52ad0b6e14795a8e0ce) + +Notes on backporting to 1.10.4: + - Adapted to the 1.10.4 pcap_filter*() names (renamed to pcapint_*() + after 1.10.4). + - The upstream CHANGES/changelog hunk is not backported. + +Upstream-Status: Backport [https://github.com/the-tcpdump-group/libpcap/commit/ff3c83475ac303c6b681c52ad0b6e14795a8e0ce] +CVE: CVE-2026-6554 +Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> +--- +diff --git a/bpf_filter.c b/bpf_filter.c +index df92c433..ae8a3a36 100644 +--- a/bpf_filter.c ++++ b/bpf_filter.c +@@ -72,6 +72,8 @@ enum { + BPF_S_ANC_VLAN_TAG_PRESENT, + }; + ++#define MAX_BACKWARD_JUMPS 64U ++ + /* + * Kernel BPF implementations tend to define BPF_MAXINSNS to 512 or 4096, the + * userland interpreter in libpcap is meant to support much longer filter +@@ -146,6 +148,7 @@ pcap_filter_with_aux_data(const struct bpf_insn *pc, const u_int proglen, + A = 0; + X = 0; + const struct bpf_insn *pc0 = pc; ++ unsigned backward_jumps = 0; + --pc; + for (;;) { + ++pc; +@@ -320,6 +323,17 @@ DIAG_ON_DEFAULT_ONLY_SWITCH + */ + if ((bpf_u_int32)(pc - pc0) + 1 + pc->k >= proglen) + return 0; ++ /* ++ * Terminate the program if this is a non-forward jump ++ * and is: ++ * - a guaranteed infinite loop because it jumps to ++ * itself (exactly the same as in the validator), or ++ * - a backward jump after many enough backward jumps ++ * already made for this packet. ++ */ ++ if ((bpf_int32)pc->k < 0 && ((bpf_int32)pc->k == -1 || ++ backward_jumps++ >= MAX_BACKWARD_JUMPS)) ++ return 0; + /* + * XXX - we currently implement "ip6 protochain" + * with backward jumps, so sign-extend pc->k. +@@ -607,6 +621,17 @@ pcap_validate_filter(const struct bpf_insn *f, int len) + */ + if (from + p->k >= (u_int)len) + return 0; ++ /* ++ * The only type of infinite loop that can be ++ * detected in this function is a "ja L" that ++ * jumps to itself. For this only k == -1 ++ * needs to be tested because the check above ++ * has already rejected all other values that ++ * would wrap the pointer equivalently on ++ * 32-bit architectures. ++ */ ++ if ((bpf_int32)p->k == -1) ++ return 0; + break; + case BPF_JEQ: + case BPF_JGT: diff --git a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb index d23a018a95..f7ba1bf3ea 100644 --- a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb +++ b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb @@ -21,6 +21,7 @@ SRC_URI = "https://www.tcpdump.org/release/${BP}.tar.gz \ file://02-CVE-2026-31912.patch \ file://03-CVE-2026-31911.patch \ file://04-CVE-2026-6244.patch \ + file://05-CVE-2026-6554.patch \ " SRC_URI[sha256sum] = "ed19a0383fad72e3ad435fd239d7cd80d64916b87269550159d20e47160ebe5f" ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [scarthgap][PATCH v2 6/7] libpcap: Fix CVE-2026-18313 2026-09-21 20:17 ` [scarthgap][PATCH v2 0/7] libpcap: backport seven CVE fixes from 1.10.7 Jaipaul Cheernam ` (4 preceding siblings ...) 2026-09-21 20:17 ` [scarthgap][PATCH v2 5/7] libpcap: Fix CVE-2026-6554 Jaipaul Cheernam @ 2026-09-21 20:17 ` Jaipaul Cheernam 2026-09-21 20:17 ` [scarthgap][PATCH v2 7/7] libpcap: Fix CVE-2026-18238 Jaipaul Cheernam 6 siblings, 0 replies; 17+ messages in thread From: Jaipaul Cheernam @ 2026-09-21 20:17 UTC (permalink / raw) To: openembedded-core NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-18313 Upstream-commit: https://github.com/the-tcpdump-group/libpcap/commit/f9775af1a0ec76db60c7213241e6b48f1be10ac7 Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> --- .../libpcap/libpcap/06-CVE-2026-18313.patch | 84 +++++++++++++++++++ .../libpcap/libpcap_1.10.4.bb | 1 + 2 files changed, 85 insertions(+) create mode 100644 meta/recipes-connectivity/libpcap/libpcap/06-CVE-2026-18313.patch diff --git a/meta/recipes-connectivity/libpcap/libpcap/06-CVE-2026-18313.patch b/meta/recipes-connectivity/libpcap/libpcap/06-CVE-2026-18313.patch new file mode 100644 index 0000000000..2a9df12e2a --- /dev/null +++ b/meta/recipes-connectivity/libpcap/libpcap/06-CVE-2026-18313.patch @@ -0,0 +1,84 @@ +From f9775af1a0ec76db60c7213241e6b48f1be10ac7 Mon Sep 17 00:00:00 2001 +From: Denis Ovsienko <denis@ovsienko.info> +Date: Sat, 1 Aug 2026 18:24:48 +0100 +Subject: [PATCH] CVE-2026-18313: Fix a memory leak in rpcapd. + +This vulnerability was originally reported publicly, hence no credit is +given. + +daemon_unpackapplyfilter() can allocate a temporary buffer for up to +RPCAP_BPF_MAXINSNS (8192) BPF instructions (65536 bytes) per each +received RPCAP_MSG_UPDATEFILTER_REQ or RPCAP_MSG_STARTCAP_REQ message. +It never frees the memory, so repeated messages from a client will +eventually leak enough memory on the server to cause problems. This +holds for all connections that pass the validation and some connections +that do not. + +48 bytes in 1 blocks are definitely lost in loss record 2 of 2 + at 0x4844818: malloc (vg_replace_malloc.c:446) + by 0x111AAB: daemon_unpackapplyfilter (daemon.c:2372) + by 0x113279: daemon_msg_startcap_req.constprop.0 (daemon.c:2139) + by 0x114808: daemon_serviceloop (daemon.c:901) + by 0x115BC7: accept_connection (rpcapd.c:1321) + by 0x115BC7: accept_connections (rpcapd.c:1118) + by 0x115BC7: main_startup (rpcapd.c:709) + by 0x1112BD: main (rpcapd.c:567) + +To fix this, after a successful malloc() return exactly once, after the +free() call. + +(backported from commit 26a1c75702b105ac8788014f35f1b5c57fa6043b) + +(cherry picked from commit f9775af1a0ec76db60c7213241e6b48f1be10ac7) + +Notes on backporting to 1.10.4: + - The upstream CHANGES/changelog hunk is not backported. + +Upstream-Status: Backport [https://github.com/the-tcpdump-group/libpcap/commit/f9775af1a0ec76db60c7213241e6b48f1be10ac7] +CVE: CVE-2026-18313 +Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech> +--- +diff --git a/rpcapd/daemon.c b/rpcapd/daemon.c +index 9b0f8285..b0268688 100644 +--- a/rpcapd/daemon.c ++++ b/rpcapd/daemon.c +@@ -2378,14 +2378,8 @@ daemon_unpackapplyfilter(SOCKET sockctrl, SSL *ctrl_ssl, struct session *session + { + status = rpcapd_recv(sockctrl, ctrl_ssl, (char *) &insn, + sizeof(struct rpcap_filterbpf_insn), plenp, errmsgbuf); +- if (status == -1) +- { +- return -1; +- } +- if (status == -2) +- { +- return -2; +- } ++ if (status == -1 || status == -2) ++ goto free_and_return_status; + + bf_insn->code = ntohs(insn.code); + bf_insn->jf = insn.jf; +@@ -2401,16 +2395,19 @@ daemon_unpackapplyfilter(SOCKET sockctrl, SSL *ctrl_ssl, struct session *session + if (bpf_validate(bf_prog.bf_insns, bf_prog.bf_len) == 0) + { + snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "The filter contains bogus instructions"); +- return -2; ++ status = -2; ++ goto free_and_return_status; + } + + if (pcap_setfilter(session->fp, &bf_prog)) + { + snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "RPCAP error: %s", pcap_geterr(session->fp)); +- return -2; ++ status = -2; + } + +- return 0; ++free_and_return_status: ++ free(bf_prog.bf_insns); ++ return status; + } + + static int diff --git a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb index f7ba1bf3ea..5f1506f8fc 100644 --- a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb +++ b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb @@ -22,6 +22,7 @@ SRC_URI = "https://www.tcpdump.org/release/${BP}.tar.gz \ file://03-CVE-2026-31911.patch \ file://04-CVE-2026-6244.patch \ file://05-CVE-2026-6554.patch \ + file://06-CVE-2026-18313.patch \ " SRC_URI[sha256sum] = "ed19a0383fad72e3ad435fd239d7cd80d64916b87269550159d20e47160ebe5f" ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [scarthgap][PATCH v2 7/7] libpcap: Fix CVE-2026-18238 2026-09-21 20:17 ` [scarthgap][PATCH v2 0/7] libpcap: backport seven CVE fixes from 1.10.7 Jaipaul Cheernam ` (5 preceding siblings ...) 2026-09-21 20:17 ` [scarthgap][PATCH v2 6/7] libpcap: Fix CVE-2026-18313 Jaipaul Cheernam @ 2026-09-21 20:17 ` Jaipaul Cheernam 6 siblings, 0 replies; 17+ messages in thread From: Jaipaul Cheernam @ 2026-09-21 20:17 UTC (permalink / raw) To: openembedded-core 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 | 222 ++++++++++++++++++ .../libpcap/libpcap_1.10.4.bb | 1 + 2 files changed, 223 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..36f80c483f --- /dev/null +++ b/meta/recipes-connectivity/libpcap/libpcap/07-CVE-2026-18238.patch @@ -0,0 +1,222 @@ +From b9590d482986d64673712460aae1d48d11fa0473 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) + +Notes on backporting to 1.10.4: + - The upstream CHANGES/changelog hunk is not backported. + +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> +--- +diff --git a/pcap-rpcap.c b/pcap-rpcap.c +index 22fc7363..30fbd6d6 100644 +--- a/pcap-rpcap.c ++++ b/pcap-rpcap.c +@@ -388,10 +388,9 @@ rpcap_deseraddr(struct rpcap_sockaddr *sockaddrin, struct sockaddr_storage **soc + 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; + +@@ -448,13 +447,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 */ +@@ -470,6 +491,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)) + { + /* +@@ -479,8 +502,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 +@@ -495,6 +528,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)) + { + /* +@@ -514,27 +548,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. */ +@@ -557,27 +599,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.4.bb b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb index 5f1506f8fc..3892454a40 100644 --- a/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb +++ b/meta/recipes-connectivity/libpcap/libpcap_1.10.4.bb @@ -23,6 +23,7 @@ SRC_URI = "https://www.tcpdump.org/release/${BP}.tar.gz \ 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] = "ed19a0383fad72e3ad435fd239d7cd80d64916b87269550159d20e47160ebe5f" ^ permalink raw reply related [flat|nested] 17+ messages in thread
end of thread, other threads:[~2026-10-02 8:30 UTC | newest] Thread overview: 17+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-15 19:45 [scarthgap][PATCH 0/7] libpcap: backport seven CVE fixes from 1.10.7 Jaipaul Cheernam 2026-09-15 19:45 ` [scarthgap][PATCH 1/7] libpcap: Fix CVE-2026-0799 Jaipaul Cheernam 2026-09-15 19:45 ` [scarthgap][PATCH 2/7] libpcap: Fix CVE-2026-31912 Jaipaul Cheernam 2026-09-15 19:45 ` [scarthgap][PATCH 3/7] libpcap: Fix CVE-2026-31911 Jaipaul Cheernam 2026-09-15 19:45 ` [scarthgap][PATCH 4/7] libpcap: Fix CVE-2026-6244 Jaipaul Cheernam 2026-09-15 19:45 ` [scarthgap][PATCH 5/7] libpcap: Fix CVE-2026-6554 Jaipaul Cheernam 2026-09-15 19:45 ` [scarthgap][PATCH 6/7] libpcap: Fix CVE-2026-18313 Jaipaul Cheernam 2026-09-15 19:45 ` [scarthgap][PATCH 7/7] libpcap: Fix CVE-2026-18238 Jaipaul Cheernam 2026-09-21 20:17 ` [scarthgap][PATCH v2 0/7] libpcap: backport seven CVE fixes from 1.10.7 Jaipaul Cheernam 2026-09-21 20:17 ` [scarthgap][PATCH v2 1/7] libpcap: Fix CVE-2026-0799 Jaipaul Cheernam 2026-09-21 20:17 ` [scarthgap][PATCH v2 2/7] libpcap: Fix CVE-2026-31912 Jaipaul Cheernam 2026-10-02 8:30 ` [OE-core] " Yoann Congal 2026-09-21 20:17 ` [scarthgap][PATCH v2 3/7] libpcap: Fix CVE-2026-31911 Jaipaul Cheernam 2026-09-21 20:17 ` [scarthgap][PATCH v2 4/7] libpcap: Fix CVE-2026-6244 Jaipaul Cheernam 2026-09-21 20:17 ` [scarthgap][PATCH v2 5/7] libpcap: Fix CVE-2026-6554 Jaipaul Cheernam 2026-09-21 20:17 ` [scarthgap][PATCH v2 6/7] libpcap: Fix CVE-2026-18313 Jaipaul Cheernam 2026-09-21 20:17 ` [scarthgap][PATCH v2 7/7] libpcap: Fix CVE-2026-18238 Jaipaul Cheernam
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox