You've already forked code_examples_server
mirror of
https://github.com/AdaCore/code_examples_server.git
synced 2026-02-12 12:45:18 -08:00
Add support for sandboxing the executables
This relies on an lxc container
This commit is contained in:
@@ -2,6 +2,13 @@
|
||||
|
||||
Prototype server for creating interactive "try SPARK / try Ada" webpages
|
||||
|
||||
## Requirements
|
||||
|
||||
In addition to Python, this system relies on LXC to sandbox
|
||||
the run of executables. To do this, you need
|
||||
- a container named "safecontainer"
|
||||
- this container should have a non-admin user 'ubuntu'
|
||||
|
||||
## Getting started
|
||||
|
||||
To setup, do this:
|
||||
|
||||
@@ -214,11 +214,16 @@ def run_program(request):
|
||||
|
||||
# Run the command(s) to check the program
|
||||
commands = [
|
||||
# Build the program
|
||||
["gprbuild", "-q", "-P", "main"],
|
||||
# TODO: implement a safe execute in a container
|
||||
[os.path.join(tempd, main[:-4])],
|
||||
# Launch the program via "safe_run", to sandbox it
|
||||
["python",
|
||||
os.path.join(os.path.dirname(__file__), 'safe_run.py'),
|
||||
os.path.join(tempd, main[:-4])],
|
||||
]
|
||||
|
||||
print commands
|
||||
|
||||
try:
|
||||
p = process_handling.SeparateProcess(commands, tempd)
|
||||
message = "running gnatprove"
|
||||
|
||||
60
compile_server/app/safe_run.py
Normal file
60
compile_server/app/safe_run.py
Normal file
@@ -0,0 +1,60 @@
|
||||
""" This is a standalone Python script that runs its argument
|
||||
safely in a container.
|
||||
|
||||
At the moment it assumes that the container "safecontainer"
|
||||
exists and is running.
|
||||
"""
|
||||
|
||||
import os
|
||||
import time
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
CONT = 'safecontainer'
|
||||
DEBUG = False
|
||||
|
||||
|
||||
def run(command):
|
||||
if DEBUG:
|
||||
print ">", " ".join(command)
|
||||
output = subprocess.check_output(["lxc", "exec", CONT, "--"] + command)
|
||||
if output:
|
||||
output = output.rstrip()
|
||||
if DEBUG:
|
||||
print "<", output
|
||||
return output
|
||||
|
||||
|
||||
def safe_run(main):
|
||||
# Make a temporary directory on the container
|
||||
tmpdir = run(["mktemp", "-d"])
|
||||
|
||||
try:
|
||||
run(["chown", "ubuntu", tmpdir])
|
||||
|
||||
# Push the executable to the container
|
||||
subprocess.check_call(["lxc", "file", "push", main,
|
||||
# This requires the dir to end with /
|
||||
CONT + tmpdir + os.sep])
|
||||
|
||||
# TODO: rlimit?
|
||||
|
||||
# Run it, printint output to stdout as we go along
|
||||
subprocess.call(["lxc", "exec", CONT, "--",
|
||||
"su", "ubuntu", "-c",
|
||||
os.path.join(tmpdir, os.path.basename(main))],
|
||||
stdout=sys.stdout)
|
||||
except E:
|
||||
print sys.exc_info()
|
||||
|
||||
finally:
|
||||
if tmpdir and tmpdir.startswith("/tmp"):
|
||||
time.sleep(0.2) # Time for the filesystem to sync
|
||||
run(["rm", "-rf", tmpdir])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Do not perform any sanity checking on args - this is not meant to
|
||||
# be launched interactively
|
||||
main = sys.argv[1]
|
||||
safe_run(main)
|
||||
Reference in New Issue
Block a user