From patchwork Mon Oct 5 10:14:11 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maninder Singh X-Patchwork-Id: 8920 Received: (qmail 116615 invoked by alias); 5 Oct 2015 10:14:58 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 116603 invoked by uid 89); 5 Oct 2015 10:14:57 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=BAYES_00, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: mailout1.samsung.com From: Maninder Singh To: libc-alpha@sourceware.org Cc: pankaj.m@samsung.com, ajeet.y@samsung.com, Maninder Singh , Vaneet Narang Subject: [PATCH 1/1] rtld.c: prelink soname mismatch fix Date: Mon, 05 Oct 2015 15:44:11 +0530 Message-id: <1444040051-3681-1-git-send-email-maninder1.s@samsung.com> DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected 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 Signed-off-by: Maninder Singh Reviewed-by: Ajeet Yadav Reviewed-by: Doha Hwang --- 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; }