Skip to content

joelmccracken/elisp-sandbox

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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.

About

A library for elisp sandboxed evaluation

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •