public inbox for glibc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug dynamic-link/28927] New: preloaded dlopen and DT_RUNPATH
@ 2022-02-28  8:50 valery_reznic at yahoo dot com
  2022-02-28 14:39 ` [Bug dynamic-link/28927] " fweimer at redhat dot com
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: valery_reznic at yahoo dot com @ 2022-02-28  8:50 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=28927

            Bug ID: 28927
           Summary: preloaded dlopen and DT_RUNPATH
           Product: glibc
           Version: unspecified
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: dynamic-link
          Assignee: unassigned at sourceware dot org
          Reporter: valery_reznic at yahoo dot com
  Target Milestone: ---

Created attachment 13998
  --> https://sourceware.org/bugzilla/attachment.cgi?id=13998&action=edit
attachement contaiins smal repro for the problem

I have to hook dlopen

Greatly simplified dlopen in the preloaded library looks like:
void *dlopen(const char *filename, int flag)
{
   printf("Preloaded dlopen\n");
   return orig_dlopen(filename, flag)
}

For a while all worked as expected, but then turns out that if executable has
DT_RUNPATH set (and this path actually used to find library)
then executable unable to load library.

HOW IT WORKS WITHOUT LD_PRELOAD?                                             

Let say,our dynamically linked executable was build with DT_RUNPATH and it
calls dlopen function.

So what happened when executable run?                                           

1. Executable calls dlopen function.                                            

2. dlopen function from libc detects that it was called from the executable.    

3. Executable's DT_RUNPATAH used to locate shared object that about to be
dlopen'ed.

4. Everything is well.  


HOW IT DOES NOT WORK WITH LD_PRELOAD                                        

Again, our dynamically linked executable was build with DT_RUNPATH and it calls
dlopen function.
But now it run with LD_PRELOAD'ed library (preload.so) and even worse,          
this library defines dlopen function.                                           

dlopen function in the preloaded library looks like following:                  

void *dlopen(const char *filename, int flag)                                    
{                                                                               
       printf("It's dlopen hook");                                             
       return dlopen_orig(filename, flag);                                     
}                                                                               

So what happened when executable run?                                           

1. Executable calls dlopen function.                                            

2. dlopen function called not from libc, but from preloaded library.

3. dlopen function from preloaded library calls dlopen function from libc.      

4. dlopen from libc detects that it was called from preload.so                  

5. preload.so does not have DT_RUNPATH, so no DT_RUNPATH will be used to locate
dlopen'ed library.                                                              

6. As a result library may be not found or different library loaded from the
wrong path


I made a pretty complex dance changing internal ld-linux.so structs to trick it
think that dlopen was called from executable, and not from preloaded library
and it even worked!
While I am quite proud of this code, IMO it will be better and much, much more
simple to have in glibc function dlopen_with_caller_address or something like
this.

dlopen_with_caller_address(const char *filename, int flag, const void *address)

This function instead of detecting who calls it, will just use 'address'
parameter.
Then hook in example can looks like

void *dlopen(const char *filename, int flag)                                    
{                                                                               
       printf("It's dlopen hook");                                             
       return dlopen_orig_with_caller(filename,
flag,__builtin_extract_return_addr(__builtin_return_address(0)))  );            
}                                                                               


Notes: 
1. If dlopen will be able to somehow auotodetect who original caller is it will
be even better then dlopen_with_caller_address
2. Of course same goes for dlmopen.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug dynamic-link/28927] preloaded dlopen and DT_RUNPATH
  2022-02-28  8:50 [Bug dynamic-link/28927] New: preloaded dlopen and DT_RUNPATH valery_reznic at yahoo dot com
@ 2022-02-28 14:39 ` fweimer at redhat dot com
  2022-02-28 19:43 ` valery_reznic at yahoo dot com
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: fweimer at redhat dot com @ 2022-02-28 14:39 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=28927

Florian Weimer <fweimer at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
                 CC|                            |fweimer at redhat dot com
   Last reconfirmed|                            |2022-02-28
             Status|UNCONFIRMED                 |WAITING

--- Comment #1 from Florian Weimer <fweimer at redhat dot com> ---
How do you obtain the pointer to the orig_dlopen?

At present, if you need to hook dlopen, the most flexible way is writing an
audit (LD_AUDIT) module.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug dynamic-link/28927] preloaded dlopen and DT_RUNPATH
  2022-02-28  8:50 [Bug dynamic-link/28927] New: preloaded dlopen and DT_RUNPATH valery_reznic at yahoo dot com
  2022-02-28 14:39 ` [Bug dynamic-link/28927] " fweimer at redhat dot com
