I ran into an odd issue building grub-9999 against libzfs (sys-fs/zfs). I've simplified the issue below. Basically, if a function with a constructor attribute in a shared library violates the sandbox restrictions, we can end up triggering an infinite recursion scenario. For example. take fictional library libfoo with constuctor libfoo_init: 1. libfoo_init() is called before libsb_init(), so sb_unwrapped_open still points to open. See note [1] below. 2. libfoo_init() calls mkdir("/foo") 3. mkdir is wrapped by mkdir_DEFAULT 4. before_syscall 5. check_syscall; access fails 6. write_logfile 7. sb_open("/var/log/sandbox/...") 8. open("/var/log/sandbox/...") 9. open is wrapped by open_DEFAULT 10. before_syscall 11. check_syscall; access fails 12. write_logfile 13. sb_open("/var/log/sandbox/...") 14. open("/var/log/sandbox/...") 15. open is wrapped by open_DEFAULT 16. Repeat 10-15 until we run out of stack and segfault. When threads are involved (as in libzfs), we end up locking somewhere and the sandbox code basically deadlocks instead of recursing. I haven't debugged this to see what is happening there. I think we could avoid this by calling libsb_init() from before_syscall() or check_syscall(). I tried inserting it at the top of before_syscall, and that seemed to work. DISCLAIMER: I don't normally work with stuff this low-level, so I may not actually know what I'm talking about. [1] Based on a quick google search, it seems the run order of constructors in different compilation units is undefined. So, libsb_init() is not guaranteed to run before libfoo_init(). http://sources.redhat.com/ml/libc-help/2009-06/msg00000.html
I have uploaded my simple test case to my devspace if you would like to try it for yourself. http://dev.gentoo.org/~floppym/sandboxtest.tar
the constructor we're using atm lacks priory, so it runs in an arbitrary order does it work if you do: -__attribute__((constructor)) +__attribute__((constructor(0)))
(In reply to comment #2) Nope, same result.
should be fixed by: http://git.overlays.gentoo.org/gitweb/?p=proj/sandbox.git;a=commitdiff;h=5498907383c7f1654188b6a0d02d8b03112a28c3 (really this just needed sbio_open to get initialized in the data section, but i figured might as well move as much out as possible while i was there)
Confirmed. Thanks!
(In reply to comment #4) unfortunately, that fix broke a different use case. if an app starts up and doesn't make any syscalls before main() and modifies the env, things don't get initialized properly. like `env -i env`. fixed thusly: http://git.overlays.gentoo.org/gitweb/?p=proj/sandbox.git;a=commit;h=d8b21b35fd536af8411975ad05eab85f89e84a2e you might want to double check i didn't re-break you