OpenWrt/LEDE Project

  • Status Closed
  • Percent Complete
    100%
  • Task Type Bug Report
  • Category Base system
  • Assigned To No-one
  • Operating System All
  • Severity Low
  • Priority Very Low
  • Reported Version Trunk
  • Due in Version Undecided
  • Due Date Undecided
  • Private
Attached to Project: OpenWrt/LEDE Project
Opened by Kirill Elagin - 16.07.2017
Last edited by Jo-Philipp Wich - 17.07.2018

FS#909 - runas wrapper executes programs using wrong interpreter

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 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 +++
Closed by  Jo-Philipp Wich
17.07.2018 14:11
Reason for closing:  Fixed
Additional comments about closing:  

Fixed with https://g it.openwrt.org/?p=openwrt/openwrt.git;a= commitdiff;h=ef1cafa736679eb035d405bcdf9 03fd1fb329865

Kirill Elagin commented on 16.07.2017 03:26

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.

Kirill Elagin commented on 16.07.2017 04:04

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.

Admin
Jo-Philipp Wich commented on 16.07.2017 17:08

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

Admin
Jo-Philipp Wich commented on 16.07.2017 22:01

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

Kirill Elagin commented on 04.05.2018 21:39

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

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

Kirill Elagin commented on 04.05.2018 21:54

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
Admin
Jo-Philipp Wich commented on 04.05.2018 22:23

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

Kirill Elagin commented on 05.05.2018 01:07
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.

Kirill Elagin commented on 05.05.2018 01:14

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

Kirill Elagin commented on 05.05.2018 01:46

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

Loading...

Available keyboard shortcuts

Tasklist

Task Details

Task Editing