diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 01e6d49a51c72..f9f746188f239 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -455,10 +455,11 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { let mut visible_parent_map: DefIdMap = Default::default(); // This is a secondary visible_parent_map, storing the DefId of - // parents that re-export the child as `_` or module parents - // which are `#[doc(hidden)]`. Since we prefer paths that don't - // do this, merge this map at the end, only if we're missing - // keys from the former. + // parents that re-export the child as `_`, module parents + // which are `#[doc(hidden)]`, or `use` items that are themselves + // `#[doc(hidden)]`. Since we prefer paths that don't do this, + // merge this map at the end, only if we're missing keys from + // the former. // This is a rudimentary check that does not catch all cases, // just the easiest. let mut fallback_map: Vec<(DefId, DefId)> = Default::default(); @@ -500,6 +501,18 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { return; } + // If the re-export itself is `#[doc(hidden)]`, deprioritize it. + // See PR #99698 for the case where the *parent* is doc-hidden. + if child + .reexport_chain + .first() + .and_then(|r| r.id()) + .is_some_and(|id| tcx.is_doc_hidden(id)) + { + fallback_map.push((def_id, parent)); + return; + } + match visible_parent_map.entry(def_id) { Entry::Occupied(mut entry) => { // If `child` is defined in crate `cnum`, ensure diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 8bf919dab8e79..72787c841204b 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -943,6 +943,10 @@ fn should_encode_attrs(def_kind: DefKind) -> bool { | DefKind::Macro(_) | DefKind::Field | DefKind::Impl { .. } => true, + // Encoding attrs for `Use` items allows `#[doc(hidden)]` on re-exports + // to be read cross-crate, which is needed for diagnostic path selection + // in `visible_parent_map`. See #153477. + DefKind::Use => true, // Tools may want to be able to detect their tool lints on // closures from upstream crates, too. This is used by // https://github.com/model-checking/kani and is not a performance @@ -953,7 +957,6 @@ fn should_encode_attrs(def_kind: DefKind) -> bool { | DefKind::ConstParam | DefKind::Ctor(..) | DefKind::ExternCrate - | DefKind::Use | DefKind::ForeignMod | DefKind::AnonConst | DefKind::InlineConst diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index b15712d3599c6..f532e8f116f05 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -134,7 +134,8 @@ impl const ops::FromResidual> for Cont } #[unstable(feature = "try_trait_v2_residual", issue = "91285")] -impl ops::Residual for ControlFlow { +#[rustc_const_unstable(feature = "const_try_residual", issue = "91285")] +impl const ops::Residual for ControlFlow { type TryType = ControlFlow; } diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index dc0d11b07a9f3..26f80fd90159d 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -2042,10 +2042,19 @@ mod type_keyword {} /// system. /// /// The `unsafe` keyword has two uses: -/// - to declare the existence of contracts the compiler can't check (`unsafe fn` and `unsafe -/// trait`), -/// - and to declare that a programmer has checked that these contracts have been upheld (`unsafe -/// {}` and `unsafe impl`, but also `unsafe fn` -- see below). +/// - to declare the existence of contracts the compiler can't check, +/// - and to declare that a programmer has checked that these contracts have been upheld. +/// +/// Typically, each `unsafe` is either of the first or second kind: `unsafe fn` and `unsafe trait` +/// declare the existence of an unsafe contract; `unsafe {}` and `unsafe impl` declare that an +/// unsafe contract (which must have been declared elsewhere) is being upheld. +/// +/// However, historically, these two are not mutually exclusive: the body of an `unsafe fn` is, on +/// old editions, treated like an unsafe block, which means that this use of `unsafe` both declares +/// the existence of a contract to call the current function, and declares that the contracts of the +/// unsafe operations inside this function are being upheld. The `unsafe_op_in_unsafe_fn` lint can +/// be enabled to change that and make `unsafe fn` only play the former role. That lint is enabled +/// by default since edition 2024. /// /// # Unsafe abilities /// @@ -2088,6 +2097,13 @@ mod type_keyword {} /// - `unsafe impl`: the contract necessary to implement the trait has been /// checked by the programmer and is guaranteed to be respected. /// +/// On old editions, `unsafe fn` also acts like an `unsafe {}` block around the code inside the +/// function. This means it is not just a signal to the caller, but also promises that the +/// preconditions for the operations inside the function are upheld. Mixing these two meanings can +/// be confusing, so the `unsafe_op_in_unsafe_fn` lint has been introduced and enabled by default +/// since edition 2024 to warn against that and require explicit unsafe blocks even inside `unsafe +/// fn`. +/// /// See the [Rustonomicon] and the [Reference] for more information. /// /// # Examples diff --git a/src/ci/docker/host-x86_64/dist-arm-linux-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-arm-linux-musl/Dockerfile index 99667d68ab7ad..a34b97d9b3b7a 100644 --- a/src/ci/docker/host-x86_64/dist-arm-linux-musl/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-arm-linux-musl/Dockerfile @@ -6,6 +6,8 @@ RUN sh /scripts/cross-apt-packages.sh WORKDIR /build COPY scripts/musl-toolchain.sh /build/ +COPY scripts/musl-cve-2026-6042.diff /build/ +COPY scripts/musl-cve-2026-40200.diff /build/ # We need to mitigate rust-lang/rust#34978 when compiling musl itself as well RUN CFLAGS="-Wa,--compress-debug-sections=none -Wl,--compress-debug-sections=none" \ CXXFLAGS="-Wa,--compress-debug-sections=none -Wl,--compress-debug-sections=none" \ diff --git a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile index 31d009b6969a0..cf8ff07a5b07f 100644 --- a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile @@ -39,6 +39,8 @@ ENV \ WORKDIR /build/ COPY scripts/musl.sh /build/ +COPY scripts/musl-cve-2026-6042.diff /build/ +COPY scripts/musl-cve-2026-40200.diff /build/ RUN CC=gcc CFLAGS="-m32 -Wa,-mrelax-relocations=no" \ CXX=g++ CXXFLAGS="-m32 -Wa,-mrelax-relocations=no" \ bash musl.sh i686 --target=i686 && \ diff --git a/src/ci/docker/host-x86_64/dist-various-1/Dockerfile b/src/ci/docker/host-x86_64/dist-various-1/Dockerfile index ff80d0e3c2960..33b48de872711 100644 --- a/src/ci/docker/host-x86_64/dist-various-1/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-1/Dockerfile @@ -65,6 +65,8 @@ ENV PATH="/build/emsdk:/build/emsdk/upstream/emscripten:/build/emsdk/node/curren ENV STAGING_DIR=/tmp COPY scripts/musl.sh /build +COPY scripts/musl-cve-2026-6042.diff /build/ +COPY scripts/musl-cve-2026-40200.diff /build/ RUN env \ CC=arm-linux-gnueabi-gcc CFLAGS="-march=armv5te -marm -mfloat-abi=soft" \ CXX=arm-linux-gnueabi-g++ CXXFLAGS="-march=armv5te -marm -mfloat-abi=soft" \ diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile index e248e1e44ca30..13d76c001a2f7 100644 --- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile @@ -68,6 +68,8 @@ ENV \ WORKDIR /build COPY scripts/musl.sh /build +COPY scripts/musl-cve-2026-6042.diff /build/ +COPY scripts/musl-cve-2026-40200.diff /build/ RUN env \ CC=arm-linux-gnueabi-gcc-9 CFLAGS="-march=armv7-a" \ CXX=arm-linux-gnueabi-g++-9 CXXFLAGS="-march=armv7-a" \ diff --git a/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile index 68f914a81552d..aaca6b2bb9afa 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile @@ -25,6 +25,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ WORKDIR /build/ COPY scripts/musl-toolchain.sh /build/ +COPY scripts/musl-cve-2026-6042.diff /build/ +COPY scripts/musl-cve-2026-40200.diff /build/ # We need to mitigate rust-lang/rust#34978 when compiling musl itself as well RUN CFLAGS="-Wa,-mrelax-relocations=no -Wa,--compress-debug-sections=none -Wl,--compress-debug-sections=none" \ CXXFLAGS="-Wa,-mrelax-relocations=no -Wa,--compress-debug-sections=none -Wl,--compress-debug-sections=none" \ diff --git a/src/ci/docker/host-x86_64/test-various/Dockerfile b/src/ci/docker/host-x86_64/test-various/Dockerfile index 10ea2646bf3b9..626929d6c19b8 100644 --- a/src/ci/docker/host-x86_64/test-various/Dockerfile +++ b/src/ci/docker/host-x86_64/test-various/Dockerfile @@ -35,6 +35,8 @@ ENV PATH="/node/bin:${PATH}" WORKDIR /build/ COPY scripts/musl-toolchain.sh /build/ +COPY scripts/musl-cve-2026-6042.diff /build/ +COPY scripts/musl-cve-2026-40200.diff /build/ RUN bash musl-toolchain.sh x86_64 && rm -rf build WORKDIR / diff --git a/src/ci/docker/scripts/musl-cve-2026-40200.diff b/src/ci/docker/scripts/musl-cve-2026-40200.diff new file mode 100644 index 0000000000000..88298ca471d38 --- /dev/null +++ b/src/ci/docker/scripts/musl-cve-2026-40200.diff @@ -0,0 +1,179 @@ +>From 228da39e38c1cae13cbe637e771412c1984dba5d Mon Sep 17 00:00:00 2001 +From: Rich Felker +Date: Thu, 9 Apr 2026 22:51:30 -0400 +Subject: [PATCH 1/3] qsort: fix leonardo heap corruption from bug in + doubleword ctz primitive + +the pntz function, implementing a "count trailing zeros" variant for a +bit vector consisting of two size_t words, erroneously returned zero +rather than the number of bits in the low word when the first bit set +was the low bit of the high word. + +as a result, a loop in the trinkle function which should have a +guaranteed small bound on the number of iterations, could run +unboundedly, thereby overflowing a stack-based working-space array +which was sized for the bound. + +CVE-2026-40200 has been assigned for this issue. +--- + src/stdlib/qsort.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/stdlib/qsort.c b/src/stdlib/qsort.c +index ab79dc6f..13219ab3 100644 +--- a/src/stdlib/qsort.c ++++ b/src/stdlib/qsort.c +@@ -34,11 +34,11 @@ + + typedef int (*cmpfun)(const void *, const void *, void *); + ++/* returns index of first bit set, excluding the low bit assumed to always ++ * be set, starting from low bit of p[0] up through high bit of p[1] */ + static inline int pntz(size_t p[2]) { +- int r = ntz(p[0] - 1); +- if(r != 0 || (r = 8*sizeof(size_t) + ntz(p[1])) != 8*sizeof(size_t)) { +- return r; +- } ++ if (p[0] != 1) return ntz(p[0] - 1); ++ if (p[1]) return 8*sizeof(size_t) + ntz(p[1]); + return 0; + } + +-- +2.21.0 + + +>From b3291b9a9f77f1f993d2b4f8c68a26cf09221ae7 Mon Sep 17 00:00:00 2001 +From: Rich Felker +Date: Thu, 9 Apr 2026 23:40:53 -0400 +Subject: [PATCH 2/3] qsort: hard-preclude oob array writes independent of any + invariants + +while the root cause of CVE-2026-40200 was a faulty ctz primitive, the +fallout of the bug would have been limited to erroneous sorting or +infinite loop if not for the stores to a stack-based array that +depended on trusting invariants in order not to go out of bounds. + +increase the size of the array to a power of two so that we can mask +indices into it to force them into range. in the absence of any +further bug, the masking is a no-op, but it does not have any +measurable performance cost, and it makes spatial memory safety +trivial to prove (and for readers not familiar with the algorithms to +trust). +--- + src/stdlib/qsort.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/src/stdlib/qsort.c b/src/stdlib/qsort.c +index 13219ab3..e4bce9f7 100644 +--- a/src/stdlib/qsort.c ++++ b/src/stdlib/qsort.c +@@ -89,10 +89,16 @@ static inline void shr(size_t p[2], int n) + p[1] >>= n; + } + ++/* power-of-two length for working array so that we can mask indices and ++ * not depend on any invariant of the algorithm for spatial memory safety. ++ * the original size was just 14*sizeof(size_t)+1 */ ++#define AR_LEN (16 * sizeof(size_t)) ++#define AR_MASK (AR_LEN - 1) ++ + static void sift(unsigned char *head, size_t width, cmpfun cmp, void *arg, int pshift, size_t lp[]) + { + unsigned char *rt, *lf; +- unsigned char *ar[14 * sizeof(size_t) + 1]; ++ unsigned char *ar[AR_LEN]; + int i = 1; + + ar[0] = head; +@@ -104,16 +110,16 @@ static void sift(unsigned char *head, size_t width, cmpfun cmp, void *arg, int p + break; + } + if(cmp(lf, rt, arg) >= 0) { +- ar[i++] = lf; ++ ar[i++ & AR_MASK] = lf; + head = lf; + pshift -= 1; + } else { +- ar[i++] = rt; ++ ar[i++ & AR_MASK] = rt; + head = rt; + pshift -= 2; + } + } +- cycle(width, ar, i); ++ cycle(width, ar, i & AR_MASK); + } + + static void trinkle(unsigned char *head, size_t width, cmpfun cmp, void *arg, size_t pp[2], int pshift, int trusty, size_t lp[]) +@@ -121,7 +127,7 @@ static void trinkle(unsigned char *head, size_t width, cmpfun cmp, void *arg, si + unsigned char *stepson, + *rt, *lf; + size_t p[2]; +- unsigned char *ar[14 * sizeof(size_t) + 1]; ++ unsigned char *ar[AR_LEN]; + int i = 1; + int trail; + +@@ -142,7 +148,7 @@ static void trinkle(unsigned char *head, size_t width, cmpfun cmp, void *arg, si + } + } + +- ar[i++] = stepson; ++ ar[i++ & AR_MASK] = stepson; + head = stepson; + trail = pntz(p); + shr(p, trail); +@@ -150,7 +156,7 @@ static void trinkle(unsigned char *head, size_t width, cmpfun cmp, void *arg, si + trusty = 0; + } + if(!trusty) { +- cycle(width, ar, i); ++ cycle(width, ar, i & AR_MASK); + sift(head, width, cmp, arg, pshift, lp); + } + } +-- +2.21.0 + + +>From 5122f9f3c99fee366167c5de98b31546312921ab Mon Sep 17 00:00:00 2001 +From: Luca Kellermann +Date: Fri, 10 Apr 2026 03:03:22 +0200 +Subject: [PATCH 3/3] qsort: fix shift UB in shl and shr + +if shl() or shr() are called with n==8*sizeof(size_t), n is adjusted +to 0. the shift by (sizeof(size_t) * 8 - n) that then follows will +consequently shift by the width of size_t, which is UB and in practice +produces an incorrect result. + +return early in this case. the bitvector p was already shifted by the +required amount. +--- + src/stdlib/qsort.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/stdlib/qsort.c b/src/stdlib/qsort.c +index e4bce9f7..28607450 100644 +--- a/src/stdlib/qsort.c ++++ b/src/stdlib/qsort.c +@@ -71,6 +71,7 @@ static inline void shl(size_t p[2], int n) + n -= 8 * sizeof(size_t); + p[1] = p[0]; + p[0] = 0; ++ if (!n) return; + } + p[1] <<= n; + p[1] |= p[0] >> (sizeof(size_t) * 8 - n); +@@ -83,6 +84,7 @@ static inline void shr(size_t p[2], int n) + n -= 8 * sizeof(size_t); + p[0] = p[1]; + p[1] = 0; ++ if (!n) return; + } + p[0] >>= n; + p[0] |= p[1] << (sizeof(size_t) * 8 - n); +-- +2.21.0 + + diff --git a/src/ci/docker/scripts/musl-cve-2026-6042.diff b/src/ci/docker/scripts/musl-cve-2026-6042.diff new file mode 100644 index 0000000000000..9b39420ea3c51 --- /dev/null +++ b/src/ci/docker/scripts/musl-cve-2026-6042.diff @@ -0,0 +1,321 @@ +>From 67219f0130ec7c876ac0b299046460fad31caabf Mon Sep 17 00:00:00 2001 +From: Rich Felker +Date: Mon, 30 Mar 2026 16:00:50 -0400 +Subject: [PATCH] fix pathological slowness & incorrect mappings in iconv + gb18030 decoder + +in order to implement the "UTF" aspect of gb18030 (ability to +represent arbitrary unicode characters not present in the 2-byte +mapping), we have to apply the index obtained from the encoded 4-byte +sequence into the set of unmapped characters. this was done by +scanning repeatedly over the table of mapped characters and counting +off mapped characters below a running index by which to adjust the +running index by on each iteration. this iterative process eventually +leaves us with the value of the Nth unmapped character replacing the +index, but depending on which particular character that is, the number +of iterations needed to find it can be in the tens of thousands, and +each iteration traverses the whole 126x190 table in the inner loop. +this can lead to run times exceeding an entire second per character on +moderate-speed machines. + +on top of that, the transformation logic produced wrong results for +BMP characters above the the surrogate range, as a result of not +correctly accounting for it being excluded, and for characters outside +the BMP, as a result of a misunderstanding of how gb18030 encodes +them. + +this patch replaces the unmapped character lookup with a single linear +search of a list of unmapped ranges. there are only 206 such ranges, +and these are permanently assigned and unchangeable as a consequence +of the character encoding having to be stable, so a simple array of +16-bit start/length values for each range consumes only 824 bytes, a +very reasonable size cost here. + +this new table accounts for the previously-incorrect surrogate +handling, and non-BMP characters are handled correctly by a single +offset, without the need for any unmapped-range search. + +there are still a small number of mappings that are incorrect due to +late changes made in the definition of gb18030, swapping PUA +codepoints with proper Unicode characters. correcting these requires a +postprocessing step that will be added later. +--- + src/locale/gb18030utf.h | 206 ++++++++++++++++++++++++++++++++++++++++ + src/locale/iconv.c | 33 +++++-- + 2 files changed, 230 insertions(+), 9 deletions(-) + create mode 100644 src/locale/gb18030utf.h + +diff --git a/src/locale/gb18030utf.h b/src/locale/gb18030utf.h +new file mode 100644 +index 00000000..322a2440 +--- /dev/null ++++ b/src/locale/gb18030utf.h +@@ -0,0 +1,206 @@ ++{ 0x80, 36 }, ++{ 0xa5, 2 }, ++{ 0xa9, 7 }, ++{ 0xb2, 5 }, ++{ 0xb8, 31 }, ++{ 0xd8, 8 }, ++{ 0xe2, 6 }, ++{ 0xeb, 1 }, ++{ 0xee, 4 }, ++{ 0xf4, 3 }, ++{ 0xf8, 1 }, ++{ 0xfb, 1 }, ++{ 0xfd, 4 }, ++{ 0x102, 17 }, ++{ 0x114, 7 }, ++{ 0x11c, 15 }, ++{ 0x12c, 24 }, ++{ 0x145, 3 }, ++{ 0x149, 4 }, ++{ 0x14e, 29 }, ++{ 0x16c, 98 }, ++{ 0x1cf, 1 }, ++{ 0x1d1, 1 }, ++{ 0x1d3, 1 }, ++{ 0x1d5, 1 }, ++{ 0x1d7, 1 }, ++{ 0x1d9, 1 }, ++{ 0x1db, 1 }, ++{ 0x1dd, 28 }, ++{ 0x1fa, 87 }, ++{ 0x252, 15 }, ++{ 0x262, 101 }, ++{ 0x2c8, 1 }, ++{ 0x2cc, 13 }, ++{ 0x2da, 183 }, ++{ 0x3a2, 1 }, ++{ 0x3aa, 7 }, ++{ 0x3c2, 1 }, ++{ 0x3ca, 55 }, ++{ 0x402, 14 }, ++{ 0x450, 1 }, ++{ 0x452, 7102 }, ++{ 0x2011, 2 }, ++{ 0x2017, 1 }, ++{ 0x201a, 2 }, ++{ 0x201e, 7 }, ++{ 0x2027, 9 }, ++{ 0x2031, 1 }, ++{ 0x2034, 1 }, ++{ 0x2036, 5 }, ++{ 0x203c, 112 }, ++{ 0x20ad, 86 }, ++{ 0x2104, 1 }, ++{ 0x2106, 3 }, ++{ 0x210a, 12 }, ++{ 0x2117, 10 }, ++{ 0x2122, 62 }, ++{ 0x216c, 4 }, ++{ 0x217a, 22 }, ++{ 0x2194, 2 }, ++{ 0x219a, 110 }, ++{ 0x2209, 6 }, ++{ 0x2210, 1 }, ++{ 0x2212, 3 }, ++{ 0x2216, 4 }, ++{ 0x221b, 2 }, ++{ 0x2221, 2 }, ++{ 0x2224, 1 }, ++{ 0x2226, 1 }, ++{ 0x222c, 2 }, ++{ 0x222f, 5 }, ++{ 0x2238, 5 }, ++{ 0x223e, 10 }, ++{ 0x2249, 3 }, ++{ 0x224d, 5 }, ++{ 0x2253, 13 }, ++{ 0x2262, 2 }, ++{ 0x2268, 6 }, ++{ 0x2270, 37 }, ++{ 0x2296, 3 }, ++{ 0x229a, 11 }, ++{ 0x22a6, 25 }, ++{ 0x22c0, 82 }, ++{ 0x2313, 333 }, ++{ 0x246a, 10 }, ++{ 0x249c, 100 }, ++{ 0x254c, 4 }, ++{ 0x2574, 13 }, ++{ 0x2590, 3 }, ++{ 0x2596, 10 }, ++{ 0x25a2, 16 }, ++{ 0x25b4, 8 }, ++{ 0x25be, 8 }, ++{ 0x25c8, 3 }, ++{ 0x25cc, 2 }, ++{ 0x25d0, 18 }, ++{ 0x25e6, 31 }, ++{ 0x2607, 2 }, ++{ 0x260a, 54 }, ++{ 0x2641, 1 }, ++{ 0x2643, 2110 }, ++{ 0x2e82, 2 }, ++{ 0x2e85, 3 }, ++{ 0x2e89, 2 }, ++{ 0x2e8d, 10 }, ++{ 0x2e98, 15 }, ++{ 0x2ea8, 2 }, ++{ 0x2eab, 3 }, ++{ 0x2eaf, 4 }, ++{ 0x2eb4, 2 }, ++{ 0x2eb8, 3 }, ++{ 0x2ebc, 14 }, ++{ 0x2ecb, 293 }, ++{ 0x2ffc, 4 }, ++{ 0x3004, 1 }, ++{ 0x3018, 5 }, ++{ 0x301f, 2 }, ++{ 0x302a, 20 }, ++{ 0x303f, 2 }, ++{ 0x3094, 7 }, ++{ 0x309f, 2 }, ++{ 0x30f7, 5 }, ++{ 0x30ff, 6 }, ++{ 0x312a, 246 }, ++{ 0x322a, 7 }, ++{ 0x3232, 113 }, ++{ 0x32a4, 234 }, ++{ 0x3390, 12 }, ++{ 0x339f, 2 }, ++{ 0x33a2, 34 }, ++{ 0x33c5, 9 }, ++{ 0x33cf, 2 }, ++{ 0x33d3, 2 }, ++{ 0x33d6, 113 }, ++{ 0x3448, 43 }, ++{ 0x3474, 298 }, ++{ 0x359f, 111 }, ++{ 0x360f, 11 }, ++{ 0x361b, 765 }, ++{ 0x3919, 85 }, ++{ 0x396f, 96 }, ++{ 0x39d1, 14 }, ++{ 0x39e0, 147 }, ++{ 0x3a74, 218 }, ++{ 0x3b4f, 287 }, ++{ 0x3c6f, 113 }, ++{ 0x3ce1, 885 }, ++{ 0x4057, 264 }, ++{ 0x4160, 471 }, ++{ 0x4338, 116 }, ++{ 0x43ad, 4 }, ++{ 0x43b2, 43 }, ++{ 0x43de, 248 }, ++{ 0x44d7, 373 }, ++{ 0x464d, 20 }, ++{ 0x4662, 193 }, ++{ 0x4724, 5 }, ++{ 0x472a, 82 }, ++{ 0x477d, 16 }, ++{ 0x478e, 441 }, ++{ 0x4948, 50 }, ++{ 0x497b, 2 }, ++{ 0x497e, 4 }, ++{ 0x4984, 1 }, ++{ 0x4987, 20 }, ++{ 0x499c, 3 }, ++{ 0x49a0, 22 }, ++{ 0x49b8, 703 }, ++{ 0x4c78, 39 }, ++{ 0x4ca4, 111 }, ++{ 0x4d1a, 148 }, ++{ 0x4daf, 81 }, ++{ 0x9fa6, 14426 }, ++{ 0xe76c, 1 }, ++{ 0xe7c8, 1 }, ++{ 0xe7e7, 13 }, ++{ 0xe815, 1 }, ++{ 0xe819, 5 }, ++{ 0xe81f, 7 }, ++{ 0xe827, 4 }, ++{ 0xe82d, 4 }, ++{ 0xe833, 8 }, ++{ 0xe83c, 7 }, ++{ 0xe844, 16 }, ++{ 0xe856, 14 }, ++{ 0xe865, 4295 }, ++{ 0xf92d, 76 }, ++{ 0xf97a, 27 }, ++{ 0xf996, 81 }, ++{ 0xf9e8, 9 }, ++{ 0xf9f2, 26 }, ++{ 0xfa10, 1 }, ++{ 0xfa12, 1 }, ++{ 0xfa15, 3 }, ++{ 0xfa19, 6 }, ++{ 0xfa22, 1 }, ++{ 0xfa25, 2 }, ++{ 0xfa2a, 1030 }, ++{ 0xfe32, 1 }, ++{ 0xfe45, 4 }, ++{ 0xfe53, 1 }, ++{ 0xfe58, 1 }, ++{ 0xfe67, 1 }, ++{ 0xfe6c, 149 }, ++{ 0xff5f, 129 }, ++{ 0xffe6, 26 }, +diff --git a/src/locale/iconv.c b/src/locale/iconv.c +index 52178950..4151411d 100644 +--- a/src/locale/iconv.c ++++ b/src/locale/iconv.c +@@ -74,6 +74,10 @@ static const unsigned short gb18030[126][190] = { + #include "gb18030.h" + }; + ++static const unsigned short gb18030utf[][2] = { ++#include "gb18030utf.h" ++}; ++ + static const unsigned short big5[89][157] = { + #include "big5.h" + }; +@@ -224,6 +228,8 @@ static unsigned uni_to_jis(unsigned c) + } + } + ++#define countof(a) (sizeof (a) / sizeof *(a)) ++ + size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restrict out, size_t *restrict outb) + { + size_t x=0; +@@ -430,15 +436,24 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri + d = *((unsigned char *)*in + 3); + if (d-'0'>9) goto ilseq; + c += d-'0'; +- c += 128; +- for (d=0; d<=c; ) { +- k = 0; +- for (int i=0; i<126; i++) +- for (int j=0; j<190; j++) +- if (gb18030[i][j]-d <= c-d) +- k++; +- d = c+1; +- c += k; ++ /* Starting at 90 30 81 30 (189000), mapping is ++ * linear without gaps, to U+10000 and up. */ ++ if (c >= 189000) { ++ c -= 189000; ++ c += 0x10000; ++ if (c >= 0x110000) goto ilseq; ++ break; ++ } ++ /* Otherwise we must process an index into set ++ * of characters unmapped by 2-byte table. */ ++ for (int i=0; ; i++) { ++ if (i==countof(gb18030utf)) ++ goto ilseq; ++ if (c= 1.2.7. +cp /build/musl-cve-2026-6042.diff ./patches/musl-1.2.5/0003-cve-2026-6042.diff +cp /build/musl-cve-2026-40200.diff ./patches/musl-1.2.5/0004-cve-2026-40200.diff + hide_output make -j$(nproc) TARGET=$TARGET MUSL_VER=1.2.5 LINUX_HEADERS_SITE=$LINUX_HEADERS_SITE LINUX_VER=$LINUX_VER hide_output make install TARGET=$TARGET MUSL_VER=1.2.5 LINUX_HEADERS_SITE=$LINUX_HEADERS_SITE LINUX_VER=$LINUX_VER OUTPUT=$OUTPUT diff --git a/src/ci/docker/scripts/musl.sh b/src/ci/docker/scripts/musl.sh index 7e293d748ce16..7258d3935e0f6 100644 --- a/src/ci/docker/scripts/musl.sh +++ b/src/ci/docker/scripts/musl.sh @@ -71,6 +71,19 @@ EOF *outb -= k; break; EOF + + # Apply patches for CVE-2026-6042 and CVE-2026-40200. + # + # At the time of adding these patches no release containing them has been published by the musl + # project, so we just apply them directly on top of the version we were distributing already. The + # patches should be removed once we upgrade to musl >= 1.2.7. + # + # Advisory: https://www.openwall.com/lists/oss-security/2026/04/09/19 + # Patches: https://www.openwall.com/lists/musl/2026/04/03/2/1 + patch -p1 -d $MUSL $DIR/hidden-child.rs:9:26 + --> $DIR/hidden-child.rs:11:26 | LL | let x: Option = 1i32; | ----------- ^^^^ expected `Option`, found `i32` @@ -8,10 +8,10 @@ LL | let x: Option = 1i32; | = note: expected enum `Option` found type `i32` -help: try wrapping the expression in `hidden_child::__private::Some` +help: try wrapping the expression in `Some` | -LL | let x: Option = hidden_child::__private::Some(1i32); - | ++++++++++++++++++++++++++++++ + +LL | let x: Option = Some(1i32); + | +++++ + error: aborting due to 1 previous error