diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | elf/dl-load.c | 43 |
2 files changed, 33 insertions, 14 deletions
@@ -1,5 +1,9 @@ 2005-09-26 Ulrich Drepper <drepper@redhat.com> + [BZ #516] + * elf/dl-load.c: Report failed loading due to ELF class mismatch + with better words. + [BZ #162] * manual/llio.texi (Waiting for I/O): Correct description of read conditions reported by select. diff --git a/elf/dl-load.c b/elf/dl-load.c index 9a780beae8..0ed670d158 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1552,7 +1552,7 @@ print_search_path (struct r_search_path_elem **list, user might want to know about this. */ static int open_verify (const char *name, struct filebuf *fbp, struct link_map *loader, - int whatcode) + int whatcode, bool *found_other_class) { /* This is the expected ELF header. */ #define ELF32_CLASS ELFCLASS32 @@ -1656,10 +1656,13 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader, ) errstring = N_("invalid ELF header"); else if (ehdr->e_ident[EI_CLASS] != ELFW(CLASS)) - /* This is not a fatal error. On architectures where - 32-bit and 64-bit binaries can be run this might - happen. */ - goto close_and_out; + { + /* This is not a fatal error. On architectures where + 32-bit and 64-bit binaries can be run this might + happen. */ + *found_other_class = true; + goto close_and_out; + } else if (ehdr->e_ident[EI_DATA] != byteorder) { if (BYTE_ORDER == BIG_ENDIAN) @@ -1766,7 +1769,8 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader, static int open_path (const char *name, size_t namelen, int preloaded, struct r_search_path_struct *sps, char **realname, - struct filebuf *fbp, struct link_map *loader, int whatcode) + struct filebuf *fbp, struct link_map *loader, int whatcode, + bool *found_other_class) { struct r_search_path_elem **dirs = sps->dirs; char *buf; @@ -1815,7 +1819,7 @@ open_path (const char *name, size_t namelen, int preloaded, if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0)) _dl_debug_printf (" trying file=%s\n", buf); - fd = open_verify (buf, fbp, loader, whatcode); + fd = open_verify (buf, fbp, loader, whatcode, found_other_class); if (this_dir->status[cnt] == unknown) { if (fd != -1) @@ -1990,6 +1994,9 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, } #endif + /* Will be true if we found a DSO which is of the other ELF class. */ + bool found_other_class = false; + if (strchr (name, '/') == NULL) { /* Search for NAME in several places. */ @@ -2010,7 +2017,8 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, for (l = loader; fd == -1 && l; l = l->l_loader) if (cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH")) fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs, - &realname, &fb, loader, LA_SER_RUNPATH); + &realname, &fb, loader, LA_SER_RUNPATH, + &found_other_class); /* If dynamically linked, try the DT_RPATH of the executable itself. NB: we do this for lookups in any namespace. */ @@ -2020,7 +2028,8 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, if (l && l->l_type != lt_loaded && l != loader && cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH")) fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs, - &realname, &fb, loader ?: l, LA_SER_RUNPATH); + &realname, &fb, loader ?: l, LA_SER_RUNPATH, + &found_other_class); } } @@ -2029,7 +2038,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, fd = open_path (name, namelen, preloaded, &env_path_list, &realname, &fb, loader ?: GL(dl_ns)[LM_ID_BASE]._ns_loaded, - LA_SER_LIBPATH); + LA_SER_LIBPATH, &found_other_class); /* Look at the RUNPATH information for this binary. */ if (fd == -1 && loader != NULL @@ -2037,7 +2046,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, DT_RUNPATH, "RUNPATH")) fd = open_path (name, namelen, preloaded, &loader->l_runpath_dirs, &realname, &fb, loader, - LA_SER_RUNPATH); + LA_SER_RUNPATH, &found_other_class); if (fd == -1 && (__builtin_expect (! preloaded, 1) @@ -2087,7 +2096,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, { fd = open_verify (cached, &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded, - LA_SER_CONFIG); + LA_SER_CONFIG, &found_other_class); if (__builtin_expect (fd != -1, 1)) { realname = local_strdup (cached); @@ -2107,7 +2116,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, || __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1)) && rtld_search_dirs.dirs != (void *) -1) fd = open_path (name, namelen, preloaded, &rtld_search_dirs, - &realname, &fb, l, LA_SER_DEFAULT); + &realname, &fb, l, LA_SER_DEFAULT, &found_other_class); /* Add another newline when we are tracing the library loading. */ if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0)) @@ -2124,7 +2133,8 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, else { fd = open_verify (realname, &fb, - loader ?: GL(dl_ns)[nsid]._ns_loaded, 0); + loader ?: GL(dl_ns)[nsid]._ns_loaded, 0, + &found_other_class); if (__builtin_expect (fd, 0) == -1) free (realname); } @@ -2167,6 +2177,11 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, return l; } + else if (found_other_class) + _dl_signal_error (0, name, NULL, + ELFW(CLASS) == ELFCLASS32 + ? N_("wrong ELF class: ELFCLASS64") + : N_("wrong ELF class: ELFCLASS32")); else _dl_signal_error (errno, name, NULL, N_("cannot open shared object file")); |