Sourceware Bugzilla – Attachment 11770 Details for
Bug 24488
ebl_openbackend might use wrong library search path
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Factor out loading of ebl backend library and try multiple times with bin/lib origin paths
try_dlopen.patch (text/plain), 4.65 KB, created by
Mark Wielaard
on 2019-05-11 15:49:52 UTC
(
hide
)
Description:
Factor out loading of ebl backend library and try multiple times with bin/lib origin paths
Filename:
MIME Type:
Creator:
Mark Wielaard
Created:
2019-05-11 15:49:52 UTC
Size:
4.65 KB
patch
obsolete
>commit 96e8fd942e2165aa138ccbce8fb0003ed8c649f1 >Author: Mark Wielaard <mark@klomp.org> >Date: Sat May 11 16:55:01 2019 +0200 > > WIP try_dlopen, try BINORIGIN, LIBORIGIN... > >diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c >index d54b720..36a2492 100644 >--- a/libebl/eblopenbackend.c >+++ b/libebl/eblopenbackend.c >@@ -251,6 +251,50 @@ fill_defaults (Ebl *result) > result->sysvhash_entrysize = sizeof (Elf32_Word); > } > >+static Ebl * >+try_dlopen (const char *dsoname, Elf *elf, GElf_Half machine, size_t cnt, >+ Ebl *result) >+{ >+ void *h = dlopen (dsoname, RTLD_LAZY); >+ >+ if (h != NULL) >+ { >+ /* We managed to load the object. Now see whether the >+ initialization function likes our file. */ >+ static const char version[] = MODVERSION; >+ const char *modversion; >+ ebl_bhinit_t initp; >+ >+ // We use a static number to help the compiler see we don't >+ // overflow the stack with an arbitrary number. >+ assert (machines[cnt].prefix_len <= MAX_PREFIX_LEN); >+ char symname[MAX_PREFIX_LEN + sizeof "_init"]; >+ >+ strcpy (mempcpy (symname, machines[cnt].prefix, >+ machines[cnt].prefix_len), "_init"); >+ >+ initp = (ebl_bhinit_t) dlsym (h, symname); >+ if (initp != NULL >+ && (modversion = initp (elf, machine, result, sizeof (Ebl))) >+ && strcmp (version, modversion) == 0) >+ { >+ /* We found a module to handle our file. */ >+ result->dlhandle = h; >+ result->elf = elf; >+ >+ /* A few entries are mandatory. */ >+ assert (result->name != NULL); >+ assert (result->destr != NULL); >+ >+ return result; >+ } >+ >+ /* Not the module we need. */ >+ (void) dlclose (h); >+ } >+ >+ return NULL; >+} > > /* Find an appropriate backend for the file associated with ELF. */ > static Ebl * >@@ -316,60 +360,39 @@ openbackend (Elf *elf, const char *emulation, GElf_Half machine) > #ifndef LIBEBL_SUBDIR > # define LIBEBL_SUBDIR PACKAGE > #endif >-#define ORIGINDIR "$ORIGIN/../$LIB/" LIBEBL_SUBDIR "/" >+ >+/* This works if libebl has been staticly linked into a binary. >+ It might also work for shared libraries when installed in >+ ${prefix}/lib/ or ${prefix}/lib64/, but not for multiarch >+ library installs like ${prefix}/lib/i386-linux-gnu/ */ >+#define BINORIGINDIR "$ORIGIN/../$LIB/" LIBEBL_SUBDIR "/" >+ >+/* This works if libebl has been linked into a shared library, >+ just look in the subdir. */ >+#define LIBORIGINDIR "$ORIGIN/" LIBEBL_SUBDIR "/" > > /* Give it a try. At least the machine type matches. First >- try to load the module. */ >+ try to load the module from the (bin) origin path. */ > char dsoname[100]; >- strcpy (stpcpy (stpcpy (dsoname, ORIGINDIR "libebl_"), >+ strcpy (stpcpy (stpcpy (dsoname, BINORIGINDIR "libebl_"), > machines[cnt].dsoname), > ".so"); >+ if (try_dlopen (dsoname, elf, machine, cnt, result) != NULL) >+ return result; > >- void *h = dlopen (dsoname, RTLD_LAZY); >- if (h == NULL) >- { >- strcpy (stpcpy (stpcpy (dsoname, "libebl_"), >- machines[cnt].dsoname), >- ".so"); >- h = dlopen (dsoname, RTLD_LAZY); >- } >+ /* Retry with the (lib) origin path. */ >+ strcpy (stpcpy (stpcpy (dsoname, LIBORIGINDIR "libebl_"), >+ machines[cnt].dsoname), >+ ".so"); >+ if (try_dlopen (dsoname, elf, machine, cnt, result) != NULL) >+ return result; > >- /* Try without an explicit path. */ >- if (h != NULL) >- { >- /* We managed to load the object. Now see whether the >- initialization function likes our file. */ >- static const char version[] = MODVERSION; >- const char *modversion; >- ebl_bhinit_t initp; >- >- // We use a static number to help the compiler see we don't >- // overflow the stack with an arbitrary number. >- assert (machines[cnt].prefix_len <= MAX_PREFIX_LEN); >- char symname[MAX_PREFIX_LEN + sizeof "_init"]; >- >- strcpy (mempcpy (symname, machines[cnt].prefix, >- machines[cnt].prefix_len), "_init"); >- >- initp = (ebl_bhinit_t) dlsym (h, symname); >- if (initp != NULL >- && (modversion = initp (elf, machine, result, sizeof (Ebl))) >- && strcmp (version, modversion) == 0) >- { >- /* We found a module to handle our file. */ >- result->dlhandle = h; >- result->elf = elf; >- >- /* A few entries are mandatory. */ >- assert (result->name != NULL); >- assert (result->destr != NULL); >- >- return result; >- } >- >- /* Not the module we need. */ >- (void) dlclose (h); >- } >+ /* Try without an explicit path (LD_LIBRARY_PATH or RPATH). */ >+ strcpy (stpcpy (stpcpy (dsoname, "libebl_"), >+ machines[cnt].dsoname), >+ ".so"); >+ if (try_dlopen (dsoname, elf, machine, cnt, result) != NULL) >+ return result; > > /* We cannot find a DSO but the emulation/machine ID matches. > Return that information. */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 24488
: 11770