1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
#!/usr/bin/python3 -u
import code
import sys
import seccomp
f = seccomp.SyscallFilter(defaction=seccomp.KILL)
# Necessary for Python.
f.add_rule(seccomp.ALLOW, "brk")
f.add_rule(seccomp.ALLOW, "exit_group")
f.add_rule(seccomp.ALLOW, "ioctl")
f.add_rule(seccomp.ALLOW, "mmap")
f.add_rule(seccomp.ALLOW, "munmap")
f.add_rule(seccomp.ALLOW, "rt_sigaction")
f.add_rule(seccomp.ALLOW, "rt_sigreturn")
# Mostly harmless.
f.add_rule(seccomp.ALLOW, "mprotect")
# Allow reading from stdin and writing to stdout/stderr.
f.add_rule(seccomp.ALLOW, "read", seccomp.Arg(0, seccomp.EQ, sys.stdin.fileno()))
f.add_rule(seccomp.ALLOW, "write", seccomp.Arg(0, seccomp.EQ, sys.stdout.fileno()))
f.add_rule(seccomp.ALLOW, "write", seccomp.Arg(0, seccomp.EQ, sys.stderr.fileno()))
# Needed for finding source code for exceptions.
f.add_rule(seccomp.ALLOW, "stat")
f.add_rule(seccomp.ALLOW, "open", seccomp.Arg(1, seccomp.MASKED_EQ, 0x3, 0)) # O_RDONLY
f.add_rule(seccomp.ALLOW, "close")
f.add_rule(seccomp.ALLOW, "read")
f.add_rule(seccomp.ALLOW, "fstat")
f.add_rule(seccomp.ALLOW, "lseek")
f.add_rule(seccomp.ALLOW, "fcntl")
# Needed for help().
f.add_rule(seccomp.ALLOW, "openat", seccomp.Arg(2, seccomp.MASKED_EQ, 0x3, 0)) # O_RDONLY
f.add_rule(seccomp.ALLOW, "getdents")
f.add_rule(seccomp.ALLOW, "getrlimit", seccomp.Arg(0, seccomp.EQ, 3)) # RLIMIT_STACK
f.add_rule(seccomp.ALLOW, "getrlimit", seccomp.Arg(0, seccomp.EQ, 7)) # RLIMIT_NOFILE
# Needed for code.InteractiveConsole.
f.add_rule(seccomp.ALLOW, "access")
f.add_rule(seccomp.ALLOW, "select")
f.load()
class MyConsole(code.InteractiveConsole):
def interact(self, banner=None):
if banner is not None:
self.write('{}\n'.format(banner))
buffer = []
prompt = '>>> '
while True:
try:
line = input(prompt)
# Assume we are running the user's program; silence the prompt.
if line == 'exec("""\\':
self.write('<run>\n')
prompt = ''
buffer.append(line)
source = '\n'.join(buffer)
more = self.runsource(source)
if more:
if prompt:
prompt = '... '
else:
prompt = '>>> '
buffer = []
except KeyboardInterrupt:
prompt = '>>> '
buffer = []
self.write('\n')
except ValueError:
break
except EOFError:
break
def runcode(self, code):
try:
exec(code, self.locals)
except KeyboardInterrupt:
self.write('^C')
raise
except SystemExit as ex:
raise
except:
# Show traceback for all other exceptions.
self.showtraceback()
MyConsole().interact()
|