@ 2022-02-28 19:43 ` valery_reznic at yahoo dot com
  2022-02-28 19:52 ` fweimer at redhat dot com
  2022-02-28 20:09 ` valery_reznic at yahoo dot com
  3 siblings, 0 replies; 5+ messages in thread
From: valery_reznic at yahoo dot com @ 2022-02-28 19:43 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=28927

--- Comment #2 from Valery <valery_reznic at yahoo dot com> ---
I got orig_dlopen from dlsym(RTLD_NEXT, "dlopen")

While LD_AUDIT option is interesting I prefer stay with LD_PRELOAD.

By the way I had one more look at the glibc sources, it has __dlopen function
with third argument DL_CALLER - exactly what I need. The trouble is this
function is not exported :(

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug dynamic-link/28927] preloaded dlopen and DT_RUNPATH
  2022-02-28  8:50 [Bug dynamic-link/28927] New: preloaded dlopen and DT_RUNPATH valery_reznic at yahoo dot com
  2022-02-28 14:39 ` [Bug dynamic-link/28927] " fweimer at redhat dot com
  2022-02-28 19:43 ` valery_reznic at yahoo dot com
@ 2022-02-28 19:52 ` fweimer at redhat dot com
  2022-02-28 20:09 ` valery_reznic at yahoo dot com
  3 siblings, 0 replies; 5+ messages in thread
From: fweimer at redhat dot com @ 2022-02-28 19:52 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=28927

Florian Weimer <fweimer at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |DUPLICATE
             Status|WAITING                     |RESOLVED

--- Comment #3 from Florian Weimer <fweimer at redhat dot com> ---
(In reply to Valery from comment #2)
> I got orig_dlopen from dlsym(RTLD_NEXT, "dlopen")

Ah, right, this particular challenge only exists for dlsym.

> While LD_AUDIT option is interesting I prefer stay with LD_PRELOAD.
> 
> By the way I had one more look at the glibc sources, it has __dlopen
> function with third argument DL_CALLER - exactly what I need. The trouble is
> this function is not exported :(

Okay, it turns out we have an older RFE for that. Note that even if we pushed
an implementation of this function today (hypothetically), it would be several
years until it will be in the hands of your users, so maybe you should
reconsider LD_AUDIT.

*** This bug has been marked as a duplicate of bug 28008 ***

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug dynamic-link/28927] preloaded dlopen and DT_RUNPATH
  2022-02-28  8:50 [Bug dynamic-link/28927] New: preloaded dlopen and DT_RUNPATH valery_reznic at yahoo dot com
                   ` (2 preceding siblings ...)
  2022-02-28 19:52 ` fweimer at redhat dot com
@ 2022-02-28 20:09 ` valery_reznic at yahoo dot com
  3 siblings, 0 replies; 5+ messages in thread
From: valery_reznic at yahoo dot com @ 2022-02-28 20:09 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=28927

--- Comment #4 from Valery <valery_reznic at yahoo dot com> ---
Name dlopen_from looks better then __dlopen.


As I mentioned early in this ticket , I already found a way - yes too
complicated for my liking, but working nevertheless, to make dlopen work as
expected with LD_PRELOAD.

Idea with LD_AUDIT is intersting I will check it, thanks.

Regardless, I think that dlopen_from (and dlmopen_from) worth having.
And almost nothing should be done, so lets hope...

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-02-28 20:09 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-28  8:50 [Bug dynamic-link/28927] New: preloaded dlopen and DT_RUNPATH valery_reznic at yahoo dot com
2022-02-28 14:39 ` [Bug dynamic-link/28927] " fweimer at redhat dot com
2022-02-28 19:43 ` valery_reznic at yahoo dot com
2022-02-28 19:52 ` fweimer at redhat dot com
2022-02-28 20:09 ` valery_reznic at yahoo dot com

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).