Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
A library for elisp sandboxed evaluation
Emacs Lisp Shell
Branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
bin
spec
vendor
.gitignore
.gitmodules
README-spec.el
README.creole
elisp-sandbox.el
erbot_research.org
test.sh

README.creole

Elisp Sandbox: run Emacs Lisp in a jail

Erbot runs the #emacs robot. He has a jail inside him for running arbitary elisp safely.

The code is here: git:git.sv.gnu.org/erbot.git

Also on GitHub here.

The goal of this project is to take erbot's code and adapt it for general use.

It is very much a work in progress. Feel free to help out!

How to use it

First load elisp-sandbox.el. It provides a number of functions that support working with Emacs Lisp code in a safe way.

The simplest function is elisp-sandbox-eval. Using it will evaluate the code in a way that prevents the code from calling any disallowed functions.

How it Works

The elisp sandbox works by prefixing any symbols it receives as input before that input is evaluated. That way, the user can only access symbols that begin with that prefix. For example,

(elisp-sandbox
 '(setq x 100))

=>

(elisp-sandbox-unsafe-env-setq elisp-sandbox-unsafe-env-x 100)

and:

(elisp-sandbox
 '(defun nic-test-2 nil 100))

=>

(elisp-sandbox-unsafe-env-defun elisp-sandbox-unsafe-env-nic-test-2 nil 100)

Programmer API

To evaluate unsafe code:

(elisp-sandbox-eval <unsafe code here>)

Example:

(elisp-sandbox-eval
 '(+ 1 2))

=>

3

Any output is stored as a list of strings in the symbol:

elisp-sandbox-evaluation-output

(elisp-sandbox-eval
 '(message "Hello World!"))

=>

("Hello World!")

Sandbox Internal API

Sandbox provides a number of functions and macros that are accessible to untrusted code.

defun -- Defines a function specific to the sandbox environment.

while -- Basic looping. Has a maxium loop depth foncigurable with sandbox-while-max .

(elisp-sandbox-eval
 '(progn
    (setq counter 0 total 0)
    (while
        (< counter 10)
      (setq total
            (+ total counter))
      (setq counter
            (+ 1 counter)))
    total))

=>

45

The maximum execution while depth can be configured:

(let
    ((sandbox-while-max 2))
  (if
      (elisp-sandbox-eval
       '(ignore-errors
          (setq counter 0 total 0)
          (while
              (< counter 10)
            (setq total
                  (+ total counter))
            (setq counter
                  (+ 1 counter)))
          t))
      "A non-nil resuld would mean that the while finished and t was returned" "A nil result means an error happend, as expected!"))

=>

"A nil result means an error happend, as expected!"

message -- method for saving output.

The following are available as aliases of the standard functions:

setq, <, +, progn, let, ignore-errors, if

Sandbox Errors

When code behaves badly, errors can be thrown. we gotta figure out how to handle these well.

Future

  • it would be nice to allow changing of prefixes, declaration with diff prefixes, and cleaning up of prefixes. That way a single process can handle different sandboxes.
  • still need to figure out which additional functions need to come from erbot
  • features to port funcall, apply, pi, e, emacs-version

Development

Use the script bin/clone_erbot.sh to get a local copy of the erbot source for yourself.

Tests are written with ert.

Tests

Run the file

./test.sh

Tests can also be run interactively... TODO document this

About This Readme

Readme content is automatically generated from the file README-spec.el, in the same directory. Its examples are used as feature tests. Do not edit README.creole directly; instead, edit README-spec.el and regenerate README.creole.

Each feature is covered more thoroughly in the specs/ directory.

Something went wrong with that request. Please try again.