This guy Hans Boehm came and gave a talk at work today about upcoming C++ support for threads. That's support built into the language. It sounds like sometime in the next few years, we will have atomic<int> . That is to say that C++ will support concurrency, you'll be able to create objects that only one process/processor/whatever can mess with at a time. Up until now, it's been fun to mock people who have opinions about concurrency in programming languages, "Enjoy the Erlang!" and all that, but soon there will be no escape.
Actually, I was thinking about concurrency earlier, when I was reading this paper that's been going around, Some thoughts on security after ten years of qmail 1.0. Some things he doesn't say so well. But there is a nice list of things that a root program can do to run another program in a sandbox:
The jpegtopnm program reads a JPEG file, a compressed image, as input. It uncompresses the image, produces a bitmap as output, and exits. Right now this program is trusted: its bugs can compromise security. Let’s see how we can fix that.
Imagine running the jpegtopnm program in an “extreme sandbox” that doesn’t let the program do anything other than read the JPEG file from standard input, write the bitmap to standard output, and allocate a limited amount of memory. Existing UNIX tools make this sandbox tolerably easy for root to create:
- Prohibit new files, new sockets, etc., by setting the current and maximum RLIMIT_NOFILE limits to 0.
- Prohibit filesystem access: chdir and chroot to an empty directory.
- Choose a uid dedicated to this process ID. This can be as simple as adding the process ID to a base uid, as long as other system-administration tools stay away from the same uid range.
- Ensure that nothing is running under the uid: fork a child to run setuid(targetuid), kill(-1,SIGKILL), and _exit(0), and then check that the child exited normally.
- Prohibit kill(), ptrace(), etc., by setting gid and uid to the target uid.
- Prohibit fork(), by setting the current and maximum RLIMIT_NPROC limits to 0.
- Set the desired limits on memory allocation and other resource allocation.
- Run the rest of the program.
At this point, unless there are severe operating-system bugs, the program has no communication channels other than its initial file descriptors.
Up until now, the phrase "chroot jail" was one of those things that I read with only a vague sense of understanding. And folks kept saying "It's not enough to set up the chroot, there's more to it", but they never seemed to list the other things to do. But now that I have a list of a few things, I can probably search the web for pages and code that mentions these things and get a nice survey.
But something I hadn't caught onto before--this chroot stuff is all about spawning programs. I guess you end up with multiple programs all running at the same time. It's a concurrent programming model, I guess. Actually, now that I look at some code samples that deal with chroot this and RLIMIT that, this stuff doesn't look so easy.
Rob Pike gave a talk about Newsqueak a little while back. Newsqueak is a language that makes it pretty easy to spawn off little programlets--there are these objects that are kinda like function pointers. And you can do this thing where you kind of set up a thingy that invokes one of these functions and blocks/waits for its return value. And I thought it would be nice if I could do something like that, but maybe first set some flag on that function-pointer-like-thingy that means "run this function in jail".
Newsqueak-like message-passing concurrency programming... it lives on in other languages these days--like Erlang. Erlang? Erlang. Jeez, maybe I should look at Erlang, stop making fun of it, see what I can learn from it. Learn from Erlang. So this is how low I've sunk.
Next thing you know, I'll be associating with LARPers. Asking Furries to share their wisdom.
Oh, now I can't stop shuddering.
Maybe I'll put off studying Erlang until C++'s atomic<int> comes along.
Labels: capabilities, link, programming languages