From: Navin P <navinp0304@gmail.com>
To: libc-alpha@sourceware.org
Subject: DT_RUNPATH of executable not found when loader and dl_caller is libasan.so
Date: Fri, 26 Feb 2021 22:59:50 +0530 [thread overview]
Message-ID: <CALO2Tq+wv-KDRtE+zN=bd9p0oDJJ6T=6YNQa3aNS6eA7bzGSRw@mail.gmail.com> (raw)
In-Reply-To: <CALO2TqLALAdwci2eFvYb3QZ6K_-2Eg8nu339VQ=23Mmq20jY+g@mail.gmail.com>
Hi,
I sent this to libc-help which seems to
the wrong group.
My scenario is $HOME/package/ contains ./a.out and dso libplugin.so.
Without address sanitizer(asan) libasan.so mode using gcc , if i run
./a.out from $HOME/package i'm able to find libplugin.so and it prints
dlopen succeeded.
Now if i go to the parent directy and cd .. . If i run
./package/a.out , it is able to find and prints dlopen succeeded .
Everything is good until here.
libplugin.so is an empty shared object without asan..
#include<dlfcn.h>
#include<cstdio>
int main(){
void *handle=dlopen("libplugin.so",RTLD_NOW);
if(handle!=NULL){
printf("dlopen succeeded\n");
} else {
printf("dlopen failed\n");
}
return 0;
}
Now i compile the example and .so with -fsanitize=address. Now in the
case of running a.out from $HOME/package , it prints dlopen
succeeded.
Now if i do cd.. and run ./package/a.out from $HOME it fails and
prints dlopen failed. This is because the loader is changed to
libasan.so and this
time the DT_RUNPATH is checked for RUNPATH of libasan. This works for
RPATH because we check for all the list of loaders and we find the
base loader whose rpath is $HOME/package. But in case of DT_RUNPATH we
don't .
I think an additional lookup needs to be performed after the old
RUNPATH code in dl-load.c which looks up for
GL(dl_ns)[LM_ID_BASE]._ns_loaded when fd==-1.
I've tested this patch and it works fine for me.
From d2cb9bba3de58af3516eb7099d0452e2ee6365d2 Mon Sep 17 00:00:00 2001
From: Navin P <navinp0304@gmail.com>
Date: Mon, 22 Feb 2021 15:02:00 +0530
Subject: [PATCH] If executables are compiled with asan, it should perform
additional LM_ID_BASE D_RUNPATH also.
---
elf/dl-load.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 9e2089cfaa..fe88c8c9ea 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -2161,6 +2161,34 @@ _dl_map_object (struct link_map *loader, const
char *name,
&loader->l_runpath_dirs, &realname, &fb, loader,
LA_SER_RUNPATH, &found_other_class);
+ /*
+ * This is not transitive dependency.It it just an additional
+ * lookup into executable/dso runpath when loader is different
+ * from LM_ID_BASE loader.
+ * In usual cases like direct call to executable, then main_map
+ * is same as loader and no lookup is performed.
+ * In cases like libasan.so being the parent caller with dl_caller
+ * set to libasan.so which is called by GL(dls_ns)[LIM_ID_BASE],
+ * we need to additionally search the executable/dso link_map
+ * other than loader link_map which is performed above.
+ */
+ struct link_map *main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
+
+ /* Look at the RUNPATH information for this binary using main_map.
+ * This lookup is only done when the binary is in namespace 0.
+ * For nested namespaces from dlmopen LM_ID_NEWLM, we don't search
+ * in namespace 0 because it is detached from LM_ID_BASE.
+ * In that case lookup is done in the callers RUNPATH above.
+ */
+
+ if (fd == -1 && (nsid == LM_ID_BASE ) && main_map != NULL
+ && main_map != loader
+ && cache_rpath (main_map, &main_map->l_runpath_dirs,
+ DT_RUNPATH, "RUNPATH"))
+ fd = open_path (name, namelen, mode,
+ &main_map->l_runpath_dirs, &realname, &fb, main_map,
+ LA_SER_RUNPATH, &found_other_class);
+
if (fd == -1)
{
realname = _dl_sysdep_open_object (name, namelen, &fd);
--
2.25.1
next parent reply other threads:[~2021-02-26 17:29 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CALO2TqLALAdwci2eFvYb3QZ6K_-2Eg8nu339VQ=23Mmq20jY+g@mail.gmail.com>
2021-02-26 17:29 ` Navin P [this message]
2021-03-03 17:51 ` Florian Weimer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CALO2Tq+wv-KDRtE+zN=bd9p0oDJJ6T=6YNQa3aNS6eA7bzGSRw@mail.gmail.com' \
--to=navinp0304@gmail.com \
--cc=libc-alpha@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).