Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FS#909 - runas wrapper executes programs using wrong interpreter #6601

Closed
openwrt-bot opened this issue Jul 16, 2017 · 10 comments
Closed

FS#909 - runas wrapper executes programs using wrong interpreter #6601

openwrt-bot opened this issue Jul 16, 2017 · 10 comments
Labels

Comments

@openwrt-bot
Copy link

kirelagin:

I happen to run a system having no easily accessible binary interpreter (that is, there is no /lib64).

Some time ago a wrapper for binaries [[https://git.lede-project.org/?p=source.git;a=commitdiff;h=72d751cba9cda9ce3ae46d5e6ab962d2f675e970|was introduced]]. The issue with this wrapper is that instead of using bundled ld-linux-x86-64.so.2, it executes the program by calling execve, which will try to use the system interpreter (and fail, in my case). In other words, all the bundled dynamic loader business is now out of work; the same result could be achieved by executing the binary directly.

This works:
[staging_dir/host]$ ./lib/ld-linux-x86-64.so.2 --library-path ./lib/ ./bin/.uuidgen.bin
fb85483b-e891-4dbd-badb-43361fc954f3

This does not:
[staging_dir/host]$ ./lib/ld-linux-x86-64.so.2 --library-path ./lib/ ./lib/runas ./bin/.uuidgen.bin uuidgen
[staging_dir/host]$ echo $?
255

[staging_dir/host]$ strace ./lib/ld-linux-x86-64.so.2 --library-path ./lib/ ./lib/runas ./bin/.uuidgen.bin uuidgen
execve("./lib/ld-linux-x86-64.so.2", ["./lib/ld-linux-x86-64.so.2", "--library-path", "./lib/", "./lib/runas", "./bin/.uuidgen.bin", "uuidgen"], 0x7ffe055921b8 /* 69 vars /) = 0
brk(NULL) = 0x55c6f060e000
open("./lib/runas", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\2\0>\0\1\0\0\0\240\4@\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=7048, ...}) = 0
getcwd("/home/kirelagin/openwrt/lede-imagebuilder-17.01.2-ar71xx-generic.Linux-x86_64/staging_dir/host", 128) = 95
mmap(0x400000, 4096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0x400000
mmap(0x600000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0x600000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f157c858000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("./lib/tls/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("./lib/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("./lib/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("./lib/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\34\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1738176, ...}) = 0
getcwd("/home/kirelagin/openwrt/lede-imagebuilder-17.01.2-ar71xx-generic.Linux-x86_64/staging_dir/host", 128) = 95
mmap(NULL, 3844640, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f157c4ad000
mprotect(0x7f157c64e000, 2097152, PROT_NONE) = 0
mmap(0x7f157c84e000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a1000) = 0x7f157c84e000
mmap(0x7f157c854000, 14880, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f157c854000
close(3) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f157c4ac000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f157c4ab000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f157c4aa000
arch_prctl(ARCH_SET_FS, 0x7f157c4ab700) = 0
mprotect(0x7f157c84e000, 16384, PROT_READ) = 0
mprotect(0x55c6f00e8000, 4096, PROT_READ) = 0
execve("./bin/.uuidgen.bin", ["uuidgen"], 0x7ffd9e14e360 /
69 vars */) = -1 ENOENT (No such file or directory)
exit_group(-1) = ?
+++ exited with 255 +++

@openwrt-bot
Copy link
Author

kirelagin:

Ugh, the category is supposed to be “Toolchain” and severity is supposed to be “Medium”. Unfortunately I don’t see how to alter those now.

@openwrt-bot
Copy link
Author

kirelagin:

I actually spent quite a few hours trying to come up with a solution, and the problem is surprisingly hard.

The only fresh idea I’ve got so far is to move all the binaries into a separate directory, rename back, and then use execvp instead of execv, setting PATH to that separate directory beforehand.

The original commit motivation lists two issues: argv[0] not being preserved (who cares?) and something about resources lookup relative to the executable location. Any one of those can be done: drop all the runas stuff to get 2 whitout 1; do what I suggested in the previous paragraph to get 1 without 2. But I am pretty sure by now that there is no way to get both without doing an insane amount of work. I hope someone can prove me wrong.

@openwrt-bot
Copy link
Author

jow-:

Not preserving argv[0] will break ccache at least.

@openwrt-bot
Copy link
Author

jow-:

Please test the commit in my staging tree:
https://git.lede-project.org/76b5006ad

@openwrt-bot
Copy link
Author

kirelagin:

I’m sorry I somehow missed these notifications :/.

I can’t find your commit now, but I’m eager to test it.

@openwrt-bot
Copy link
Author

kirelagin:

Actually, now I’ve got a similar issue, but this time with mksquashfs4, which needs zlib.

[staging_dir/host]$ ./lib/ld-linux-x86-64.so.2 --library-path lib/ ./bin/.mksquashfs4.bin mksquashfs4
(works)

[staging_dir/host]$ ./lib/ld-linux-x86-64.so.2 --library-path lib/ lib/runas ./bin/.mksquashfs4.bin mksquashfs4
mksquashfs4: error while loading shared libraries: libz.so.1: cannot open shared object file: No such file or directory

@openwrt-bot
Copy link
Author

jow-:

The failing command line looks weird... why two space separated arguments to --library-path ? Also I dropped the runas executable in favor to a shared library opened with LD_PRELOAD.

See http://git.openwrt.org/ef1cafa736679eb035d405bcdf903fd1fb329865

@openwrt-bot
Copy link
Author

kirelagin:

The failing command line looks weird... why two space separated arguments to –library-path

Why two arguments? --library-path lib/ is the library path and then comes the executable that we run and its arguments. The failing line is exactly the one that existing wrappers use (and they are failing for me).

The change you linked did get included into 17.01.4, right? I am trying to generate a 17.01.4 image and it was failing for me with exactly the same mksquashfs4 error as in my example (not being able to find libz.so). I replaced the failing one with the top one (which skips lib/runas) and the image was generated successfully. Well, “successfully” might not be the right word here, because it completely bricked my router and I am still trying to understand what went wrong, because there were no errors from the generation process :(.

Anyway, what I see is that all wrappers in lede-imagebuilder-17.01.4-ar71xx-generic.Linux-x86_64/staging_dir/host/bin go through lib/runas. I’m sorry if I originally didn’t make it clear enough that I was talking specifically about the image generator all this time.

@openwrt-bot
Copy link
Author

kirelagin:

Ah, I see, your commit didn’t make it into 17.01.4. Alright, let me try staging (too bad I no longer have a router to try the resulting firmware on :).

@openwrt-bot
Copy link
Author

kirelagin:

Yes, your new way of wrapping executables works wonderfully. The issue is resolved now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant