Gentoo has a feature in portage, that prevents and logs writes outside of the build and packaging directories.
Checkinstall is able to monitor writes, and package up all the generated files after completion.
Autotools have the DESTDIR
macro that enables you to usually direct most of the filesystem activity to an alternate location.
- How can I do this myself with the safety of the Gentoo sandboxing method?
- Can I use SELinux, rlimit, or some other resource limiting API?
- What APIs are available do this from C, Python?
Update0
- The mechanism used will not require root privileges or any involved/persistent system modification. This rules out creating users and using
chroot()
. - Please link to the doc开发者_运维问答umentation for APIs that you mention, for some reason they're exceptionally difficult to find.
Update1
- This is to prevent accidents. I'm not worried about malicious code, only the poorly written variety.
The way Debian handles this sort of problem is to not run the installation code as root in the first place. Package build scripts are run as a normal user, and install scripts are run using fakeroot - this LD_PRELOAD library redirects permission-checking calls to make it look like the installer is actually running as root, so the resulting file ownership and permissions are right (ie, if you run /usr/bin/install
from within the fakeroot environment, further stat
s from within the environment show proper root ownership), but in fact the installer is run as an ordinary user.
Builds are also, in some cases (primarily for development), done in chroots using eg pbuilder - this is likely easier on a binary distribution however, as each build using pbuilder reinstalls all dependencies beyond the base system, acting as a test that all necessary dependencies are specified (this is the primary reason for using a chroot; not for protection against accidental installs)
One approach is to virtualize a process, similar to how wine
does it, and reinterpret file paths. That's rather heavy duty to implement though.
A more elegant approach is to use the chroot()
system call which sets a subtree of the filesystem as a process's root directory. Create a virtual subtree, including /bin, /tmp, /usr, /etc as you want the process to see them, call chroot with the virtual tree, then exec the target executable. I can't recall if it is possible to have symbolic links within the tree reference files outside, but I don't think so. But certainly everything needed could be copied into the sandbox, and then when it is done, check for changes against the originals.
Maybe get the sandbox safety with regular user permissions? So the process running the show has specific access to specific directories.
chroot
would be an option but I can't figure out how to track these tries to write outside the root.
Another idea would be along the lines of intercepting system calls. I don't know much about this but strace
is a start, try running a program through it and check if you see something you like.
edit:
is using kernel modules an option? because you could replace the write system call with your own so you could prevent whatever you needed and also log it.
It sounds a bit like what you are describing is containers. Once you've got the container infrastructure set up, it's pretty cheap to create containers, and they're quite secure.
There are two methods to do this. One is to use LD_PRELOAD
to hook library calls that result in syscalls, such as those in libc, and call dlsym
/dlopen
. This will not allow you to directly hook syscalls.
The second method, which allows hooking syscalls, is to run your executable under ptrace
, which provides options to stop and examine syscalls when they occur. This can be set up programmatically to sandbox calls to restricted areas of the filesystem, among other things.
- LD_PRELOAD can not intercept syscalls, but only libcalls?
- Dynamic linker tricks: Using LD_PRELOAD to cheat, inject features and investigate programs
- Write Yourself an Strace in 70 Lines of Code
精彩评论