2

Context:

In Lua, it's trivial and very cheap (4kb of memory) to create a new Lua VM. Thus, it's trivial to create cheap lua "jails". Then, if the untrusted code misbehaves, I just kill the Lua VM.

I'm aware of https://github.com/Licenser/clj-sandbox but it appears to just wrap around Java ... which would make untrusted code thread be native Java threads, which I would then be powerless to kill.

Question:

Is there anyway to create cheap / light weight Clojure jails?

user1383359
  • 2,673
  • 2
  • 25
  • 32

1 Answers1

3

I'm the (co)author of a little library called clojail that was kind of a rethinking of clj-sandbox. It also makes use of the Java sandbox, but also provides features for sandboxing Clojure-specific things. tryclj and 4clojure make use of it.

I don't understand what you mean by the rest of that. The JVM sandbox is great in that it can prevent I/O. Clojail goes the rest of the way by allowing timeouts to prevent long running code. If what you're saying is that "people could create threads and I wouldn't be able to kill them", clojail kills threads created inside of the sandbox and generally does its best to prevent stray threads from running away. The JVM sandbox (and clojail specific stuff) still prevents dangerous code from running on threads as well.

In summary, check out clojail. It might be what you need. It is sufficient for most purposes, and is the only game in town (save for clj-sandbox which isn't maintained) for jails. It isn't always the best solution but it is usually the easiest.

The next step up if clojail doesn't do what you need is to roll your own jailing mechanism that involves using the JVM sandbox and spinning off JVMs. This has massive overhead, so I'd avoid it if anyway possible. Definitely not in 4KB Luatown anymore. ;)

Rayne
  • 31,473
  • 17
  • 86
  • 101
  • We create a thread group so that any threads created in the sandbox context are inside of that group, and then we kill them after evaluation completes or a timeout occurs. This doesn't work for threads created in thread pools, which is just something we have to deal with, so we try to prevent the creation of those threads (future and such that create those types of threads are blacklisted in the sandbox). – Rayne Jun 09 '12 at 20:33
  • Are you killing ThreadGroups with the deprecated stop? http://docs.oracle.com/javase/6/docs/api/java/lang/ThreadGroup.html If so, how do you do it without sabotaging the VM? – user1383359 Jun 10 '12 at 02:43
  • Yes, because there aren't a lot of other options. I don't know what you mean by sabotaging the VM. The idea is to sandbox code, not to clean it up properly. – Rayne Jun 10 '12 at 09:41
  • I was under the impression that thread.stop leaves the JVM in an unclean/unstable state. This seems like it might provide an (theoretical/pedantic) attack; i.e. long running threads -> thread.stop -> JVM in weird state -> exploit. BTW, I know far less about this than you, so this is all theoretical / my ignorance. – user1383359 Jun 10 '12 at 12:13
  • I've never seen an issue were the JVM was literally broken by a stopped thread. With the sandbox in place, there isn't a lot of state that can be mutated, so there isn't a lot of date to corrupt. :) – Rayne Jun 10 '12 at 18:38
  • Rayne: with sufficient restrictions on the sandbox, is it possible to ensure that there isn't random locks / mutexes being held? If so, I'd consider running my _normal_ clojure code in sandboxes -- just so I can kill infinite loops without restarting the JVM. – user1383359 Jun 11 '12 at 03:24