public inbox for glibc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libc/11754] New: RFE: dlopen of ET_EXEC file
@ 2010-06-24 23:21 jreiser at BitWagon dot com
  2010-06-24 23:24 ` [Bug libc/11754] " roland at gnu dot org
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: jreiser at BitWagon dot com @ 2010-06-24 23:21 UTC (permalink / raw)
  To: glibc-bugs

Request For Enhancement (RFE):  Please enhance dlopen() of an ET_EXEC file to
work in many cases.  Currently dlopen() of an ET_EXEC file always fails with the
dlerror() string "cannot dynamically load executable".  However, the test
program below shows by example that dlopen() of the corresponding ET_DYN file
(just change Elf32_Ehdr.e_type from ET_EXEC to ET_DYN) can give useful results.
 In particular, the file is mapped into the address space, along with all its
DT_NEEDED dependencies, and can be invoked successfully at its .e_entry point. 
If the handle returned by dlopen() were not NULL, then dlsym() probably would
work, too.  All of these are useful properties that would be nice to have. 
Thank you.

-----hello.c
#include <stdio.h>

int
main(int argc, char *argv[])
{
	printf("Hello world.\n");
	return 0;
}
-----dlopen-exec.c
/* Show that dlopen of an ET_EXEC file would mostly work, at least if the
 * address space that is requested is currently unoccupied.
 *
 * Compile and run via:
 *    gcc -m32 -g -o hello32 hello.c
 *    gcc -m32 -g -o dlopen-exec -Ttext-segment=0x0a000000 dlopen-exec.c -ldl
 *    ./dlopen-exec
 * -Ttext-segment=0x0a000000 leaves enough room for the default 0x08048000.
 */

#include <dlfcn.h>
#include <elf.h>
#include <sys/fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

/* i386 code to invoke an ET_EXEC image that has been loaded into memory. */
void
raw_start(Elf32_Addr entry, int original_argc, char const **original_argv)
{
	asm("mov 2*4(%ebp),%eax");  /* entry */
	asm("mov 3*4(%ebp),%ecx");  /* original_argc */
	asm("mov 4*4(%ebp),%edx");  /* original_argv */
	asm("mov %edx,%esp");  /* Trim stack. */
	asm("push %ecx");      /* New argc */
	asm("sub %edx,%edx");  /* no rtld_fini function */
	asm("jmp *%eax");      /* Goto entry. */
}

char fname[] = "/tmp/dlopen-exec-XXXXXX";

int
main(int argc, char const *argv[])
{
	/* Try to dlopen an ET_EXEC file. */
	void *handle = dlopen("./hello32", RTLD_LAZY);
	if (0==handle) {
		fprintf(stderr, "dlopen ./hello32 failed:%s\n", dlerror());
	}

	/* Write a new file that is the same except for ET_DYN. */
	/* Error checking has been omitted in this section. */
	int const fdi = open("./hello32", O_RDONLY);
	struct stat sb;
	fstat(fdi, &sb);
	Elf32_Ehdr *const ehdr = malloc(sb.st_size);
	read(fdi, ehdr, sb.st_size);
	close(fdi);
	ehdr->e_type = ET_DYN;
	int const fdo = mkstemp(fname);
	write(fdo, ehdr, sb.st_size);
	close(fdo);

	/* Try to dlopen the ET_DYN file. */
	void *h2 = dlopen(fname, RTLD_LAZY);
	if (0==handle) {
		fprintf(stderr, "dlopen failed:%s\n", dlerror());
	}
	else {
		fprintf(stderr, "Success: %s\n", fname);
	}
	unlink(fname);  /* Clean up. */

	/* dlopen() "succeeded" even though the return value was 0.
	 * Demonstrate success by executing the loaded program.
	 */
	raw_start(ehdr->e_entry, argc, argv);

	return 0;
}
-----console log
$ gcc -m32 -g -o hello32 hello.c
$ gcc -m32 -g -o dlopen-exec -Ttext-segment=0x0a000000 dlopen-exec.c -ldl
$ ./dlopen-exec
dlopen ./hello32 failed:./hello32: cannot dynamically load executable
dlopen failed:(null)
Hello world.
$ 
-----

-- 
           Summary: RFE: dlopen of ET_EXEC file
           Product: glibc
           Version: 2.12
            Status: NEW
          Severity: normal
          Priority: P2
         Component: libc
        AssignedTo: drepper at redhat dot com
        ReportedBy: jreiser at BitWagon dot com
                CC: glibc-bugs at sources dot redhat dot com


http://sourceware.org/bugzilla/show_bug.cgi?id=11754

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


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

* [Bug libc/11754] RFE: dlopen of ET_EXEC file
  2010-06-24 23:21 [Bug libc/11754] New: RFE: dlopen of ET_EXEC file jreiser at BitWagon dot com
@ 2010-06-24 23:24 ` roland at gnu dot org
  2010-06-25  1:32 ` jreiser at BitWagon dot com
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: roland at gnu dot org @ 2010-06-24 23:24 UTC (permalink / raw)
  To: glibc-bugs


------- Additional Comments From roland at gnu dot org  2010-06-24 23:24 -------
Is there a reason you can't just build an executable you want to use this way
with -fPIE -pie?  A PIE is both an executable and an ET_DYN.

The usual handling for ET_EXEC files uses MAP_FIXED, which will clobber any
existing mappings.  So it is dangerous to blindly load an ET_EXEC file.  There
is not really any very good way for dlopen to determine that the regions used by
the particular ET_EXEC file are not already mapped.

-- 


http://sourceware.org/bugzilla/show_bug.cgi?id=11754

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


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

* [Bug libc/11754] RFE: dlopen of ET_EXEC file
  2010-06-24 23:21 [Bug libc/11754] New: RFE: dlopen of ET_EXEC file jreiser at BitWagon dot com
  2010-06-24 23:24 ` [Bug libc/11754] " roland at gnu dot org
