From 6a5da8faa95148af5ace04cd63a9e11686b61d12 Mon Sep 17 00:00:00 2001 From: Arjun Shankar Date: Tue, 17 Mar 2026 12:39:23 +0100 Subject: [PATCH] dlfcn: Add dlinfo request type RTLD_DI_ORIGIN_PATH (RHEL-54450) Resolves: RHEL-54450 --- glibc-RHEL-54450.patch | 111 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 glibc-RHEL-54450.patch diff --git a/glibc-RHEL-54450.patch b/glibc-RHEL-54450.patch new file mode 100644 index 0000000..ab7c187 --- /dev/null +++ b/glibc-RHEL-54450.patch @@ -0,0 +1,111 @@ +commit b52619f2e8bbae57d79c95538346198c4a9f24a6 +Author: Arjun Shankar +Date: Mon Jan 26 13:49:37 2026 +0100 + + dlfcn: Add dlinfo request type RTLD_DI_ORIGIN_PATH (bug #24298) + + The existing dlinfo request type RTLD_DI_ORIGIN used for querying the + value of the '$ORIGIN' dynamic string token is prone to buffer + overflows. + + This commit adds a new request type named RTLD_DI_ORIGIN_PATH that + returns a pointer to the dynamic string token (i.e. the 'l_origin' field + in the link map) instead. The dlinfo manual is updated with the new + request type, and the description of RTLD_DI_ORIGIN is updated to + recommend RTLD_DI_ORIGIN_PATH instead. + + A test for the new request type is also added to tst-dlinfo. + + Reviewed-by: Carlos O'Donell + +diff --git a/dlfcn/dlfcn.h b/dlfcn/dlfcn.h +index 8168a71dbfe90e75..b80c3e3d9f240e80 100644 +--- a/dlfcn/dlfcn.h ++++ b/dlfcn/dlfcn.h +@@ -169,7 +169,12 @@ enum + the number of program headers in the array. */ + RTLD_DI_PHDR = 11, + +- RTLD_DI_MAX = 11 ++ /* Treat ARG as `const char **' and at that location, store the address ++ of the directory name used to expand $ORIGIN in this shared object's ++ dependency file names. */ ++ RTLD_DI_ORIGIN_PATH = 12, ++ ++ RTLD_DI_MAX = 12 + }; + + +diff --git a/dlfcn/dlinfo.c b/dlfcn/dlinfo.c +index 1842925fb7c594dd..28681a865a11e102 100644 +--- a/dlfcn/dlinfo.c ++++ b/dlfcn/dlinfo.c +@@ -67,6 +67,13 @@ dlinfo_doit (void *argsblock) + strcpy (args->arg, l->l_origin); + break; + ++ case RTLD_DI_ORIGIN_PATH: ++ if (l->l_origin != (char *) -1) ++ *(const char **) args->arg = l->l_origin; ++ else ++ *(const char **) args->arg = NULL; ++ break; ++ + case RTLD_DI_TLS_MODID: + *(size_t *) args->arg = 0; + *(size_t *) args->arg = l->l_tls_modid; +diff --git a/dlfcn/tst-dlinfo.c b/dlfcn/tst-dlinfo.c +index d47eebc013a556b4..0765be8e649251b7 100644 +--- a/dlfcn/tst-dlinfo.c ++++ b/dlfcn/tst-dlinfo.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + #define TEST_FUNCTION do_test () + +@@ -56,6 +57,13 @@ do_test (void) + printf ("origin: %s\n", origin); + } + ++ const char *origin_path; ++ TRY (RTLD_DI_ORIGIN_PATH, &origin_path) ++ { ++ TEST_COMPARE_STRING (origin, origin_path); ++ printf ("origin_path: %s\n", origin_path); ++ } ++ + Dl_serinfo counts; + TRY (RTLD_DI_SERINFOSIZE, &counts) + { +diff --git a/manual/dynlink.texi b/manual/dynlink.texi +index f97f13444f1c5946..2b35e5883c3e65c0 100644 +--- a/manual/dynlink.texi ++++ b/manual/dynlink.texi +@@ -482,13 +482,23 @@ The namespace identifier of @var{handle} is written to + @code{*@var{arg}}. The @var{arg} argument must be the address of an + object of type @code{Lmid_t}. + ++@item RTLD_DI_ORIGIN_PATH ++The @code{$ORIGIN} dynamic string token pointer for @var{handle} is written ++to @code{*@var{arg}}. The @var{arg} argument must be the address of a ++@code{const char *}. If the @code{$ORIGIN} could not be determined, the ++function still returns 0 but writes a null pointer to @code{*@var{arg}}. ++The returned string is only valid as long as the corresponding handle is ++valid. Accessing it after @code{dlclose} has been called for the ++corresponding @var{handle} is undefined behavior. ++ + @item RTLD_DI_ORIGIN + The value of the @code{$ORIGIN} dynamic string token for @var{handle} is + written to the character array starting at @var{arg} as a + null-terminated string. + + This request type should not be used because it is prone to buffer +-overflows. ++overflows. Instead, @code{RTLD_DI_ORIGIN_PATH} described above should be ++used. + + @item RTLD_DI_SERINFO + @itemx RTLD_DI_SERINFOSIZE