#1151052 busybox: CVE-2026-88839

Package:
src:busybox
Source:
src:busybox
Submitter:
Moritz Mühlenhoff
Date:
2026-11-03 11:43:03 UTC
Severity:
normal
Tags:
#1151052#5
Date:
2026-10-16 12:54:43 UTC
From:
To:
Hi,

The following vulnerability was published for busybox.

CVE-2026-88839[0]:
| BusyBox passwd/group tokenize() references a stale endpoint pointer
| after trimming, causing an out-of-bounds write of heap pointers.

https://bugzilla.redhat.com/show_bug.cgi?id=2531353

If you fix the vulnerability please also make sure to include the
CVE (Common Vulnerabilities & Exposures) id in your changelog entry.

For further information see:

[0] https://security-tracker.debian.org/tracker/CVE-2026-88839
https://www.cve.org/CVERecord?id=CVE-2026-88839

Please adjust the affected versions in the BTS as needed.

#1151052#12
Date:
2026-11-03 11:32:16 UTC
From:
To:
Hi,

None of these bugs, nor the tracker, records upstream fix commits yet.
I went through busybox master (
https://www.google.com/url?q=http://git.busybox.net/busybox&source=gmail&ust=1793791935761000&sa=E,
HEAD 5eee801,
2026-10-22) and matched each commit against the CVE text and the Red
Hat bugzilla descriptions. This is a single mail to all the affected
bugs, to avoid eleven near-identical messages.

FIXED UPSTREAM (all after the 1_38_0 tag, so 1:1.38.0-3 is affected):

CVE-2026-88830 (#1151048) TLS Montgomery buffer unit confusion
89ac82774f90e270d04ed5299e5cf05dfbc314c1 "tls: fix undersized buffer
calculation"
It computes cSize = (2*pa+1)*sizeof(pstm_digit) and uses it both for
the paDlen check and for xzalloc(). The old code compared paDlen (in
bytes) against 2*pa+1 (in digits). Upstream's commit message calls the
xzalloc branch unreachable, but the check fix applies to the paD path
too.

CVE-2026-88831 (#1151049) httpd invalid CIDR deny rule fails open
339e3c62f5bcf252839c8abca5325f48a22f21aa "httpd: fix handling of
"D:1.2.3/999""
On a parse error it now zeroes pip->ip as well as the mask, so the rule
becomes D:0/0 (deny all) instead of D:IP/0 (which matches nobody).

CVE-2026-88832 (#1151050) romfs volume_id unbounded strlen
9073c1d15c9953c6f1e39145815fc5dccfa6081c "volume_id/romfs: limit the
maximum size of label to VOLUME_ID_LABEL_SIZE"
It uses strnlen(..., VOLUME_ID_LABEL_SIZE), clamps the count in
volume_id_set_label_string(), and compares the full 8-byte magic.

CVE-2026-88834 (#1150941) httpd user existence oracle
b829bba95095b87834628adb38ea14b5885c0fbc "httpd: do not try to use
obviously bogus password from /etc/passwd"
If the passwd entry is "x"/"*" and getspnam_r() finds no shadow entry,
it skips the entry instead of running crypt on it. This matches the
"uncommon password file states" in the CVE text; please double-check.

CVE-2026-88837 (#1151051) httpd yescrypt hash treated as plaintext
9f5cbdcaa5972d58503c59cd0da13da1e5bb272b "httpd: allow yescrypt passwords
("$y$....")"
check_user_passwd() now treats "$y" as encrypted, not only "$<digit>".

CVE-2026-88839 (#1151052) libpwdgrp tokenize() stale end pointer
c2dec52d37380d27d89827cf01a770f6b3b04e3a "libpwdgrp: tokenizer fix for
trailing whitespace removeal."
A one-line change: it tests *p instead of the stale *end after
overlapping_strcpy().

CVE-2026-88842 (#1151678) dpkg write_status_file() field cursor not reset
d5cc94063b2bb5b54fe1021e54600cbcbce6a350 "dpkg: fix field handling in
write_status_file()"
field_start moves into the "not-installed" and "config-files" branches,
so it starts at 0 for every stanza.

CVE-2026-108119 (#1150771) tar deferred symlink+hardlink escape
382008b3f07d78e3abbc50d00bb857622dbbfac6 "tar: protect against
Symlink+Hardlink attack" (+ testsuite/tar.tests case)
5da20102b5db249c76edddd2cf608394a1ad34dc "tar: ".." is also an unsafe
filename, treat as such"
The CVE text specifically mentions a symlink target of exactly "..",
which is what 5da2010 handles, so both commits are needed.

Backport check against 1.38.0 (the 1_38_0 tag): 89ac827, 339e3c6,
9073c1d, 9f5cbdc, b829bba, c2dec52, 5da2010 and 382008b cherry-pick
cleanly, in that order, on top of 1_38_0. d5cc940 conflicts only
because of unrelated read_package_field() refactoring that landed on
master on 2026-09-21 (f5a4a02, 7c61186, e2c5cc0, ...). The attached
minimal backport does just the field_start move. I checked these
against the upstream tag, not against Debian's patch series, but none
of the debian/patches I can see on salsa touch these functions.

NOT FIXED UPSTREAM (as of 5eee801):

CVE-2026-88833 (#1150942) udhcpc raw packet length
fd1972099f28636b5deea200022b528f3a0bd523 "udhcpc: ensure packet.data.cookie
exists before we access it"
This raises the minimum check on the recvmsg() length, but that check
still runs before "bytes = ntohs(packet.ip.tot_len)". The value used
afterwards (bytes -= sizeof(ip)+sizeof(udp); memcpy(..., bytes)) is
not re-checked against the minimum. That is the path the Red Hat
description (rhbz#2531347) gives, so I think the issue is still open
on master and fd19720 alone does not fix it. The obvious fix is to
repeat the minimum-size check after the tot_len assignment. I have not
tested that, so I am only describing it, not offering a patch.

CVE-2026-88829 (#1151677) httpd P: proxy
39c2dc8 only documents that P: proxying does not check passwords.
There is no code change for the pipelined-request path rewrite.

CVE-2026-88838 (#1150940) mount clearing-mask options
556567f is "mount: document a possible bug in comment, no code changes".

CVE-2026-90954 (no Debian bug) dpkg-deb ar handler
archival/libarchive/get_header_ar.c:133 still calls
create_links_from_list() inside the per-member loop on master.

CVE-2026-92205 (#1151857, ZDI-26-705) was published as a 0-day with no
technical detail, so I could not match it to a commit.

What I have NOT done: I have not built busybox or run the testsuite,
with or without these commits. The above is from reading the commits
and cherry-picking onto 1_38_0.

Regards

#1151052#17
Date:
2026-11-03 11:41:11 UTC
From:
To:
Hi,

A follow-up to my mail mapping upstream commits to these CVEs, which was
static only. I have now built and tested them.

Trees:
base: upstream tag 1_38_0
patched: 1_38_0 + 89ac827, 339e3c6, 9073c1d, 9f5cbdc, b829bba,
c2dec52, 5da2010, 382008b + the minimal d5cc940 backport
attached to the previous mail
Config: make defconfig, with CONFIG_TC disabled (as Debian does,
because of the cbq removal). Built on amd64, gcc, Debian sid.

Build: both trees build with no errors and no warnings in the touched
files.

Testsuite (make check, run as an unprivileged user):
base: PASS 1012, FAIL 8, SKIPPED 27
patched: PASS 1013, FAIL 8, SKIPPED 27

The 8 failures are identical in both trees (cpio lists hardlinks;
ls -q/-Q/-qQ; three sed NUL/label tests; tar writing into read-only
dir), so they are pre-existing or environment-related and not caused
by the fixes. The extra PASS is the test that 382008b adds.

CVE-2026-108119 (#1150771): I copied upstream's new
testsuite/tar.tests, which contains the test "tar Symlink+Hardlink
attack: create symlink-to-outside and then create a hardlink in it",
into the base tree and ran it against the unpatched 1.38.0 binary:

base: FAIL - expected "can't create hardlink 'portal/ESCAPED' to
'seed': Not a directory" / exit 1;
got exit 0 and "ESCAPED!", i.e. the file was created outside
the extraction directory
patched: PASS

So 1.38.0 is affected, and 382008b (+5da2010) fixes it on 1.38.0.

There are no testsuite cases for the other CVEs (httpd, tls, volume_id,
libpwdgrp, dpkg). For those, the result above only shows that the
backports build and cause no regressions in the existing tests; I did
not exercise the fixed code paths.

Regards