From 1fac669cf3cf9733cc5d4c03a9568c150761fc1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Bednarski?= Date: Sat, 14 May 2016 17:22:21 +0200 Subject: [PATCH] ltrace: Fix incompatibilities with Android linker - Find libraries in LD_LIBRARY_PATH if relative path is found in debug link_map - Skip main executable - Skip /system/bin/linker and [vdso] - Only set proc->e_machine once, as it might be set wrongly if we later try to load library that we couldn't find --- disabled-packages/ltrace/ltrace-elf.c.patch | 23 +++++++- .../ltrace/sysdeps-linux-gnu-proc.c.patch | 59 +++++++++++++++++++ 2 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 disabled-packages/ltrace/sysdeps-linux-gnu-proc.c.patch diff --git a/disabled-packages/ltrace/ltrace-elf.c.patch b/disabled-packages/ltrace/ltrace-elf.c.patch index eaa181256..7e5f82492 100644 --- a/disabled-packages/ltrace/ltrace-elf.c.patch +++ b/disabled-packages/ltrace/ltrace-elf.c.patch @@ -1,6 +1,8 @@ ---- ltrace-2def9f1217374cc8371105993003b2c663aefda7/ltrace-elf.c 2016-04-11 21:30:04.000000000 +0200 -+++ src/ltrace-elf.c 2016-05-07 21:23:17.999754862 +0200 -@@ -423,7 +423,9 @@ +diff --git a/ltrace-elf.c b/ltrace-elf.c +index f439cb0..60f1941 100644 +--- a/ltrace-elf.c ++++ b/ltrace-elf.c +@@ -423,7 +423,9 @@ ltelf_destroy(struct ltelf *lte) debug(DEBUG_FUNCTION, "close_elf()"); elf_end(lte->elf); close(lte->fd); @@ -11,3 +13,18 @@ } static void +@@ -1149,9 +1151,11 @@ read_module(struct library *lib, struct process *proc, + * determine whether ABI is supported. This is to get + * reasonable error messages when trying to run 64-bit binary + * with 32-bit ltrace. It is desirable to preserve this. */ +- proc->e_machine = lte.ehdr.e_machine; +- proc->e_class = lte.ehdr.e_ident[EI_CLASS]; +- get_arch_dep(proc); ++ if (proc->e_machine == 0) { ++ proc->e_machine = lte.ehdr.e_machine; ++ proc->e_class = lte.ehdr.e_ident[EI_CLASS]; ++ get_arch_dep(proc); ++ } + + /* Find out the base address. For PIE main binaries we look + * into auxv, otherwise we scan phdrs. */ diff --git a/disabled-packages/ltrace/sysdeps-linux-gnu-proc.c.patch b/disabled-packages/ltrace/sysdeps-linux-gnu-proc.c.patch new file mode 100644 index 000000000..af2d7c189 --- /dev/null +++ b/disabled-packages/ltrace/sysdeps-linux-gnu-proc.c.patch @@ -0,0 +1,59 @@ +diff --git a/sysdeps/linux-gnu/proc.c b/sysdeps/linux-gnu/proc.c +index 953fd86..bdb96cb 100644 +--- a/sysdeps/linux-gnu/proc.c ++++ b/sysdeps/linux-gnu/proc.c +@@ -524,9 +524,53 @@ crawl_linkmap(struct process *proc, struct lt_r_debug_64 *dbg) + || strcmp(lib_name, "linux-vdso.so.1") == 0 + || strcmp(lib_name, "linux-gate.so.1") == 0 + || strcmp(lib_name, "linux-vdso32.so.1") == 0 +- || strcmp(lib_name, "linux-vdso64.so.1") == 0) ++ || strcmp(lib_name, "linux-vdso64.so.1") == 0 ++ || strcmp(lib_name, "[vdso]") == 0 ++ /* Android linker includes itself in list of libraries ++ * on GNU linker it appears as empty string */ ++ || strcmp(lib_name, "/system/bin/linker") == 0 ++ || strcmp(lib_name, "/system/bin/linker64") == 0) + continue; + ++ /* On Android main executable is included in library list ++ * On GNU it appears as empty string */ ++ if (rlm.l_prev == 0 && strstr(lib_name, ".so") == NULL) { ++ continue; ++ } ++ ++ /* Android < 6 provides just library name without full path, ++ * will find full path ourselves */ ++ if (lib_name[0] != '/') { ++ char local_path[1024]; ++ /* Include path from LD_LIBRARY_PATH */ ++ const char *path = getenv("LD_LIBRARY_PATH"); ++ if (path) { ++ strlcpy(local_path, path, sizeof(local_path)); ++ } else { ++ local_path[0] = '\0'; ++ } ++ /* Include default path (hardcoded in /system/bin/linker) */ ++ strlcat( ++ local_path, ++ select_32_64(proc, ":/vendor/lib:/system/lib", ":/vendor/lib64:/system/lib64"), ++ sizeof(local_path) ++ ); ++ ++ char *local_path_ptr = local_path; ++ const char *tested_path; ++ char full_lib_name[BUFSIZ]; ++ while ((tested_path = strsep(&local_path_ptr, ":"))) { ++ if (tested_path[0] == '\0') { ++ continue; ++ } ++ snprintf(full_lib_name, sizeof(full_lib_name), "%s/%s", tested_path, lib_name); ++ if (access(full_lib_name, F_OK) == 0) { ++ strlcpy(lib_name, full_lib_name, sizeof(lib_name)); ++ break; ++ } ++ } ++ } ++ + /* Do we have that library already? */ + if (proc_each_library(proc, NULL, library_with_key_cb, &key)) + continue;