** Description changed: + SRU justification: + + [ Impact ] + + * On s390x systems with a z13 (or later) CPU, glibc's vector-optimized + wcsncmp() implementation (sysdeps/s390/wcsncmp-vx.S, used whenever the + HWCAP_S390_VX facility is available, i.e. essentially every s390x system + in practice) can segfault when called with n == 1. + + * The bug is triggered when the single wide character being compared is + equal on both strings AND that character is the last one before a page + boundary. The current code special-cases the very first character by + loading and comparing it directly (without using the vector + load-to-block-boundary instruction, vlbb, which is otherwise used + throughout to avoid reading past the end of a buffer/page). After that + direct compare, it fails to re-check whether n has already been + satisfied and falls through into the main vector loop, which then issues + an additional (unbounded) load that can read past the page boundary and + fault. + + * Any userspace or library code that calls wcsncmp(s1, s2, 1) - a + perfectly legal call per POSIX/GNU extension semantics - can crash if + the compared buffers happen to be positioned so that the single + character sits right at the end of a mapped page. This is a real crash + bug (denial of service), not merely a performance concern, and is only + reproducible on s390x hardware supporting the z13 vector facility. + + * The fix has already been cherry-picked upstream onto every maintained + stable glibc branch at the time (2.32 through 2.39), and is included as + of glibc 2.40. It is already present in Ubuntu 24.10 (oracular) via the + 2.40-1ubuntu1 merge (this bug's oracular task is Fix Released). + + [ Fix ] + + * 9b7651410375ec8848a1944992d663d514db4ba7 "s390x: Fix segfault in wcsncmp [BZ #31934]" + The fix removes the special-cased "check first character without vector + load" fast path entirely and lets the main vlbb-based loop (which + already respects n) handle the first character too. It is a minimal, + surgical, s390x-only assembly change (net -9 lines) with no behavioural + change for any other architecture. + + * It is missing in: + - Ubuntu 22.04 LTS (jammy) - glibc 2.35-0ubuntu3.14 + - Ubuntu 24.04 LTS (noble) - glibc 2.39-0ubuntu8.8 + + [ Test Plan ] + + * Reproducing the crash (pre-fix) requires an s390x machine/VM with a + z13-or-later CPU (i.e. essentially any currently supported s390x + target). + + * A standalone reproducer, extracted by IBM from Florian Weimer's test + case for BZ #31934, is attached to the bug: + https://bugs.launchpad.net/ubuntu/+source/glibc/+bug/2073372/+attachment/5798051/+files/tst-bz31934-wcsncmp-standalone.c + It allocates two adjacent pages, unmaps/guards the page following the + buffer, places a single wide character right at the end of the mapped + page in both buffers, and calls wcsncmp(s1, s2, 1). + + Steps: + 1. On s390x (z13+), compile and run the reproducer against the + stock/-updates libc6: + $ gcc -o tst-bz31934 tst-bz31934-wcsncmp-standalone.c + $ ./tst-bz31934 + Expected (unpatched): SIGSEGV. + 2. Install the candidate libc6 from -proposed (or the PPA build) and + re-run the same binary (no rebuild needed, this is a runtime libc + fix): + $ ./tst-bz31934 + Expected (patched): no crash, wcsncmp() returns 0 (equal) as + expected for n=1. + + * In addition, upstream added permanent regression coverage for this bug + in "Enhanced test coverage for strncmp, wcsncmp" + (commit 54252394c25ddf0062e288d4a6ab7a885f8ae009), which extends the + existing wcsmbs/test-wcsncmp.c test to include this corner case. This + test is part of the normal build-time test suite (run automatically by + the package build/autopkgtest on s390x) for the version already fixed + in oracular/2.40, but is not yet present in the jammy/noble sources; it + is not required for this SRU (the assembly fix alone is sufficient and + independently verifiable with the standalone reproducer above), but + could be considered as a follow-up hardening item. + + [ Where problems could occur ] + + * The change touches only sysdeps/s390/wcsncmp-vx.S, which is compiled + only for s390x and only used when the z13 vector facility (ifunc + HAVE_WCSNCMP_Z13) is selected at runtime; no other architecture's + wcsncmp implementation, nor any other symbol, is affected. + + * The fix removes an early-exit fast path that special-cased "compare + just the first character directly." The remaining code (the + vlbb-based loop) already handles the first character correctly and + already respects n, so semantically the change simply routes the n=1 + (and n>1) first-character comparison through the existing, + already-tested block-boundary-safe loop instead of a separate, + buggy shortcut. Risk of a subtle behavioural regression (e.g. wrong + comparison result or off-by-one on the returned difference value) is + assessed as low given: + - it is a small, precise upstream fix, authored by the IBM s390x + glibc maintainer; + - it has shipped in every currently-supported upstream glibc branch + (2.35 equivalent and later) as well as Ubuntu 24.10 for several + months with no reported regressions; + - it is exercised by the general wcsncmp test coverage in the + existing test suite (wcsmbs/test-wcsncmp, wcsmbs/tst-wcsncmp2) + which is run on every build via autopkgtest. + + * As with any glibc SRU, the package is essential and universally + depended upon; a bad build would affect every s390x system. This is + mitigated by: + - restricting the change to a single, s390x-only assembly file; + - running the full glibc build-time testsuite before release; + - running autopkgtest across all supported architectures in + -proposed; + - test-building in a PPA across all architectures prior to upload, + to confirm no build regression is introduced for the other + (unaffected) architectures. + + [ Other Info ] + + * Affected/target series: + - Jammy 22.04 LTS - SRU (glibc 2.35-0ubuntu3.14 -> 2.35-0ubuntu3.15) + - Noble 24.04 LTS - SRU (glibc 2.39-0ubuntu8.8 -> 2.39-0ubuntu8.9) + + * Focal 20.04 LTS is out of standard support and will not receive this + fix (task marked Won't Fix). + + * Upstream fix (single commit, applies verbatim to both series): + 9b7651410375ec8848a1944992d663d514db4ba7 + "s390x: Fix segfault in wcsncmp [BZ #31934]" + Stable-branch cherry-picks (context-identical to the above, differing + only by the "(cherry picked from ...)" trailer): + - 2.39 (noble): 5c46e6b66636be0010e9a732d5ba1e65ebd54687 + - 2.35 (jammy): c7cd62653850135bc880688a78104dbf77cf8121 + + * PPA test builds are available here: + https://launchpad.net/~fheimes/+archive/ubuntu/lp2073372 + __________ + The >=z13 wcsncmp implementation segfaults if n=1 and there is only one character (equal on both strings) before the page end. Then it loads and compares one character and misses to check n again. The following load fails. This issue was reported here: Bug 31934 - wcsncmp crash on s390x on vlbb instruction https://sourceware.org/bugzilla/show_bug.cgi?id=31934 And fixed upstream (first in glibc 2.40): s390x: Fix segfault in wcsncmp [BZ #31934] https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=9b7651410375ec8848a1944992d663d514db4ba7 This Fix was cherry-picked to the current branches glibc 2.32-39: - 2.39: commit 5c46e6b66636be0010e9a732d5ba1e65ebd54687 - 2.38: commit 712453634c8efd71a9b3ff0122145a9e90e9955c - 2.37: commit 340ca2d5148371614c234068f430c19293f962dc - 2.36: commit a70c55a91b2b361f43e4142aadf86f22af57d406 - 2.35: commit c7cd62653850135bc880688a78104dbf77cf8121 - 2.34: commit 87fa7bfb84895bb517beb8aaf92bd45b829daabb - 2.33: commit 5f08d1df2c07904c1dc98bdf2b363c65874266f7 - 2.32: commit 5ad449c398a845a9c84808e4ac603beaa1006909 In case somebody needs the fix for older glibc releases (issue was introduced with glibc 2.23), feel free to just cherry-pick it. Note, that the file was moved from sysdeps/s390/multiarch/wcsncmp-vx.S to sysdeps/s390/wcsncmp-vx.S with commit e9873e1d47c870d707117ada91c9be21e3bf1537 (in glibc 2.29), but the implementation does not differ.
-- You received this bug notification because you are a member of Ubuntu Bugs, which is subscribed to Ubuntu. https://bugs.launchpad.net/bugs/2073372 Title: [UBUNTU 20.04] s390x: z13 wcsncmp implementation segfaults if n=1 To manage notifications about this bug go to: https://bugs.launchpad.net/ubuntu-z-systems/+bug/2073372/+subscriptions -- ubuntu-bugs mailing list [email protected] https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs
