import os import subprocess import shlex from flask import Flask, flash, request, redirect, make_response, url_for from werkzeug.utils import secure_filename import subprocess import resource # Maximal virtual memory for subprocesses (in bytes). MAX_VIRTUAL_MEMORY = 20 * 1024 * 1024 # 2 MB def limit_virtual_memory(): # The tuple below is of the form (soft limit, hard limit). Limit only # the soft part so that the limit can be increased later (setting also # the hard limit would prevent that). # When the limit cannot be changed, setrlimit() raises ValueError. resource.setrlimit(resource.RLIMIT_AS, (MAX_VIRTUAL_MEMORY, resource.RLIM_INFINITY)) app = Flask(__name__) PRELUDE = b""" (defn all-bindings [&] (error "Function all-bindings not allowed")) (defn all-dynamics [&] (error "Function all-dynamics not allowed")) (defn bad-compile [&] (error "Function bad-compile not allowed")) (defn bad-parse [&] (error "Function bad-parse not allowed")) (defn cli-main [&] (error "Function cli-main not allowed")) (defn compile [&] (error "Function compile not allowed")) (defn curenv [&] (error "Function curenv not allowed")) (defn debug [&] (error "Function debug not allowed")) (defn debug/arg-stack [&] (error "Function debug/arg-stack not allowed")) (defn debug/break [&] (error "Function debug/break not allowed")) (defn debug/fbreak [&] (error "Function debug/fbreak not allowed")) (defn debug/lineage [&] (error "Function debug/lineage not allowed")) (defn debug/stack [&] (error "Function debug/stack not allowed")) (defn debug/stacktrace [&] (error "Function debug/stacktrace not allowed")) (defn debug/step [&] (error "Function debug/step not allowed")) (defn debug/unbreak [&] (error "Function debug/unbreak not allowed")) (defn debug/unfbreak [&] (error "Function debug/unfbreak not allowed")) (defn debugger-env [&] (error "Function debugger-env not allowed")) (defn dofile [&] (error "Function dofile not allowed")) (defn env-lookup [&] (error "Function env-lookup not allowed")) (defn eval [&] (error "Function eval not allowed")) (defn eval-string [&] (error "Function eval-string not allowed")) (defn fiber/getenv [&] (error "Function fiber/getenv not allowed")) (defn fiber/setenv [&] (error "Function fiber/setenv not allowed")) (defn file/close [&] (error "Function file/close not allowed")) (defn file/flush [&] (error "Function file/flush not allowed")) (defn file/open [&] (error "Function file/open not allowed")) (defn file/popen [&] (error "Function file/popen not allowed")) (defn file/read [&] (error "Function file/read not allowed")) (defn file/seek [&] (error "Function file/seek not allowed")) (defn file/temp [&] (error "Function file/temp not allowed")) (defn file/write [&] (error "Function file/write not allowed")) (defn import [&] (error "Function import not allowed")) (defn import* [&] (error "Function import* not allowed")) (defn load-image [&] (error "Function load-image not allowed")) (defn load-image-dict [&] (error "Function load-image-dict not allowed")) (defn make-env [&] (error "Function make-env not allowed")) (defn make-image [&] (error "Function make-image not allowed")) (defn make-image-dict [&] (error "Function make-image-dict not allowed")) (defn marshal [&] (error "Function marshal not allowed")) (defn module/add-paths [&] (error "Function module/add-paths not allowed")) (defn module/cache [&] (error "Function module/cache not allowed")) (defn module/expand-path [&] (error "Function module/expand-path not allowed")) (defn module/find [&] (error "Function module/find not allowed")) (defn module/loaders [&] (error "Function module/loaders not allowed")) (defn module/loading [&] (error "Function module/loading not allowed")) (defn module/paths [&] (error "Function module/paths not allowed")) (defn net/accept [&] (error "Function net/accept not allowed")) (defn net/accept-loop [&] (error "Function net/accept-loop not allowed")) (defn net/address [&] (error "Function net/address not allowed")) (defn net/chunk [&] (error "Function net/chunk not allowed")) (defn net/close [&] (error "Function net/close not allowed")) (defn net/connect [&] (error "Function net/connect not allowed")) (defn net/flush [&] (error "Function net/flush not allowed")) (defn net/listen [&] (error "Function net/listen not allowed")) (defn net/read [&] (error "Function net/read not allowed")) (defn net/recv-from [&] (error "Function net/recv-from not allowed")) (defn net/send-to [&] (error "Function net/send-to not allowed")) (defn net/server [&] (error "Function net/server not allowed")) (defn net/write [&] (error "Function net/write not allowed")) (defn os/cd [&] (error "Function os/cd not allowed")) (defn os/chmod [&] (error "Function os/chmod not allowed")) (defn os/clock [&] (error "Function os/clock not allowed")) (defn os/cryptorand [&] (error "Function os/cryptorand not allowed")) (defn os/cwd [&] (error "Function os/cwd not allowed")) (defn os/date [&] (error "Function os/date not allowed")) (defn os/dir [&] (error "Function os/dir not allowed")) (defn os/environ [&] (error "Function os/environ not allowed")) (defn os/execute [&] (error "Function os/execute not allowed")) (defn os/exit [&] (error "Function os/exit not allowed")) (defn os/getenv [&] (error "Function os/getenv not allowed")) (defn os/link [&] (error "Function os/link not allowed")) (defn os/lstat [&] (error "Function os/lstat not allowed")) (defn os/mkdir [&] (error "Function os/mkdir not allowed")) (defn os/sleep [&] (error "Function os/sleep not allowed")) (defn os/mktime [&] (error "Function os/mktime not allowed")) (defn os/open [&] (error "Function os/open not allowed")) (defn os/perm-int [&] (error "Function os/perm-int not allowed")) (defn os/perm-string [&] (error "Function os/perm-string not allowed")) (defn os/pipe [&] (error "Function os/pipe not allowed")) (defn os/proc-close [&] (error "Function os/proc-close not allowed")) (defn os/proc-kill [&] (error "Function os/proc-kill not allowed")) (defn os/proc-wait [&] (error "Function os/proc-wait not allowed")) (defn os/readlink [&] (error "Function os/readlink not allowed")) (defn os/realpath [&] (error "Function os/realpath not allowed")) (defn os/rename [&] (error "Function os/rename not allowed")) (defn os/rm [&] (error "Function os/rm not allowed")) (defn os/rmdir [&] (error "Function os/rmdir not allowed")) (defn os/setenv [&] (error "Function os/setenv not allowed")) (defn os/shell [&] (error "Function os/shell not allowed")) (defn os/spawn [&] (error "Function os/spawn not allowed")) (defn os/stat [&] (error "Function os/stat not allowed")) (defn os/symlink [&] (error "Function os/symlink not allowed")) (defn os/time [&] (error "Function os/time not allowed")) (defn os/touch [&] (error "Function os/touch not allowed")) (defn os/umask [&] (error "Function os/umask not allowed")) (defn os/which [&] (error "Function os/which not allowed")) (defn repl [&] (error "Function repl not allowed")) (defn require [&] (error "Function require not allowed")) (defn root-env [&] (error "Function root-env not allowed")) (defn run-context [&] (error "Function run-context not allowed")) (defn signal [&] (error "Function signal not allowed")) (defn symbol [&] (error "Function symbol not allowed")) (defn symbol/slice [&] (error "Function symbol/slice not allowed")) (defn thread/close [&] (error "Function thread/close not allowed")) (defn thread/current [&] (error "Function thread/current not allowed")) (defn thread/exit [&] (error "Function thread/exit not allowed")) (defn thread/new [&] (error "Function thread/new not allowed")) (defn thread/receive [&] (error "Function thread/receive not allowed")) (defn thread/send [&] (error "Function thread/send not allowed")) (defn trace [&] (error "Function trace not allowed")) (defn tracev [&] (error "Function tracev not allowed")) (defn unmarshal [&] (error "Function unmarshal not allowed")) (defn use [&] (error "Function use not allowed")) (defn slurp [&] (error "Function slurp not allowed")) (defn spit [&] (error "Function spit not allowed")) (defn flycheck [&] (error "Function flycheck not allowed")) (defn xprin [&] (error "Function xprin not allowed")) (defn xprinf [&] (error "Function xprin not allowed")) (defn xprint [&] (error "Function xprint not allowed")) (defn xprintf [&] (error "Function xprintf not allowed")) """ PROC = {} @app.route('/', methods=['GET', 'POST']) def upload_file(): if request.method == 'POST': # Limit one process per IP. if request.remote_addr in PROC: PROC[request.remote_addr].kill() del PROC[request.remote_addr] source_code = request.get_data() proc = subprocess.Popen( ['build/janet', '/dev/stdin'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, preexec_fn=limit_virtual_memory ) PROC[request.remote_addr] = proc result = "Something went wrong..." try: result = proc.communicate(input=PRELUDE + source_code, timeout=10*60) result = result[0] except Exception: pass response = make_response(result, 200) response.mimetype = "text/plain" return response return '''
Janet Script:
Program output:
'''