@ 2010-06-25  1:32 ` jreiser at BitWagon dot com
  2010-06-25  2:27 ` jreiser at BitWagon dot com
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: jreiser at BitWagon dot com @ 2010-06-25  1:32 UTC (permalink / raw)
  To: glibc-bugs


------- Additional Comments From jreiser at BitWagon dot com  2010-06-25 01:32 -------
My application is an auditor (checker/verifier) and the target application
already has been built by someone else, usually without -fPIE -pie.

> "The usual handling for ET_EXEC files uses MAP_FIXED, which will clobber any
existing mappings."
Yes.  However, instead of calling mmap(.p_vaddr,,,MAP_FIXED,,):  omit the
MAP_FIXED, then compare the return value with .p_vaddr.  If the two addresses
are equal, then the space was available and has been filled with the correct
contents.  (As demonstrated by the test case, that is essentially the main
effect of  calling dlopen on the original file but with .e_type=ET_DYN.)  If the
return value from mmap does not equal .p_vaddr, then the pages weren't available
for some reason, and you get to decide what to do.

-- 


http://sourceware.org/bugzilla/show_bug.cgi?id=11754

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


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

* [Bug libc/11754] RFE: dlopen of ET_EXEC file
  2010-06-24 23:21 [Bug libc/11754] New: RFE: dlopen of ET_EXEC file jreiser at BitWagon dot com
  2010-06-24 23:24 ` [Bug libc/11754] " roland at gnu dot org
  2010-06-25  1:32 ` jreiser at BitWagon dot com
@ 2010-06-25  2:27 ` jreiser at BitWagon dot com
  2010-06-29 17:36 ` jreiser at BitWagon dot com
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: jreiser at BitWagon dot com @ 2010-06-25  2:27 UTC (permalink / raw)
  To: glibc-bugs


------- Additional Comments From jreiser at BitWagon dot com  2010-06-25 02:26 -------
Current behavior is actually even better: tantalizingly close!  Fixing the
copy+paste error:
-----
 	void *h2 = dlopen(fname, RTLD_LAZY);
