From ab06327b134503a2590f42bb9e788013d05505aa Mon Sep 17 00:00:00 2001 From: Hannu Nyman Date: Thu, 21 May 2026 16:07:31 +0300 Subject: [PATCH] musl: update to 1.2.6 Update musl C library to 1.2.6. Fixes CVE-2025-26519 * Patches refreshed. Unnecessary upstream patch removed. * Add a post-release patch for timezone handling in datetime string matching (affecting at least uhttpd): bug report: https://www.openwall.com/lists/musl/2026/03/22/3 fix: https://www.openwall.com/lists/musl/2026/03/30/6 1.2.6 release notes https://git.musl-libc.org/cgit/musl/tree/WHATSNEW?id=9fa28ece75d8a2191de7c5bb53bed224c5947417 new features: - posix_getdents interface (new in POSIX-2024) - renameat2 interface (linux extension) - iconv support for CP858 - vdso clock_gettime for riscv{32,64}, powerpc{,64}, and s390x - loongarch64 TLSDESC support - exposed __getauxval for compiler runtime use detecting cpu features compatibility: - initgroups no longer artificially limits number of supplementary groups - getusershell now skips blank lines and comments - exit is now explicitly thread-safe (possible future requirement) - atexit now fails rather than deadlocking if called from late dtor - strerror now has error strings for EUCLEAN and ENAVAIL - isatty no longer collapses errors to ENOTTY - sched.h namespace pollution with _GNU_SOURCE is reduced - hasmntopt now matches only whole options, not arbitrary substrings - shadow.h no longer declares an unimplemented sgetspent interface - vdso with missing sysv hash table (only gnu hash) is now supported conformance: - pwrite now handles O_APPEND correctly, reports error if it can't - mbnrtowcs now conforms to new POSIX-2024 requirement for partial character - iconv GBK now properly includes euro symbol - strptime now accepts conversion specifiers added in POSIX-2024 - inet_ntop IPv6 "zero compression" now conforms to RFC 5952 bugs fixed: - iconv euc-kr decoder could do oob writes on invalid inputs (CVE-2025-26519) - iconv shift_jis decoder could produce wrong outputs for some invalid inputs - printf did not honor hex float precision correctly in some cases - lost or delayed wakes in sem_post under race condition - termios input speed handling was wrong - strcasestr failed to match zero-length needle - fma handled corner case with negative zero wrongly - syslog LOG_MAKEPRI macro was incorrect - timer_create is no longer affected by known pthread_barrier bugs - sysconf(_SC_MINSIGSTKSZ) computed min size incorrectly - statx emulation left some fields uninitialized - mntent wrongly included final newline in parsed field output - SIGEV_THREAD timers could abort process if SIGTIMER became unblocked - bind_textdomain_codeset returned wrong value arch-specific bugs fixed: - early dynamic linker handled page size wrong on dynamic pagesize archs - arm and aarch64 crti/n files had wrong alignment - m68k POLLWRNORM and POLLWRBAND values were incorrect - x32 mq ABI was mismatched Signed-off-by: Hannu Nyman Link: https://github.com/openwrt/openwrt/pull/22547 Signed-off-by: Hauke Mehrtens --- toolchain/musl/common.mk | 4 +- ...cess-to-tzname-by-strptime-Z-convers.patch | 99 +++++++++++++++++++ ...-slowness-incorrect-mappings-in-icon.patch | 2 +- .../patches/110-read_timezone_from_fs.patch | 4 +- ...-add-renameat2-linux-syscall-wrapper.patch | 61 ------------ .../musl/patches/900-iconv_size_hack.patch | 6 +- 6 files changed, 107 insertions(+), 69 deletions(-) create mode 100644 toolchain/musl/patches/001-fix-1.2.6-incorrect-access-to-tzname-by-strptime-Z-convers.patch delete mode 100644 toolchain/musl/patches/610-add-renameat2-linux-syscall-wrapper.patch diff --git a/toolchain/musl/common.mk b/toolchain/musl/common.mk index 35bdfd184be..10bd51768e4 100644 --- a/toolchain/musl/common.mk +++ b/toolchain/musl/common.mk @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/target.mk PKG_NAME:=musl -PKG_VERSION:=1.2.5 +PKG_VERSION:=1.2.6 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://musl.libc.org/releases/ -PKG_HASH:=a9a118bbe84d8764da0ea0d28b3ab3fae8477fc7e4085d90102b8596fc7c75e4 +PKG_HASH:=d585fd3b613c66151fc3249e8ed44f77020cb5e6c1e635a616d3f9f82460512a PKG_CPE_ID:=cpe:/a:musl-libc:musl LIBC_SO_VERSION:=$(PKG_VERSION) diff --git a/toolchain/musl/patches/001-fix-1.2.6-incorrect-access-to-tzname-by-strptime-Z-convers.patch b/toolchain/musl/patches/001-fix-1.2.6-incorrect-access-to-tzname-by-strptime-Z-convers.patch new file mode 100644 index 00000000000..6ed5b0299f9 --- /dev/null +++ b/toolchain/musl/patches/001-fix-1.2.6-incorrect-access-to-tzname-by-strptime-Z-convers.patch @@ -0,0 +1,99 @@ +From 0572555dab1d1e10b5f7351a005ec588cab41e25 Mon Sep 17 00:00:00 2001 +From: Rich Felker +Date: Sun, 22 Mar 2026 21:32:35 -0400 +Subject: [PATCH] fix incorrect access to tzname[] by strptime %Z conversion + specifier + +there are three issues here: + +1. if tzset has not been called (explicitly or implicitly), the +tzname[] array will contain null pointers, and the dereference to +compare against them has undefined behavior (and will fault). + +2. access to tzname[] was performed without the timezone lock held. +this resulted in a data race if the timezone is concurrently changed +from another thread. + +3. due to unintended signedness of the types, the open-coded isalpha +in the non-matching case was wrong and would continue past null +termination. + +to fix the first two issues, the body of the %Z conversion is moved to +__tz.c where it has access to locking, and null checks are added. + +there is probably an argument to be made that the equivalent of tzset +should happen here, but POSIX does not specify that to happen, so in +the absence of an interpretation adding such an allowance or +requirement, it is not done. + +the third issue is fixed just by using the existing isalpha macro. +--- + src/time/__tz.c | 19 +++++++++++++++++++ + src/time/strptime.c | 13 +++---------- + src/time/time_impl.h | 1 + + 3 files changed, 23 insertions(+), 10 deletions(-) + +--- a/src/time/__tz.c ++++ b/src/time/__tz.c +@@ -436,3 +436,22 @@ const char *__tm_to_tzname(const struct + UNLOCK(lock); + return p; + } ++ ++int __tzname_to_isdst(const char *restrict *s) ++{ ++ size_t len; ++ int isdst = -1; ++ LOCK(lock); ++ if (tzname[0] && !strncmp(*s, tzname[0], len = strlen(tzname[0]))) { ++ isdst = 0; ++ *s += len; ++ } else if (tzname[1] && !strncmp(*s, tzname[1], len=strlen(tzname[1]))) { ++ isdst = 1; ++ *s += len; ++ } else { ++ /* FIXME: is this supposed to be an error? */ ++ while (isalpha(**s)) ++*s; ++ } ++ UNLOCK(lock); ++ return isdst; ++} +--- a/src/time/strptime.c ++++ b/src/time/strptime.c +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include "time_impl.h" + + char *strptime(const char *restrict s, const char *restrict f, struct tm *restrict tm) + { +@@ -207,16 +208,8 @@ char *strptime(const char *restrict s, c + s += 5; + break; + case 'Z': +- if (!strncmp(s, tzname[0], len = strlen(tzname[0]))) { +- tm->tm_isdst = 0; +- s += len; +- } else if (!strncmp(s, tzname[1], len=strlen(tzname[1]))) { +- tm->tm_isdst = 1; +- s += len; +- } else { +- /* FIXME: is this supposed to be an error? */ +- while ((*s|32)-'a' <= 'z'-'a') s++; +- } ++ i = __tzname_to_isdst(&s); ++ if (i>=0) tm->tm_isdst = i; + break; + case '%': + if (*s++ != '%') return 0; +--- a/src/time/time_impl.h ++++ b/src/time/time_impl.h +@@ -5,6 +5,7 @@ hidden int __month_to_secs(int, int); + hidden long long __year_to_secs(long long, int *); + hidden long long __tm_to_secs(const struct tm *); + hidden const char *__tm_to_tzname(const struct tm *); ++hidden int __tzname_to_isdst(const char *restrict *); + hidden int __secs_to_tm(long long, struct tm *); + hidden void __secs_to_zone(long long, int, int *, long *, long *, const char **); + hidden const char *__strftime_fmt_1(char (*)[100], size_t *, int, const struct tm *, locale_t, int); diff --git a/toolchain/musl/patches/003-fix-pathological-slowness-incorrect-mappings-in-icon.patch b/toolchain/musl/patches/003-fix-pathological-slowness-incorrect-mappings-in-icon.patch index 11dc0464d58..a14765cef9e 100644 --- a/toolchain/musl/patches/003-fix-pathological-slowness-incorrect-mappings-in-icon.patch +++ b/toolchain/musl/patches/003-fix-pathological-slowness-incorrect-mappings-in-icon.patch @@ -276,7 +276,7 @@ postprocessing step that will be added later. size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restrict out, size_t *restrict outb) { size_t x=0; -@@ -423,15 +429,24 @@ size_t iconv(iconv_t cd, char **restrict +@@ -430,15 +436,24 @@ size_t iconv(iconv_t cd, char **restrict d = *((unsigned char *)*in + 3); if (d-'0'>9) goto ilseq; c += d-'0'; diff --git a/toolchain/musl/patches/110-read_timezone_from_fs.patch b/toolchain/musl/patches/110-read_timezone_from_fs.patch index e1d0f3ac7a4..a1f54db5519 100644 --- a/toolchain/musl/patches/110-read_timezone_from_fs.patch +++ b/toolchain/musl/patches/110-read_timezone_from_fs.patch @@ -1,6 +1,6 @@ --- a/src/time/__tz.c +++ b/src/time/__tz.c -@@ -32,6 +32,9 @@ static int r0[5], r1[5]; +@@ -31,6 +31,9 @@ static int r0[5], r1[5]; static const unsigned char *zi, *trans, *index, *types, *abbrevs, *abbrevs_end; static size_t map_size; @@ -10,7 +10,7 @@ static char old_tz_buf[32]; static char *old_tz = old_tz_buf; static size_t old_tz_size = sizeof old_tz_buf; -@@ -133,6 +136,15 @@ static void do_tzset() +@@ -132,6 +135,15 @@ static void do_tzset() "/usr/share/zoneinfo/\0/share/zoneinfo/\0/etc/zoneinfo/\0"; s = getenv("TZ"); diff --git a/toolchain/musl/patches/610-add-renameat2-linux-syscall-wrapper.patch b/toolchain/musl/patches/610-add-renameat2-linux-syscall-wrapper.patch deleted file mode 100644 index 167769360e3..00000000000 --- a/toolchain/musl/patches/610-add-renameat2-linux-syscall-wrapper.patch +++ /dev/null @@ -1,61 +0,0 @@ -From dc651fe2e6b16087c519c0bd0bf943cb7c53c807 Mon Sep 17 00:00:00 2001 -In-Reply-To: <20240423234355.2414567-1-Tony.Ambardar@gmail.com> -References: <20240423234355.2414567-1-Tony.Ambardar@gmail.com> -From: Tony Ambardar -Date: Sat, 20 Apr 2024 21:30:13 -0700 -Subject: [PATCH v3] add renameat2 linux syscall wrapper -To: musl@lists.openwall.com -Cc: Rich Felker - -This syscall is available since Linux 3.15 and also implemented in glibc -from version 2.28. It is commonly used in filesystem or security contexts. - -Constants RENAME_NOREPLACE, RENAME_EXCHANGE, RENAME_WHITEOUT are guarded by -_GNU_SOURCE as with glibc. - -Signed-off-by: Tony Ambardar ---- -v2 -> v3: - * call SYS_renameat first if applicable - * drop unneeded error code handling - -v1 -> v2: - * align related constants - * drop 'int' from 'unsigned int' - * add fallback to SYS_renameat where applicable ---- - include/stdio.h | 7 +++++++ - src/linux/renameat2.c | 11 +++++++++++ - 2 files changed, 18 insertions(+) - create mode 100644 src/linux/renameat2.c - ---- a/include/stdio.h -+++ b/include/stdio.h -@@ -158,6 +158,13 @@ char *ctermid(char *); - #define L_ctermid 20 - #endif - -+#if defined(_GNU_SOURCE) -+#define RENAME_NOREPLACE (1 << 0) -+#define RENAME_EXCHANGE (1 << 1) -+#define RENAME_WHITEOUT (1 << 2) -+ -+int renameat2(int, const char *, int, const char *, unsigned); -+#endif - - #if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \ - || defined(_BSD_SOURCE) ---- /dev/null -+++ b/src/linux/renameat2.c -@@ -0,0 +1,11 @@ -+#define _GNU_SOURCE -+#include -+#include "syscall.h" -+ -+int renameat2(int oldfd, const char *old, int newfd, const char *new, unsigned flags) -+{ -+#ifdef SYS_renameat -+ if (!flags) return syscall(SYS_renameat, oldfd, old, newfd, new); -+#endif -+ return syscall(SYS_renameat2, oldfd, old, newfd, new, flags); -+} diff --git a/toolchain/musl/patches/900-iconv_size_hack.patch b/toolchain/musl/patches/900-iconv_size_hack.patch index 8dc0471386c..b3085d45392 100644 --- a/toolchain/musl/patches/900-iconv_size_hack.patch +++ b/toolchain/musl/patches/900-iconv_size_hack.patch @@ -56,7 +56,7 @@ case SHIFT_JIS: if (c < 128) break; if (c-0xa1 <= 0xdf-0xa1) { -@@ -533,6 +540,7 @@ size_t iconv(iconv_t cd, char **restrict +@@ -540,6 +547,7 @@ size_t iconv(iconv_t cd, char **restrict c = ksc[c][d]; if (!c) goto ilseq; break; @@ -64,7 +64,7 @@ default: if (!c) break; c = legacy_map(map, c); -@@ -574,6 +582,7 @@ size_t iconv(iconv_t cd, char **restrict +@@ -585,6 +593,7 @@ size_t iconv(iconv_t cd, char **restrict } } goto subst; @@ -72,7 +72,7 @@ case SHIFT_JIS: if (c < 128) goto revout; if (c == 0xa5) { -@@ -647,6 +656,7 @@ size_t iconv(iconv_t cd, char **restrict +@@ -658,6 +667,7 @@ size_t iconv(iconv_t cd, char **restrict *(*out)++ = 'B'; *outb -= 8; break;