Implement single rtld_flags interpretation through all the
do_dlopen()/_dl_load_shared_library()/_dl_load_elf_shared_library()
calls chain.
This adds the ability to use the flags, passed to dlopen(), in all
underlaying functions and implement rtld_flags inheritance.
Saves a few bytes code.
Signed-off-by: Leonid Lisovskiy <lly.dev(a)gmail.com>
---
include/dlfcn.h | 3 +++
ldso/include/dl-elf.h | 7 ++-----
ldso/ldso/dl-elf.c | 14 +++++++-------
ldso/ldso/ldso.c | 5 +++--
ldso/libdl/libdl.c | 10 +++-------
5 files changed, 18 insertions(+), 21 deletions(-)
diff --git a/include/dlfcn.h b/include/dlfcn.h
index 241ec54..74825aa 100644
--- a/include/dlfcn.h
+++ b/include/dlfcn.h
@@ -26,6 +26,9 @@
/* Collect various system dependent definitions and declarations. */
#include <bits/dlfcn.h>
+/* Internally used flag. */
+#define __RTLD_SECURE 0x04000000 /* Apply additional security checks. */
+
#ifdef __USE_GNU
/* If the first argument of `dlsym' or `dlvsym' is set to RTLD_NEXT
diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h
index 4cc9b2b..57f0ddc 100644
--- a/ldso/include/dl-elf.h
+++ b/ldso/include/dl-elf.h
@@ -29,18 +29,15 @@ static __inline__ void _dl_map_cache(void) { }
static __inline__ void _dl_unmap_cache(void) { }
#endif
-#define DL_RESOLVE_SECURE 0x0001
-#define DL_RESOLVE_NOLOAD 0x0002
-
/* Function prototypes for non-static stuff in elfinterp.c */
extern void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
unsigned long rel_addr, unsigned long rel_size);
extern int _dl_parse_relocation_information(struct dyn_elf *rpnt,
struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size);
-extern struct elf_resolve * _dl_load_shared_library(unsigned rflags,
+extern struct elf_resolve * _dl_load_shared_library(unsigned int rflags,
struct dyn_elf **rpnt, struct elf_resolve *tpnt, char *full_libname,
int trace_loaded_objects);
-extern struct elf_resolve * _dl_load_elf_shared_library(unsigned rflags,
+extern struct elf_resolve * _dl_load_elf_shared_library(unsigned int rflags,
struct dyn_elf **rpnt, const char *libname);
extern int _dl_linux_resolve(void);
extern int _dl_fixup(struct dyn_elf *rpnt, struct r_scope_elem *scope, int flag);
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index 5b8572a..04e8c60 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -132,7 +132,7 @@ _dl_protect_relro (struct elf_resolve *l)
/* This function's behavior must exactly match that
* in uClibc/ldso/util/ldd.c */
static struct elf_resolve *
-search_for_named_library(const char *name, unsigned rflags, const char *path_list,
+search_for_named_library(const char *name, unsigned int rflags, const char *path_list,
struct dyn_elf **rpnt, const char* origin)
{
char *mylibname;
@@ -164,7 +164,7 @@ search_for_named_library(const char *name, unsigned rflags, const char
*path_lis
int olen;
/* $ORIGIN is not expanded for SUID/GUID programs
(except if it is $ORIGIN alone) */
- if ((rflags & DL_RESOLVE_SECURE) && plen != 7)
+ if ((rflags & __RTLD_SECURE) && plen != 7)
continue;
if (origin == NULL)
continue;
@@ -196,7 +196,7 @@ search_for_named_library(const char *name, unsigned rflags, const char
*path_lis
unsigned long _dl_error_number;
unsigned long _dl_internal_error_number;
-struct elf_resolve *_dl_load_shared_library(unsigned rflags, struct dyn_elf **rpnt,
+struct elf_resolve *_dl_load_shared_library(unsigned int rflags, struct dyn_elf **rpnt,
struct elf_resolve *tpnt, char *full_libname, int attribute_unused
trace_loaded_objects)
{
char *pnt;
@@ -495,7 +495,7 @@ map_writeable (int infile, ElfW(Phdr) *ppnt, int piclib, int flags,
* are required.
*/
-struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,
+struct elf_resolve *_dl_load_elf_shared_library(unsigned int rflags,
struct dyn_elf **rpnt, const char *libname)
{
ElfW(Ehdr) *epnt;
@@ -534,7 +534,7 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,
}
/* If we are in secure mode (i.e. a setuid/gid binary using LD_PRELOAD),
we don't load the library if it isn't setuid. */
- if (rflags & DL_RESOLVE_SECURE) {
+ if (rflags & __RTLD_SECURE) {
if (!(st.st_mode & S_ISUID)) {
_dl_close(infile);
return NULL;
@@ -550,7 +550,7 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,
return tpnt;
}
}
- if (rflags & DL_RESOLVE_NOLOAD) {
+ if (rflags & RTLD_NOLOAD) {
_dl_close(infile);
return NULL;
}
@@ -814,7 +814,7 @@ struct elf_resolve *_dl_load_elf_shared_library(unsigned rflags,
DL_RELOC_ADDR(DL_GET_RUN_ADDR(tpnt->loadaddr, tpnt->mapaddr),
epnt->e_phoff);
tpnt->n_phent = epnt->e_phnum;
- tpnt->rtld_flags |= rtld_flags;
+ tpnt->rtld_flags = rflags | rtld_flags;
#ifdef __LDSO_STANDALONE_SUPPORT__
tpnt->l_entry = epnt->e_entry;
#endif
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
index 0cdc91d..9f4e841 100644
--- a/ldso/ldso/ldso.c
+++ b/ldso/ldso/ldso.c
@@ -589,7 +589,8 @@ of this helper program; chances are you did not intend to run this
program.\n\
* but it could be also a shared object (when ld.so used for tracing)
* We keep the misleading app_tpnt name to avoid variable pollution
*/
- app_tpnt = _dl_load_elf_shared_library(_dl_secure, &rpnt, _dl_progname);
+ app_tpnt = _dl_load_elf_shared_library(_dl_secure ? __RTLD_SECURE : 0,
+ &rpnt, _dl_progname);
if (!app_tpnt) {
_dl_dprintf(2, "can't load '%s'\n", _dl_progname);
_dl_exit(16);
@@ -887,7 +888,7 @@ of this helper program; chances are you did not intend to run this
program.\n\
_dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", str,
_dl_progname);
tpnt1 = _dl_load_shared_library(
- _dl_secure ? DL_RESOLVE_SECURE : 0,
+ _dl_secure ? __RTLD_SECURE : 0,
&rpnt, NULL, str, trace_loaded_objects);
if (!tpnt1) {
#ifdef __LDSO_LDD_SUPPORT__
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index 08619bc..42a09a8 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -59,8 +59,6 @@ extern struct link_map *_dl_update_slotinfo(unsigned long int
req_modid);
* and use a pile of symbols from ldso... */
#include <dl-elf.h>
#if 0
-extern struct elf_resolve * _dl_load_shared_library(unsigned, struct dyn_elf **,
- struct elf_resolve *, char *, int);
extern int _dl_fixup(struct dyn_elf *rpnt, struct r_scope_elem *scope, int lazy);
extern void _dl_protect_relro(struct elf_resolve * tpnt);
#endif
@@ -385,7 +383,7 @@ static void *do_dlopen(const char *libname, int flag, ElfW(Addr)
from)
_dl_if_debug_print("Trying to dlopen '%s', RTLD_GLOBAL:%d
RTLD_NOW:%d\n",
(char*)libname, (flag & RTLD_GLOBAL ? 1:0), (now_flag & RTLD_NOW ? 1:0));
- tpnt = _dl_load_shared_library((flag & RTLD_NOLOAD) ? DL_RESOLVE_NOLOAD : 0,
+ tpnt = _dl_load_shared_library(flag & (RTLD_NOLOAD | RTLD_GLOBAL | RTLD_NODELETE),
&rpnt, tfrom, (char*)libname, 0);
if (tpnt == NULL) {
_dl_unmap_cache();
@@ -394,7 +392,6 @@ static void *do_dlopen(const char *libname, int flag, ElfW(Addr)
from)
dyn_chain = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));
memset(dyn_chain, 0, sizeof(struct dyn_elf));
dyn_chain->dyn = tpnt;
- tpnt->rtld_flags |= (flag & (RTLD_GLOBAL|RTLD_NODELETE));
dyn_chain->next_handle = _dl_handles;
_dl_handles = dyn_ptr = dyn_chain;
@@ -435,12 +432,11 @@ static void *do_dlopen(const char *libname, int flag, ElfW(Addr)
from)
dpnt->d_un.d_val);
_dl_if_debug_print("Trying to load '%s', needed by
'%s'\n",
lpntstr, runp->tpnt->libname);
- tpnt1 = _dl_load_shared_library(0, &rpnt, runp->tpnt, lpntstr, 0);
+ tpnt1 = _dl_load_shared_library(flag & (RTLD_GLOBAL | RTLD_NODELETE),
+ &rpnt, runp->tpnt, lpntstr, 0);
if (!tpnt1)
goto oops;
- tpnt1->rtld_flags |= (flag & (RTLD_GLOBAL|RTLD_NODELETE));
-
/* This list is for dlsym() and relocation */
dyn_ptr->next = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));
memset (dyn_ptr->next, 0, sizeof (struct dyn_elf));
--
1.8.5.6