summaryrefslogtreecommitdiffstats
path: root/linker/linker.cpp
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2012-10-29 17:37:13 -0700
committerElliott Hughes <enh@google.com>2012-10-30 16:35:38 -0700
commit18a206c81d9743481e364384affd43306911283d (patch)
tree2f211404b359cb7278f6963bb82f507e6c9a2050 /linker/linker.cpp
parent06b596104a9ed3ac089abd00186a5698d7e8544f (diff)
downloadbionic-18a206c81d9743481e364384affd43306911283d.zip
bionic-18a206c81d9743481e364384affd43306911283d.tar.gz
bionic-18a206c81d9743481e364384affd43306911283d.tar.bz2
More dynamic linker cleanup.
I still want to break linker_format out into its own library so we can reuse it for malloc debugging and so forth. (There are many similar pieces of code in bionic, but the linker's one seems to be the most complete/functional.) Change-Id: If3721853d28937c8e821ca1d23cf200e228a409a
Diffstat (limited to 'linker/linker.cpp')
-rw-r--r--linker/linker.cpp73
1 files changed, 23 insertions, 50 deletions
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 4ffa1e7..4c52f3d 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -93,7 +93,6 @@ static soinfo *sonext = &libdl_info;
static soinfo *somain; /* main process, always the one after libdl_info */
#endif
-
static char ldpaths_buf[LDPATH_BUFSIZE];
static const char *ldpaths[LDPATH_MAX + 1];
@@ -108,9 +107,6 @@ int debug_verbosity;
static int pid;
-/* This boolean is set if the program being loaded is setuid */
-static bool program_is_setuid;
-
enum RelocationKind {
kRelocAbsolute = 0,
kRelocRelative,
@@ -257,8 +253,7 @@ static void notify_gdb_of_unload(soinfo* info) {
rtld_db_dlactivity();
}
-extern "C" void notify_gdb_of_libraries()
-{
+void notify_gdb_of_libraries() {
_r_debug.r_state = RT_ADD;
rtld_db_dlactivity();
_r_debug.r_state = RT_CONSISTENT;
@@ -1689,7 +1684,7 @@ static int soinfo_link_image(soinfo *si)
ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:23.stdio.asc
*/
- if (program_is_setuid) {
+ if (get_AT_SECURE()) {
nullify_closed_stdio();
}
notify_gdb_of_load(si);
@@ -1750,11 +1745,6 @@ static unsigned __linker_init_post_relocation(unsigned **elfdata, unsigned linke
int argc = (int) *elfdata;
char **argv = (char**) (elfdata + 1);
unsigned *vecs = (unsigned*) (argv + argc + 1);
- unsigned *v;
- soinfo *si;
- int i;
- const char *ldpath_env = NULL;
- const char *ldpreload_env = NULL;
/* NOTE: we store the elfdata pointer on a special location
* of the temporary TLS area in order to pass it to
@@ -1773,53 +1763,36 @@ static unsigned __linker_init_post_relocation(unsigned **elfdata, unsigned linke
gettimeofday(&t0, 0);
#endif
- /* Initialize environment functions, and get to the ELF aux vectors table */
+ // Initialize environment functions, and get to the ELF aux vectors table.
vecs = linker_env_init(vecs);
- /* Check auxv for AT_SECURE first to see if program is setuid, setgid,
- has file caps, or caused a SELinux/AppArmor domain transition. */
- for (v = vecs; v[0]; v += 2) {
- if (v[0] == AT_SECURE) {
- /* kernel told us whether to enable secure mode */
- program_is_setuid = v[1];
- goto sanitize;
- }
- }
-
- /* Kernel did not provide AT_SECURE - fall back on legacy test. */
- program_is_setuid = (getuid() != geteuid()) || (getgid() != getegid());
-
-sanitize:
- /* Sanitize environment if we're loading a setuid program */
- if (program_is_setuid) {
- linker_env_secure();
- }
-
debugger_init();
- /* Get a few environment variables */
- {
+ // Get a few environment variables.
#if LINKER_DEBUG
- const char* env;
- env = linker_env_get("DEBUG"); /* XXX: TODO: Change to LD_DEBUG */
- if (env)
+ {
+ const char* env = linker_env_get("LD_DEBUG");
+ if (env != NULL) {
debug_verbosity = atoi(env);
+ }
+ }
#endif
- /* Normally, these are cleaned by linker_env_secure, but the test
- * against program_is_setuid doesn't cost us anything */
- if (!program_is_setuid) {
- ldpath_env = linker_env_get("LD_LIBRARY_PATH");
- ldpreload_env = linker_env_get("LD_PRELOAD");
- }
+ // Normally, these are cleaned by linker_env_init, but the test
+ // doesn't cost us anything.
+ const char* ldpath_env = NULL;
+ const char* ldpreload_env = NULL;
+ if (!get_AT_SECURE()) {
+ ldpath_env = linker_env_get("LD_LIBRARY_PATH");
+ ldpreload_env = linker_env_get("LD_PRELOAD");
}
INFO("[ android linker & debugger ]\n");
DEBUG("%5d elfdata @ 0x%08x\n", pid, (unsigned)elfdata);
- si = soinfo_alloc(argv[0]);
- if(si == 0) {
- exit(-1);
+ soinfo* si = soinfo_alloc(argv[0]);
+ if (si == NULL) {
+ exit(EXIT_FAILURE);
}
/* bootstrap the link map, the main exe always needs to be first */
@@ -1858,7 +1831,7 @@ sanitize:
insert_soinfo_into_debug_map(&linker_soinfo);
/* extract information passed from the kernel */
- while(vecs[0] != 0){
+ while (vecs[0] != 0){
switch(vecs[0]){
case AT_PHDR:
si->phdr = (Elf32_Phdr*) vecs[1];
@@ -1899,12 +1872,12 @@ sanitize:
char errmsg[] = "CANNOT LINK EXECUTABLE\n";
write(2, __linker_dl_err_buf, strlen(__linker_dl_err_buf));
write(2, errmsg, sizeof(errmsg));
- exit(-1);
+ exit(EXIT_FAILURE);
}
soinfo_call_preinit_constructors(si);
- for(i = 0; preloads[i] != NULL; i++) {
+ for (size_t i = 0; preloads[i] != NULL; ++i) {
soinfo_call_constructors(preloads[i]);
}
@@ -2049,7 +2022,7 @@ extern "C" unsigned __linker_init(unsigned **elfdata) {
//
// This situation should never occur unless the linker itself
// is corrupt.
- exit(-1);
+ exit(EXIT_FAILURE);
}
// We have successfully fixed our own relocations. It's safe to run