Bug#650234: Use chroot's ld.so to do loading?
repen 650234 quit I guess I'm wondering whether I should be letting #650234 close and we need a separate bug for the current phase... The provided explanation of the status does not make sense. The explanation I can come up with is the wrapping is working, except around shell scripts. For shell scripts you would have the problem of arguments: /lib/ld-linux.so.2 shell.sh which won't work. I'm guessing you'll need to scan executables so the right one is invoked (the fakechroot()'s installed utility may be later than the system one). -- (\___(\___(\__ --= 8-) EHM =-- __/)___/)___/) \BS (| ehem+sig...@m5p.com PGP 87145445 |) / \_CS\ | _ -O #include stddisclaimer.h O- _ | / _/ 8A19\___\_|_/58D2 7E3D DDF4 7BA6 -PGP- 41D1 B375 37D0 8714\_|_/___/5445 -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org
Bug#650234: Use chroot's ld.so to do loading?
On Wed, Nov 27, 2013 at 10:15:19PM +0100, Piotr Roszatycki wrote: 2012/10/24 Jonathan Nieder jrnie...@gmail.com: Thanks. Indeed, ideally fakechroot's execve should look up the interpreter filename from the ELF .interp section, map it according to the faked chroot, and set argv[0]. The hard part is the ELF parsing. It doesn't work correctly: 1. The glibc dynamic loader can't change argv[0] to other value than the file name. It means that some apps are broken, ie. busybox. See https://sourceware.org/bugzilla/show_bug.cgi?id=16124 This means this particular avenue of replacing argv[0] isn't open, but how do you claim busybox is broken without argv[0] being replaced? Your proposed feature for the runtime linker would allow for argv[0] being replaced, but not being able to replace argv[0] with the passed value shouldn't break anything (and a quick check indicates busybox works just fine without it). Being able to replace argv[0] would mean could get at busybox's `ls` or `sh` personalities without having the requisite symbolic links. Each command implemented by busybox is accompanied by a symbolic link to the busybox binary (/bin/ls - busybox, /bin/sh - busybox. /usr/bin/expr - /bin/busybox, et al). Now, the weakness of my solution without replacing argv[0] is merely that the executed program sees the full path, but busybox deals with this just fine. Normally if I type `ls -l /` into a shell, the program will see as its arguments: { ls, -l, / } without the capability the program will instead see: { /bin/ls, -l, / }, mainly argv[0] has the full path instead of just the filename. Any program that changes behavior based on argv[0] *should* be striping everything up to the last '/', but I wouldn't be surprised if some fail to do this (but busybox isn't one of those). I dislike that executed programs see something different than if they were called normally, but this shouldn't effect anything. My biggest concern is this uses additional space in the environment and *might* cause issues if someone was right up against the limits (hello, xargs). 2. Using dynamic loader directly from command line is possible but the loader is less stable and coredumps sometimes. You can test it already, eg. calling FAKECHROOT_ELFLOADER=/lib64/ld-linux-x86-64.so.2 from test directory of fakechroot source. You should expect that debootstrap environment can be created but calling debian/rules or even ./configure in such environment fails. Hmm... Two explanations come up for this. Is the debootstrap environment i386, or amd64? I'm unsure of whether the amd64 runtime loader can handle loading i386 binaries (I *hope* it isn't a mixed environment, but this could be a problem). Second, this may be an issue of shell scripts. I wouldn't be surprised if both of these were issues. Unfortunately this reads like an issue where you're going to have to look at the file being executed and behave appropriately, at least shell scripts are easy to handle. Perhaps there is another possibility: to change .interp section for every binary file in fake chroot environment: off-line or even on-the-fly. I think about similar to chrpath tool which can change another ELF section. I suspect you're overthinking the problem. Thank you for taking on this bug, for the right situations fakechroot is a very handy tool. -- (\___(\___(\__ --= 8-) EHM =-- __/)___/)___/) \BS (| ehem+sig...@m5p.com PGP 87145445 |) / \_CS\ | _ -O #include stddisclaimer.h O- _ | / _/ 8A19\___\_|_/58D2 7E3D DDF4 7BA6 -PGP- 41D1 B375 37D0 8714\_|_/___/5445 -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org
Bug#650234: Use chroot's ld.so to do loading?
2012/10/24 Jonathan Nieder jrnie...@gmail.com: Thanks. Indeed, ideally fakechroot's execve should look up the interpreter filename from the ELF .interp section, map it according to the faked chroot, and set argv[0]. The hard part is the ELF parsing. It doesn't work correctly: 1. The glibc dynamic loader can't change argv[0] to other value than the file name. It means that some apps are broken, ie. busybox. See https://sourceware.org/bugzilla/show_bug.cgi?id=16124 2. Using dynamic loader directly from command line is possible but the loader is less stable and coredumps sometimes. You can test it already, eg. calling FAKECHROOT_ELFLOADER=/lib64/ld-linux-x86-64.so.2 from test directory of fakechroot source. You should expect that debootstrap environment can be created but calling debian/rules or even ./configure in such environment fails. Perhaps there is another possibility: to change .interp section for every binary file in fake chroot environment: off-line or even on-the-fly. I think about similar to chrpath tool which can change another ELF section. -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org
Bug#650234: Use chroot's ld.so to do loading?
unmerge 626482 reassign 650234 fakechroot 2.15-1 severity 650234 important tags 650234 + upstream quit Elliott Mitchell wrote: user@host:/$ ls Segmentation fault user@host:/$ /lib/ld-linux.so.2 ls ls: error while loading shared libraries: ls: cannot open shared object file: No such file or directory user@host:/$ /lib/ld-linux.so.2 /bin/ls bin debootstrap etc lib proc sbin sys usr [...] So, something along these lines is possible. Thanks. Indeed, ideally fakechroot's execve should look up the interpreter filename from the ELF .interp section, map it according to the faked chroot, and set argv[0]. The hard part is the ELF parsing. Hints for inspiration[1]: git://github.com/NixOS/patchelf.git https://fedorahosted.org/elfutils/ Doable, though it seems a little too much like work for me to actually do it. ;-) Reassigning because I can't imagine glibc changing its compatibility requirements any time soon. Hope that helps, Jonathan [1] some pseudocode to experiment with for your amusement: diff --git i/src/execve.c w/src/execve.c index 60351177..70d0a9ea 100644 --- i/src/execve.c +++ w/src/execve.c @@ -71,6 +71,25 @@ static int try_cmd_subst (char * env, const char * filename, char * cmd_subst) return 0; } +static int get_elf_interp(const char * filename, char * buf, size_t buflen) +{ +int num_sections = num_sections(); /* header-e_shnum */ +int i; + +for (i = 0; i num_sections; i++) { +string section_name = section_names + section_header[i].sh_name; +if (section_name == .interp) /* found it! */ +break; +} +if (i == num_sections) +return -1; + +// found .interp section +size_t offset = section_hdr.sh_offset; +size_t size = section_hdr.sh_size; +... +} + wrapper(execve, int, (const char * filename, char * const argv [], char * const envp [])) { @@ -195,8 +214,11 @@ wrapper(execve, int, (const char * filename, char * const argv [], char * const } /* No hashbang in argv */ -if (hashbang[0] != '#' || hashbang[1] != '!') -return nextcall(execve)(filename, argv, newenvp); +if (hashbang[0] != '#' || hashbang[1] != '!') { +if (get_elf_interp(filename, hashbang + 2, sizeof(hashbang) - 3)) +return nextcall(execve)(filename, argv, newenvp); +i = strlen(hashbang); +} /* For hashbang we must fix argv[0] */ hashbang[i] = hashbang[i+1] = 0; -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org
Bug#650234: Use chroot's ld.so to do loading?
found 2.9-1.1+squeeze1 found 2.16-1 quit This appears to be an issue for a lot more than just 2.15-1. I could be wrong, but I'd assume it is in pretty well every version. -- (\___(\___(\__ --= 8-) EHM =-- __/)___/)___/) \BS (| ehem+sig...@m5p.com PGP F6B23DE0 |) / \_CS\ | _ -O #include stddisclaimer.h O- _ | / _/ 2477\___\_|_/DC21 03A0 5D61 985B -PGP- F2BE 6526 ABD2 F6B2\_|_/___/3DE0 -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org
Bug#650234: Use chroot's ld.so to do loading?
Any progress as solving #650234? Reads like the problem has been identified, but no solution has come up. I've got no idea if any possible solutions are visible... One thought, in wrapping execve(), use chroot/lib/ld-linux.so.2 as the filename. Push chroot/lib/ld-linux.so.2 on to argv[], then use the filename as argv[1]. This means invoked programs will always see their full pathname as argv[0], but ensures the chroot's loader is used. Another thought, perhaps try loading ld.so's version of libc? I'd seriously worry about chroot programs needing a later version, but might handle easier cases. -- (\___(\___(\__ --= 8-) EHM =-- __/)___/)___/) \BS (| ehem+sig...@m5p.com PGP F6B23DE0 |) / \_CS\ | _ -O #include stddisclaimer.h O- _ | / _/ 2477\___\_|_/DC21 03A0 5D61 985B -PGP- F2BE 6526 ABD2 F6B2\_|_/___/3DE0 -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org
Bug#650234: Use chroot's ld.so to do loading?
Simple test I tried in a test chroot image area: user@host:~/build$ fakechroot user@host:~/build$ chroot test.image Segmentation fault user@host:~/build$ chroot test.image /lib/ld-linux.so.2 /bin/bash user@host:/$ ls Segmentation fault user@host:/$ /lib/ld-linux.so.2 ls ls: error while loading shared libraries: ls: cannot open shared object file: No such file or directory user@host:/$ /lib/ld-linux.so.2 /bin/ls bin debootstrap etc lib proc sbin sys usr boot dev home mnt root selinux tmp var user@host:/$ exit So, something along these lines is possible. I suspect using the chroot's version of ld-linux.so.2 is a better bet than trying to use the system's libc.so. The one question is, the original argv[0] can be stashed in the environment, but can argv[0] be swaped out by a LD_PRELOAD library? -- (\___(\___(\__ --= 8-) EHM =-- __/)___/)___/) \BS (| ehem+sig...@m5p.com PGP F6B23DE0 |) / \_CS\ | _ -O #include stddisclaimer.h O- _ | / _/ 2477\___\_|_/DC21 03A0 5D61 985B -PGP- F2BE 6526 ABD2 F6B2\_|_/___/3DE0 -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org