guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: modify environments to make sandboxes


From: Ludovic Courtès
Subject: Re: modify environments to make sandboxes
Date: Mon, 12 Jun 2006 18:47:33 +0200
User-agent: Gnus/5.110004 (No Gnus v0.4) Emacs/21.4 (gnu/linux)

Hi,

Mildred <address@hidden> writes:

> I do not know how to do that in scheme. Apparetly the function
> null-environment can return an environment and eval can evaluate some
> code in an environment. But the question is how to define a variable in
> an environment and also how to undefine a variable that you don't want
> to appear.

Code confinement is indeed an interesting feature.  Fortunately, Guile
offers various ways to do it (AFAIK, there's no standard way to do this
in R5RS Scheme).  :-)

Basically, in Guile, one can manipulate "modules".  Modules are
first-class representations of name spaces (i.e., environments with
bindings).  The second argument of `eval' is a module, so you can ask
Guile to evaluate a piece of code within the context of a particular
module.

The basic way to create a module is `make-module'.  However, this
returns a module with absolutely no defined binding (i.e., no variable
is bound within it, not even `define', `let', etc.).  If you were to
create a confined module to evaluate mathematical expressions, you could
start from there:

  (define (make-pure-math-module)
    (let ((m (make-module)))
      (module-define! m '+ +)
      (module-define! m '- -)
      (module-define! m '* *)
      (module-define! m '/ /)
      (module-define! m 'let let)
      m))

Now, thanks to this, you will be able to catch the following:

  (eval '(system "rm -rf /") (make-pure-math-module))

IOW, you can safely evaluate any expression, and you know that it will
fail if it's not a pure mathematical expression.


Now, in the general case, you want to create a module that contains
enough bindings to allow "friendly" code to evaluate, but you don't want
to list all those bindings one by one.  In this case, you can use
`make-root-module' which returns a new module that contains all the
default Guile bindings.  Then, you can selectively undefine or modify
various bindings within that module (using `module-remove!' and
`module-set!').  In particular, you'll want to make sure that no POSIX
syscall is available, and that `load' and `resolve-module' (which allows
one to load a Scheme file) are either undefined or restricted (e.g.,
such that only specific modules can be loaded from within the confined
module).

Finally, another approach is to start from an empty module (returned by
`make-module') and then use a set of `module-use!' calls to have it
import bindings from a few specific modules.

You can get more information about modules in `ice-9/boot-9.scm'.


Happy hacking!
Ludovic.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]