package/libcurl: fix build on LoongArch with musl
PATCH 1/1 package/libcurl: fix build on LoongArch with musl
Since libcurl 8.21.0, building the curl tool for loongarch64 with a musl toolchain fails with:
ld: read-only segment has dynamic relocations
collect2: error: ld returned 1 exit status
On musl, none of the secure memory zeroing functions curl knows about are detected, so curlx_memzero_low() falls back to calling memset() through a 'const volatile' function pointer. In non-PIC code, GCC places this pointer in .rodata, and on LoongArch the linker emits a dynamic R_LARCH_64 relocation against memset() there, i.e. a text relocation. musl's dynamic loader does not support DT_TEXTREL, so the Buildroot toolchain wrapper links with -z text, which turns it into an error. Other architectures resolve the address to a PLT entry at link time and are not affected.
Add a patch, submitted upstream, that drops the 'const' qualifier, so that the pointer is placed in .data.
This issue has been present since commit be2789d08432 ("package/libcurl:
security bump to version 8.21.0"), which brought in the upstream code using the 'const volatile' pointer. It therefore affects 2026.08 and later, and 2026.05.x since 2026.05.1.
Fixes:
https://autobuild.buildroot.org/results/558c08d552920e45628254bdc029518120a35ae1
--- ...-relocation-in-curlx_memzero_low-fal.patch | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 package/libcurl/0001-curlx-avoid-text-relocation-in-curlx_memzero_low-fal.patch
package/libcurl/0001-curlx-avoid-text-relocation-in-curlx_memzero_low-fal.patch new file +41 -0
@@ -0,0 +1,41 @@ +From 8c05728ff2dfd5481379280ee7215518a2817725 Mon Sep 17 00:00:00 2001 +From: Yegor Yefremov <[email protected]> +Date: Mon, 9 Nov 2026 13:42:51 +0100 +Subject: [PATCH] curlx: avoid text relocation in curlx_memzero_low() fallback + +The const volatile function pointer is placed in .rodata in non-PIC +code. On LoongArch this needs a dynamic relocation for memset(), so +linking the curl tool against musl with -z text fails: + + ld: read-only segment has dynamic relocations + +Drop the const. volatile is enough to keep the call. + +Follow-up to 066478f6346a2d987a9ecc3bd3bf45764d69c1c4 #21598 + +Upstream: https://github.com/curl/curl/pull/23844 +Assisted-by: Claude:claude-opus-5-5 +Signed-off-by: Yegor Yefremov <[email protected]> +--- + lib/curlx/strdup.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/lib/curlx/strdup.c b/lib/curlx/strdup.c +index ebc58c236..6f6d7c673 100644 +--- a/lib/curlx/strdup.c ++++ b/lib/curlx/strdup.c +@@ -96,8 +96,9 @@ void *curlx_memdup0(const char *src, size_t length) + } + + #ifdef USE_CURLX_MEMZERO +-static void *(* const volatile p_curlx_memset)(void *buf, int val, +- size_t size) = memset; ++/* not const, to keep it out of .rodata and avoid a text relocation */ ++static void *(* volatile p_curlx_memset)(void *buf, int val, ++ size_t size) = memset; + + /* Local fallback in case there is no system function to securely zero a memory + buffer. */ +-- +2.34.1 +
Signature · 6 lines
2.34.1 _______________________________________________ buildroot mailing list [email protected] https://lists.buildroot.org/mailman/listinfo/buildroot
PATCH v2 1/1 package/libcurl: fix build on LoongArch with musl
Since libcurl 8.21.0, building the curl tool for loongarch64 with a musl toolchain fails with:
ld: read-only segment has dynamic relocations
collect2: error: ld returned 1 exit status
On musl, none of the secure memory zeroing functions curl knows about are detected, so curlx_memzero_low() falls back to calling memset() through a 'const volatile' function pointer. In non-PIC code, GCC places this pointer in .rodata, and on LoongArch the linker emits a dynamic R_LARCH_64 relocation against memset() there, i.e. a text relocation. musl's dynamic loader does not support DT_TEXTREL, so the Buildroot toolchain wrapper links with -z text, which turns it into an error. Other architectures resolve the address to a PLT entry at link time and are not affected.
Backport the upstream fix, which detects explicit_bzero() at configure time. musl provides it since 1.1.20, so the memset() fallback is no longer used. As the patch touches configure.ac and m4/, autoreconf the package.
This issue has been present since commit be2789d08432 ("package/libcurl:
security bump to version 8.21.0"), which brought in the upstream code using the 'const volatile' pointer. It therefore affects 2026.08 and later, and 2026.05.x since 2026.05.1.
Fixes:
https://autobuild.buildroot.org/results/558c08d552920e45628254bdc029518120a35ae1
---
Changes v1 -> v2:
- replace the local patch with the upstream fix, which detects explicit_bzero() at configure time instead (suggested by Viktor Szakats in the upstream review)
- autoreconf the package, as the patch touches configure.ac and m4/
...o-detect-explicit_bzero-in-configure.patch | 235 ++++++++++++++++++ package/libcurl/libcurl.mk | 2 + 2 files changed, 237 insertions(+) create mode 100644 package/libcurl/0001-build-auto-detect-explicit_bzero-in-configure.patch
package/libcurl/0001-build-auto-detect-explicit_bzero-in-configure.patch new file +235 -0
@@ -0,0 +1,235 @@ +From e55a7ff40ebe1974735205135dfb3bf9e3db269b Mon Sep 17 00:00:00 2001 +From: Viktor Szakats <[email protected]> +Date: Mon, 9 Nov 2026 19:24:43 +0100 +Subject: [PATCH] build: auto-detect `explicit_bzero()` in configure + +Replacing compile-time auto-detection. Mainly due to MUSL, which offers +no means to detect its presence or version via the preprocessor, +requiring costly configure-time detection. + +After this patch `explicit_bzero()` is used with MUSL 1.1.20+ +(2018-09-04), and potentially more platforms which wasn't expliticly +opted-in previously. + +This in turn avoids this link-time error, and suspect toolchain bug, +when falling back to the local memzero, combined with LoongArch ld +2.45.1 + gcc 16.2.0: +``` +gcc/loongarch64-buildroot-linux-musl/16.2.0/.../loongarch64-buildroot-linux-musl/bin/ld: read-only segment has dynamic relocations +``` +Ref: https://autobuild.buildroot.org/results/558c08d552920e45628254bdc029518120a35ae1 + +Reported-by: Yegor Yefremov +Fixes #23844 +Follow-up to 982e2e8c75f157940ef100f59dea94c4eb607058 #21989 +Follow-up to 066478f6346a2d987a9ecc3bd3bf45764d69c1c4 #21598 + +Closes #23866 + +Upstream: https://github.com/curl/curl/commit/e55a7ff40ebe1974735205135dfb3bf9e3db269b +Signed-off-by: Yegor Yefremov <[email protected]> +--- + CMake/unix-cache.cmake | 9 +++++ + CMakeLists.txt | 5 ++- + configure.ac | 6 +++- + lib/cf-socket.c | 4 +++ + lib/curl_config-cmake.h.in | 3 ++ + lib/curl_setup.h | 15 +++------ + m4/curl-functions.m4 | 67 ++++++++++++++++++++++++++++++++++++++ + 7 files changed, 96 insertions(+), 13 deletions(-) + +diff --git a/CMake/unix-cache.cmake b/CMake/unix-cache.cmake +index b6b544442046..468bd3e4dc01 100644 +--- a/CMake/unix-cache.cmake ++++ b/CMake/unix-cache.cmake +@@ -69,6 +69,15 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR + CMAKE_SYSTEM_NAME STREQUAL "NetBSD") + set(HAVE_EVENTFD 1) + endif() ++if(CYGWIN OR ++ CMAKE_SYSTEM_NAME STREQUAL "Linux" OR # glibc 2.25+, MUSL 1.1.20+ ++ CMAKE_SYSTEM_NAME STREQUAL "DragonFlyBSD" OR # 5.6+ ++ CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR # 11 r272673+ ++ CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") # 5.5+ ++ set(HAVE_EXPLICIT_BZERO 1) ++elseif(APPLE) ++ set(HAVE_EXPLICIT_BZERO 0) ++endif() + if(ANDROID AND ANDROID_PLATFORM_LEVEL GREATER_EQUAL 34) + set(HAVE_MEMSET_EXPLICIT 1) + endif() +diff --git a/CMakeLists.txt b/CMakeLists.txt +index a9df7a21bc3c..23f21dd37d47 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1739,7 +1739,10 @@ if(NOT WIN32) + + check_symbol_exists("memset_s" "string.h" HAVE_MEMSET_S) + if(NOT HAVE_MEMSET_S) +- check_function_exists("memset_explicit" HAVE_MEMSET_EXPLICIT) ++ check_symbol_exists("explicit_bzero" "string.h" HAVE_EXPLICIT_BZERO) ++ if(NOT HAVE_EXPLICIT_BZERO) ++ check_function_exists("memset_explicit" HAVE_MEMSET_EXPLICIT) ++ endif() + endif() + endif() + +diff --git a/configure.ac b/configure.ac +index d6a542311116..ebefb158a27f 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -4242,7 +4242,11 @@ if test "$curl_cv_native_windows" != "yes"; then + + CURL_CHECK_FUNC_MEMSET_S + if test "$curl_cv_func_memset_s" = "no"; then +- AC_CHECK_FUNCS([memset_explicit]) ++ dnl Use complex detection to avoid misdetection on old Linux. ++ CURL_CHECK_FUNC_EXPLICIT_BZERO ++ if test "$curl_cv_func_explicit_bzero" = "no"; then ++ AC_CHECK_FUNCS([memset_explicit]) ++ fi + fi + fi + +diff --git a/lib/cf-socket.c b/lib/cf-socket.c +index 97b5fa89d219..9073274ba0c2 100644 +--- a/lib/cf-socket.c ++++ b/lib/cf-socket.c +@@ -59,6 +59,10 @@ + #include <inet.h> + #endif + ++#ifdef __DragonFly__ ++#include <sys/param.h> /* for __DragonFly_version */ ++#endif ++ + #include "urldata.h" + #include "curl_trc.h" + #include "if2ip.h" +diff --git a/lib/curl_config-cmake.h.in b/lib/curl_config-cmake.h.in +index 45c5de970dce..dbbbd04fdfb8 100644 +--- a/lib/curl_config-cmake.h.in ++++ b/lib/curl_config-cmake.h.in +@@ -234,6 +234,9 @@ + /* Define to 1 if you have the `opendir' function. */ + #cmakedefine HAVE_OPENDIR 1 + ++/* Define to 1 if you have the explicit_bzero function. */ ++#cmakedefine HAVE_EXPLICIT_BZERO 1 ++ + /* Define to 1 if you have the memset_explicit (C23) function. */ + #cmakedefine HAVE_MEMSET_EXPLICIT 1 + +diff --git a/lib/curl_setup.h b/lib/curl_setup.h +index d4d0f25bfe24..504b21210352 100644 +--- a/lib/curl_setup.h ++++ b/lib/curl_setup.h +@@ -1638,9 +1638,8 @@ typedef struct sockaddr_un { + #endif + + /* For FreeBSD it is included from curl/curl.h */ +-#if defined(__DragonFly__) || defined(__OpenBSD__) || defined(__NetBSD__) +-#include <sys/param.h> /* for __DragonFly_version, OpenBSD, +- __NetBSD_Version__ */ ++#ifdef __NetBSD__ ++#include <sys/param.h> /* for __NetBSD_Version__ */ + #endif + + /* NetBSD before 6.1 did not set SS_NBIO for SOCK_NONBLOCK. */ +@@ -1660,16 +1659,10 @@ typedef struct sockaddr_un { + #endif + #elif defined(HAVE_MEMSET_S) + #define curlx_memzero_low(buf, size) (void)memset_s(buf, size, 0, size) ++#elif defined(HAVE_EXPLICIT_BZERO) ++#define curlx_memzero_low(buf, size) explicit_bzero(buf, size) + #elif defined(HAVE_MEMSET_EXPLICIT) + #define curlx_memzero_low(buf, size) (void)memset_explicit(buf, 0, size) +-#elif defined(__CYGWIN__) || \ +- (defined(__NEWLIB__) && !defined(__CLIB2__)) || \ +- (defined(__GLIBC__) && \ +- (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))) || \ +- (defined(__DragonFly__) && __DragonFly_version >= 500600 /* 5.6+ */) || \ +- (defined(__FreeBSD__) && __FreeBSD_version >= 1100037 /* 11.0+ */) || \ +- (defined(__OpenBSD__) && OpenBSD >= 201405 /* 5.5+ */) +-#define curlx_memzero_low(buf, size) explicit_bzero(buf, size) + #elif defined(__NetBSD__) && __NetBSD_Version__ >= 702000000 /* 7.2+ */ + #define curlx_memzero_low(buf, size) (void)explicit_memset(buf, 0, size) + #endif +diff --git a/m4/curl-functions.m4 b/m4/curl-functions.m4 +index 64046a834afb..2edbdf0fb5f4 100644 +--- a/m4/curl-functions.m4 ++++ b/m4/curl-functions.m4 +@@ -3956,6 +3956,73 @@ AC_DEFUN([CURL_CHECK_FUNC_MEMSET_S], [ + fi + ]) + ++dnl CURL_CHECK_FUNC_EXPLICIT_BZERO ++dnl ------------------------------------------------- ++dnl Verify if explicit_bzero is available. ++ ++AC_DEFUN([CURL_CHECK_FUNC_EXPLICIT_BZERO], [ ++ ++ tst_links_explicit_bzero="unknown" ++ tst_proto_explicit_bzero="unknown" ++ tst_compile_explicit_bzero="unknown" ++ ++ AC_MSG_CHECKING([if explicit_bzero can be linked]) ++ AC_LINK_IFELSE([ ++ AC_LANG_FUNC_LINK_TRY([explicit_bzero]) ++ ],[ ++ AC_MSG_RESULT([yes]) ++ tst_links_explicit_bzero="yes" ++ ],[ ++ AC_MSG_RESULT([no]) ++ tst_links_explicit_bzero="no" ++ ]) ++ ++ if test "$tst_links_explicit_bzero" = "yes"; then ++ AC_MSG_CHECKING([if explicit_bzero is prototyped]) ++ AC_EGREP_CPP([explicit_bzero],[ ++ $curl_includes_string ++ ],[ ++ AC_MSG_RESULT([yes]) ++ tst_proto_explicit_bzero="yes" ++ ],[ ++ AC_MSG_RESULT([no]) ++ tst_proto_explicit_bzero="no" ++ ]) ++ fi ++ ++ if test "$tst_proto_explicit_bzero" = "yes"; then ++ AC_MSG_CHECKING([if explicit_bzero is compilable]) ++ AC_COMPILE_IFELSE([ ++ AC_LANG_PROGRAM([[ ++ $curl_includes_string ++ ]],[[ ++ char buf[2]; ++ explicit_bzero(buf, sizeof(buf)); ++ ]]) ++ ],[ ++ AC_MSG_RESULT([yes]) ++ tst_compile_explicit_bzero="yes" ++ ],[ ++ AC_MSG_RESULT([no]) ++ tst_compile_explicit_bzero="no" ++ ]) ++ fi ++ ++ AC_MSG_CHECKING([if explicit_bzero might be used]) ++ if test "$tst_links_explicit_bzero" = "yes" && ++ test "$tst_proto_explicit_bzero" = "yes" && ++ test "$tst_compile_explicit_bzero" = "yes" && ++ test "x$curl_disallow_explicit_bzero" != "xyes"; then ++ AC_MSG_RESULT([yes]) ++ AC_DEFINE_UNQUOTED(HAVE_EXPLICIT_BZERO, 1, ++ [Define to 1 if you have the explicit_bzero function.]) ++ curl_cv_func_explicit_bzero="yes" ++ else ++ AC_MSG_RESULT([no]) ++ curl_cv_func_explicit_bzero="no" ++ fi ++]) ++ + dnl CURL_RUN_IFELSE + dnl ------------------------------------------------- + dnl Wrapper macro to use instead of AC_RUN_IFELSE. It
package/libcurl/libcurl.mk +2 -0
@@ -14,6 +14,8 @@ LIBCURL_LICENSE = curl LIBCURL_LICENSE_FILES = COPYING LIBCURL_CPE_ID_VENDOR = haxx LIBCURL_INSTALL_STAGING = YES +# 0001-build-auto-detect-explicit_bzero-in-configure.patch +LIBCURL_AUTORECONF = YES # Likewise, there is no compiler on the target, so libcurl-option (to # generate C code) isn't very useful
Signature · 6 lines
2.34.1 _______________________________________________ buildroot mailing list [email protected] https://lists.buildroot.org/mailman/listinfo/buildroot
Quoted 34 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
"Yegor" == Yegor Yefremov via buildroot <[email protected]> writes:
Since libcurl 8.21.0, building the curl tool for loongarch64 with a musl toolchain fails with:
ld: read-only segment has dynamic relocations
collect2: error: ld returned 1 exit statusOn musl, none of the secure memory zeroing functions curl knows about are detected, so
curlx_memzero_low()falls back to callingmemset()through a 'const volatile' function pointer. In non-PIC code, GCC places this pointer in .rodata, and on LoongArch the linker emits a dynamicR_LARCH_64relocation againstmemset()there, i.e. a text relocation. musl's dynamic loader does not supportDT_TEXTREL, so the Buildroot toolchain wrapper links with -z text, which turns it into an error. Other architectures resolve the address to a PLT entry at link time and are not affected.Backport the upstream fix, which detects
explicit_bzero()at configure time. musl provides it since 1.1.20, so thememset()fallback is no longer used. As the patch touches configure.ac and m4/, autoreconf the package.This issue has been present since commit
be2789d08432("package/libcurl:
security bump to version 8.21.0"), which brought in the upstream code using the 'const volatile' pointer. It therefore affects 2026.08 and later, and 2026.05.x since 2026.05.1.Fixes:
https://autobuild.buildroot.org/results/558c08d552920e45628254bdc029518120a35ae1Fixes be2789d08432da951c0ebfb23b034072601bc8fe ("package/libcurl: security bump to version 8.21.0")Assisted-by Claude:claude-opus-5-5Signed-off-by Yegor Yefremov <[email protected]>
Quoted 6 lines
---
Changes v1 -> v2:
- replace the local patch with the upstream fix, which detectsexplicit_bzero()at configure time instead (suggested by Viktor Szakats in the upstream review)
- autoreconf the package, as the patch touches configure.ac and m4/
Committed, thanks.
Signature · 5 lines
Bye, Peter Korsgaard _______________________________________________ buildroot mailing list [email protected] https://lists.buildroot.org/mailman/listinfo/buildroot