4

How do you start a process that cannot do any file IO (opening / closing files, creating / deleting files, reading / writing files, etc.), except to read and write to pre-created FIFOs?

(chroot will not work because the process can break out of it, but messing with / modifying the kernel and such is okay)

BTW: I cannot modify the programs that are being run

3 Answers3

4

If

  1. the program can be modified to make a system call of your choice before any of the untrusted code (this might be done via LD_PRELOAD), and
  2. the program doesn't need to do any system calls beyond exit(), sigreturn(), read() and write()

then you can use seccomp (Wikipedia article). To allow for more that just those system calls there's seccomp-bpf, which uses Berkeley Packet Filter to determine which system calls to allow. The libseccomp library simplifies seccomp-bpf so (for example) if you wanted to allow the close() system call:

seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0);

Or for something similar to chroot, but which can't be broken out of, you could try Linux containers, OpenVZ or Linux VServer.

1

Your best bet is to run the problem as an unprivileged user. The give the correct permissions to the FIFO.

That said the unprivileged user will have access to all the files any other non-privileged user will have.

To do more then that you would have to seriously modify things on the file system. but:

chmod o-rwx / -R

Will certainly lock things down. But again other users won't be able to read anything either.

I guess the more important questions to ask your self is "Why do I need this restriction?" Maybe there is a better way to obtain your goals?

coteyr
  • 4,310
  • 1
    Seems like too much work. Seems like he shouldn't have to lean on the environment this much. Also it fails for the same reason a chroot doesn't work here either. User's can play games and "level up". – slm Nov 03 '13 at 22:22
  • Ture, but you really need to look at why you need this restriction. It's likely that your over thinking some other problem. – coteyr Nov 03 '13 at 22:24
  • I don't doubt that, I'm just playing the OP's part in looking at this. Your idea is what I would've probably went with, truth be told. It passes my tests of being reasonably portable (just lift the setup of the account and a couple of chmods/chowns from boxA to boxB). – slm Nov 03 '13 at 22:26
1

A process cannot break out of a chroot if you do things right, namely, run the process under its own user ID (i.e. there must not be any process running as the same user outside the chroot).

Chroot the process to a directory that the process cannot write to and that only contains FIFOs. You'll need to either put the executable and the libraries and data files it needs in that chroot, or else start the process as root, then chroot and then change the user ID.

If you can't involve root, you can use a namespace, but you need a recent kernel for that (≥3.8). First create a user namespace, then inside it chroot and change to an in-namespace user ID with the required absence of privileges.

Alternatively, this can be done (with root's cooperation) through security frameworks such as SELinux or AppArmor: disable all filesystem-related syscalls except open, read, write, close and lseek, and restrict open to the directory containing the FIFOs. Be sure to disable ptrace as well.

  • I don't suppose there is some way to do the second way without the help of root (or at least, with root only being involved once in a setup of sorts)? – haneefmubarak Nov 05 '13 at 08:57
  • @haneefmubarak Without root being involved, you need either a recent Linux kernel for user namespaces or to go to full virtualization. (If you were only targetting cooperating processes, you could do it with LD_PRELOAD, but that can be easily worked around by a malicious process.) – Gilles 'SO- stop being evil' Nov 05 '13 at 09:07
  • How would a malicious process work around LD_PRELOAD? – haneefmubarak Nov 05 '13 at 09:48
  • Also, the lwn link is broken. – haneefmubarak Nov 05 '13 at 09:48
  • @haneefmubarak LD_PRELOAD only redirects library calls. A process can make system calls directly, this won't be affected. This needn't even be malicious (though in practice it does tend to work in most non-malicious situations): in particular LD_PRELOAD has no effect on a statically-linked binary. – Gilles 'SO- stop being evil' Nov 05 '13 at 11:19
  • And uh, do you have the lwn link on namespaces? – haneefmubarak Nov 06 '13 at 01:35