diff options
Diffstat (limited to 'libexec/ld.so/loader.c')
-rw-r--r-- | libexec/ld.so/loader.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/libexec/ld.so/loader.c b/libexec/ld.so/loader.c index 9f15530e2c4..de53dc85d58 100644 --- a/libexec/ld.so/loader.c +++ b/libexec/ld.so/loader.c @@ -1,4 +1,4 @@ -/* $OpenBSD: loader.c,v 1.218 2023/12/19 16:13:22 deraadt Exp $ */ +/* $OpenBSD: loader.c,v 1.219 2024/01/14 09:39:03 kettenis Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -70,6 +70,7 @@ int _dl_trust __relro = 0; char **_dl_libpath __relro = NULL; const char **_dl_argv __relro = NULL; int _dl_argc __relro = 0; +const char *_dl_libcname; char *_dl_preload __boot_data = NULL; char *_dl_tracefmt1 __boot_data = NULL; @@ -358,6 +359,31 @@ _dl_load_dep_libs(elf_object_t *object, int flags, int booting) if (dynp->d_tag == DT_NEEDED) liblist[loop++].dynp = dynp; + /* + * We can't support multiple versions of libc + * in a single process. So remember the first + * libc SONAME we encounter as a dependency + * and use it in further loads of libc. In + * practice this means we will always use the + * libc version that the binary was linked + * against. This isn't entirely correct, but + * it will keep most binaries running when + * transitioning over a libc major bump. + */ + if (_dl_libcname == NULL) { + for (loop = 0; loop < libcount; loop++) { + const char *libname; + libname = dynobj->dyn.strtab; + libname += + liblist[loop].dynp->d_un.d_val; + if (_dl_strncmp(libname, + "libc.so.", 8) == 0) { + _dl_libcname = libname; + break; + } + } + } + /* Randomize these */ for (loop = 0; loop < libcount; loop++) randomlist[loop] = loop; @@ -380,6 +406,10 @@ _dl_load_dep_libs(elf_object_t *object, int flags, int booting) liblist[randomlist[loop]].dynp->d_un.d_val; DL_DEB(("loading: %s required by %s\n", libname, dynobj->load_name)); + if (_dl_strncmp(libname, "libc.so.", 8) == 0) { + if (_dl_libcname) + libname = _dl_libcname; + } depobj = _dl_load_shlib(libname, dynobj, OBJTYPE_LIB, depflags, nodelete); if (depobj == 0) { |