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 Answers 3



  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.

  • Is there any way to allow other non-IO related calls (ie: waitpid(), time(), alarm(), pause(), uname(), mmap(), etc.)? Commented Nov 4, 2013 at 1:53
  • There's seccomp-bpf, which uses Berkeley Packet Filter rules to determine which syscalls to allow. Commented Nov 4, 2013 at 21:48
  • I was looking more for something where I could specify syscalls. Commented Nov 5, 2013 at 8:58
  • I'd guess that libseccomp would allow you to just specify the syscalls. Commented Nov 5, 2013 at 12:14
  • That will work. Please add that libseccomp will allow specifying syscalls to the answer and I will mark it as correct. Thanks Matthew! Commented Nov 6, 2013 at 23:19

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?

  • 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
    Commented Nov 3, 2013 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
    Commented Nov 3, 2013 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
    Commented Nov 3, 2013 at 22:26

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)? Commented Nov 5, 2013 at 8: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.) Commented Nov 5, 2013 at 9:07
  • How would a malicious process work around LD_PRELOAD? Commented Nov 5, 2013 at 9:48
  • Also, the lwn link is broken. Commented Nov 5, 2013 at 9: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. Commented Nov 5, 2013 at 11:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .