** 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

Reply via email to