This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH 1/1] rtld.c: prelink soname mismatch fix
- From: Maninder Singh <maninder1 dot s at samsung dot com>
- To: libc-alpha at sourceware dot org
- Cc: pankaj dot m at samsung dot com, ajeet dot y at samsung dot com, Maninder Singh <maninder1 dot s at samsung dot com>, Vaneet Narang <v dot narang at samsung dot com>
- Date: Mon, 05 Oct 2015 15:44:11 +0530
- Subject: [PATCH 1/1] rtld.c: prelink soname mismatch fix
- Authentication-results: sourceware.org; auth=none
- Dlp-filter: Pass
This patch fixes the issue wherein prelink verification by loader fails
when shared library soname is different from filename.
Method to verify the given issue:
1. Create shared library "libB.so" with same soname "libB.so"
2. Build a program that link to library "libB.so".
#gcc test.c -o test -lB
3. Now replace the original "libB.so" with symlink, like below
#ln -sf libA.so libB.so
(libB.so -> libA.so)
4. When we prelink "test", library list section '.gnu.liblist' contains
entries as below.
0: libA.so 2014-12-02T04:28:40 0x95c929e5 0 0 //SONAME
5. A runtime, prelink verification faile due to mismatched dependency
due to soname issue.
expect libA.so, found /lib/libB.so in dependency order
prelink checking: failed
The issue is prelink fills soname in gnu.liblist section but loader uses
filename for prelink verification during loading instead of soname.
So, now we are comparing soname of a library with .gnu.liblist section of
prelinked executable, after the original filename mismatch occurs.
Signed-off-by: Vaneet Narang <v.narang@samsung.com>
Signed-off-by: Maninder Singh <maninder1.s@samsung.com>
Reviewed-by: Ajeet Yadav <ajeet.y@samsung.com>
Reviewed-by: Doha Hwang <doha.hwang@samsung.com>
---
elf/rtld.c | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/elf/rtld.c b/elf/rtld.c
index 1474c72..24dd07c 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -1927,6 +1927,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
{
ElfW(Lib) *liblist, *liblistend;
struct link_map **r_list, **r_listend, *l;
+ const char *soname;
const char *strtab = (const void *) D_PTR (main_map, l_info[DT_STRTAB]);
assert (main_map->l_info[VALIDX (DT_GNU_LIBLISTSZ)] != NULL);
@@ -1961,7 +1962,14 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
break;
if (! _dl_name_match_p (strtab + liblist->l_name, l))
- break;
+ {
+ if (l->l_info[DT_SONAME] == NULL)
+ break;
+ soname = ((const char *) D_PTR (l, l_info[DT_STRTAB]) +
+ l->l_info[DT_SONAME]->d_un.d_val);
+ if (strcmp(strtab + liblist->l_name, soname) != 0)
+ break;
+ }
++liblist;
}
--
1.7.1