aboutsummaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-load.c43
1 files changed, 29 insertions, 14 deletions
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 9a780be..0ed670d 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"));