
I have the idea that we ought to be able to implement the equivalent of a unix chroot command, but all within the haskell IO monad.
[...]
As I see it, implementing such a function would require support in the IO monad (some of which may already be there?), since it would need to know for each primitive operation which arguments are file paths, plus whether that operation is even legal in a chroot environment. Or perhaps it's the other way around, and every primitive operation would need to support chroot...
Implementing barriers of this kind requires that your code has a "narrow waist". That is, if you look at a callgraph for your system (including libraries, runtime system, system calls and anything else you have the option of changing), you need to find a small number of edges in the callgraph which all relevant calls pass through. If the waist is not narrow, it is a huge amount of work to insert and maintain all the tests and your chances of getting them all are pretty slim. Unfortunately, the foreign function interface is specifically designed to make the IO monad be a very, very broad waist. Every library is free to add further IO operations. Worse, functions like 'System.system' allow arbitrary strings to be passed out of Haskell and interpreted there. Another problem is the unsafePerformIO function which could easily result in code that is supposed to be protected by your chroot function to be executed after the chroot call has finished. I think your best bet is to catch problems at the system call interface (either using the Unix chroot system call itself or by interposing on calls to 'open'). Or, tackle the same problem in a different way by extending Haskell with a datasource-tracking feature along the lines of taint perl. -- Alastair Reid