-	if (0==handle) {
+       if (0==h2) {
		fprintf(stderr, "dlopen failed:%s\n", dlerror());
-----
then running:
-----
dlopen ./hello32 failed:./hello32: cannot dynamically load executable
Success: /tmp/dlopen-exec-v66w8C
Hello world.
-----

Therefore "masquerading" the ET_EXEC as ET_DYN essentially works as long as the
address space is available and the operating system is in a good mood (honors
the hint when the first parameter of mmap is not NULL.)  Many systems honor the
hint as a matter of policy [default, or at least administratively chosen], so
I'd like to take advantage of those cases.

-- 


http://sourceware.org/bugzilla/show_bug.cgi?id=11754

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


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

* [Bug libc/11754] RFE: dlopen of ET_EXEC file
  2010-06-24 23:21 [Bug libc/11754] New: RFE: dlopen of ET_EXEC file jreiser at BitWagon dot com
                   ` (2 preceding siblings ...)
  2010-06-25  2:27 ` jreiser at BitWagon dot com
@ 2010-06-29 17:36 ` jreiser at BitWagon dot com
  2010-06-29 17:38 ` jreiser at BitWagon dot com
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: jreiser at BitWagon dot com @ 2010-06-29 17:36 UTC (permalink / raw)
  To: glibc-bugs


------- Additional Comments From jreiser at BitWagon dot com  2010-06-29 17:35 -------
Created an attachment (id=4863)
 --> (http://sourceware.org/bugzilla/attachment.cgi?id=4863&action=view)
patch to elf/dl-load.c

This patch to elf/dl-load.c implements the requested enhancement.

-- 


http://sourceware.org/bugzilla/show_bug.cgi?id=11754

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


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

* [Bug libc/11754] RFE: dlopen of ET_EXEC file
  2010-06-24 23:21 [Bug libc/11754] New: RFE: dlopen of ET_EXEC file jreiser at BitWagon dot com
                   ` (3 preceding siblings ...)
  2010-06-29 17:36 ` jreiser at BitWagon dot com
@ 2010-06-29 17:38 ` jreiser at BitWagon dot com
  2010-09-21 14:17 ` pasky at suse dot cz
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: jreiser at BitWagon dot com @ 2010-06-29 17:38 UTC (permalink / raw)
  To: glibc-bugs


------- Additional Comments From jreiser at BitWagon dot com  2010-06-29 17:38 -------
Created an attachment (id=4864)
 --> (http://sourceware.org/bugzilla/attachment.cgi?id=4864&action=view)
revised testcase (for x86_64)

This revised testcase allows for success of the requested enhancement.

-- 


http://sourceware.org/bugzilla/show_bug.cgi?id=11754

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


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

* [Bug libc/11754] RFE: dlopen of ET_EXEC file
  2010-06-24 23:21 [Bug libc/11754] New: RFE: dlopen of ET_EXEC file jreiser at BitWagon dot com
                   ` (4 preceding siblings ...)
  2010-06-29 17:38 ` jreiser at BitWagon dot com
@ 2010-09-21 14:17 ` pasky at suse dot cz
  2010-09-21 16:55 ` jreiser at BitWagon dot com
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: pasky at suse dot cz @ 2010-09-21 14:17 UTC (permalink / raw)
  To: glibc-bugs


------- Additional Comments From pasky at suse dot cz  2010-09-21 14:17 -------
The patch looks good to me! However, there are numerous style issues; the source
is usually aligned by opening parenthesis, and boolean operators are always at
the beginning of the next line. Also, I know why you use const == var, but
everywhere else var == const is used, so it would be better to stick with that.

The issues are in the second if condition, and I think the new mappref
initializer is also nearly unreadable now and would benefit from splitting to
multiple expressions.

-- 


http://sourceware.org/bugzilla/show_bug.cgi?id=11754

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


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

* [Bug libc/11754] RFE: dlopen of ET_EXEC file
  2010-06-24 23:21 [Bug libc/11754] New: RFE: dlopen of ET_EXEC file jreiser at BitWagon dot com
                   ` (5 preceding siblings ...)
  2010-09-21 14:17 ` pasky at suse dot cz
@ 2010-09-21 16:55 ` jreiser at BitWagon dot com
  2010-10-04  2:49 ` drepper dot fsp at gmail dot com
  2010-10-04 15:42 ` jreiser at BitWagon dot com
  8 siblings, 0 replies; 10+ messages in thread
From: jreiser at BitWagon dot com @ 2010-09-21 16:55 UTC (permalink / raw)
  To: glibc-bugs


------- Additional Comments From jreiser at BitWagon dot com  2010-09-21 16:54 -------
Created an attachment (id=4997)
 --> (http://sourceware.org/bugzilla/attachment.cgi?id=4997&action=view)
revised patch to elf/dl-load.c

revised patch (for coding style)

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
Attachment #4863 is|0                           |1
           obsolete|                            |


http://sourceware.org/bugzilla/show_bug.cgi?id=11754

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


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

* [Bug libc/11754] RFE: dlopen of ET_EXEC file
  2010-06-24 23:21 [Bug libc/11754] New: RFE: dlopen of ET_EXEC file jreiser at BitWagon dot com
                   ` (6 preceding siblings ...)
  2010-09-21 16:55 ` jreiser at BitWagon dot com
@ 2010-10-04  2:49 ` drepper dot fsp at gmail dot com
  2010-10-04 15:42 ` jreiser at BitWagon dot com
  8 siblings, 0 replies; 10+ messages in thread
From: drepper dot fsp at gmail dot com @ 2010-10-04  2:49 UTC (permalink / raw)
  To: glibc-bugs


------- Additional Comments From drepper dot fsp at gmail dot com  2010-10-04 02:48 -------
I won't change this because it can never work reliably in all situations where 
such a call can be made.  There can be address space conflicts and they cannot 
even be detected.  This inevitably will lead to problems.  There are very good 
reasons why this never was imagined to be implemented.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |WONTFIX


http://sourceware.org/bugzilla/show_bug.cgi?id=11754

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


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

* [Bug libc/11754] RFE: dlopen of ET_EXEC file
  2010-06-24 23:21 [Bug libc/11754] New: RFE: dlopen of ET_EXEC file jreiser at BitWagon dot com
                   ` (7 preceding siblings ...)
  2010-10-04  2:49 ` drepper dot fsp at gmail dot com
@ 2010-10-04 15:42 ` jreiser at BitWagon dot com
  8 siblings, 0 replies; 10+ messages in thread
From: jreiser at BitWagon dot com @ 2010-10-04 15:42 UTC (permalink / raw)
  To: glibc-bugs


------- Additional Comments From jreiser at BitWagon dot com  2010-10-04 15:42 -------
Please explain how an undetected conflict over address space could arise.  The
interval of pages requested by mmap is the convex hull of all of the PT_LOAD, so
the interval contains each PT_LOAD.  The first argument to mmap is the address
of the lowest page in the range, and the flags argument _omits_ MAP_FIXED.  If
the kernel's allocation policy honors the suggested placement, then the kernel
believes that no page in the requested range was occupied before.  If any page
in the requested range _was_ occupied before, then the kernel will choose some
other address, else return MAP_FAILED.  In all cases, comparing the desired
lowest address to the return value of mmap() correctly determines success or
failure, including any conflicts that might exist.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|WONTFIX                     |


http://sourceware.org/bugzilla/show_bug.cgi?id=11754

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


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

end of thread, other threads:[~2010-10-04 15:42 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-24 23:21 [Bug libc/11754] New: RFE: dlopen of ET_EXEC file jreiser at BitWagon dot com
2010-06-24 23:24 ` [Bug libc/11754] " roland at gnu dot org
2010-06-25  1:32 ` jreiser at BitWagon dot com
2010-06-25  2:27 ` jreiser at BitWagon dot com
2010-06-29 17:36 ` jreiser at BitWagon dot com
2010-06-29 17:38 ` jreiser at BitWagon dot com
2010-09-21 14:17 ` pasky at suse dot cz
2010-09-21 16:55 ` jreiser at BitWagon dot com
2010-10-04  2:49 ` drepper dot fsp at gmail dot com
2010-10-04 15:42 ` jreiser at BitWagon 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).