Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
fb534323
Commit
fb534323
authored
Apr 12, 2013
by
Ned Batchelder
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
jail_code can execute a provided file also.
parent
9683098f
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
49 additions
and
21 deletions
+49
-21
common/lib/codejail/codejail/jail_code.py
+15
-5
common/lib/codejail/codejail/safe_exec.py
+1
-1
common/lib/codejail/codejail/tests/doit.py
+4
-0
common/lib/codejail/codejail/tests/test_jailpy.py
+29
-15
No files found.
common/lib/codejail/codejail/jail_code.py
View file @
fb534323
...
...
@@ -68,15 +68,20 @@ class JailResult(object):
self
.
stdout
=
self
.
stderr
=
self
.
status
=
None
def
jail_code
(
command
,
code
,
files
=
None
,
argv
=
None
,
stdin
=
None
):
def
jail_code
(
command
,
code
=
None
,
files
=
None
,
argv
=
None
,
stdin
=
None
):
"""Run code in a jailed subprocess.
`command` is an abstract command ("python", "node", ...) that must have
been configured using `configure`.
`code` is a string containing the Python code to run.
`code` is a string containing the code to run. If no code is supplied,
then the code to run must be in one of the `files` copied, and must be
named in the `argv` list.
`files` is a list of file paths.
`files` is a list of file paths, they are all copied to the jailed
directory.
`argv` is the command-line arguments to supply.
Return an object with:
...
...
@@ -92,6 +97,8 @@ def jail_code(command, code, files=None, argv=None, stdin=None):
log
.
debug
(
"Executing jailed code:
%
r"
,
code
)
argv
=
argv
or
[]
# All the supporting files are copied into our directory.
for
filename
in
files
or
():
if
os
.
path
.
isfile
(
filename
):
...
...
@@ -101,10 +108,13 @@ def jail_code(command, code, files=None, argv=None, stdin=None):
shutil
.
copytree
(
filename
,
dest
)
# Create the main file.
with
open
(
os
.
path
.
join
(
tmpdir
,
"jailed_code.py"
),
"w"
)
as
jailed
:
if
code
:
with
open
(
os
.
path
.
join
(
tmpdir
,
"jailed_code"
),
"w"
)
as
jailed
:
jailed
.
write
(
code
)
cmd
=
COMMANDS
[
command
]
+
[
'jailed_code.py'
]
+
(
argv
or
[])
argv
=
[
"jailed_code"
]
+
argv
cmd
=
COMMANDS
[
command
]
+
argv
subproc
=
subprocess
.
Popen
(
cmd
,
preexec_fn
=
set_process_limits
,
cwd
=
tmpdir
,
...
...
common/lib/codejail/codejail/safe_exec.py
View file @
fb534323
...
...
@@ -85,7 +85,7 @@ def safe_exec(code, globals_dict, files=None, python_path=None):
log
.
debug
(
"Exec:
%
s"
,
code
)
log
.
debug
(
"Stdin:
%
s"
,
stdin
)
res
=
jail_code
.
jail_code
(
"python"
,
jailed_code
,
stdin
=
stdin
,
files
=
files
)
res
=
jail_code
.
jail_code
(
"python"
,
code
=
jailed_code
,
stdin
=
stdin
,
files
=
files
)
if
res
.
status
!=
0
:
raise
Exception
(
"Couldn't execute jailed code:
%
s"
%
res
.
stderr
)
globals_dict
.
update
(
json
.
loads
(
res
.
stdout
))
...
...
common/lib/codejail/codejail/tests/doit.py
0 → 100644
View file @
fb534323
import
sys
print
"This is doit.py!"
print
"My args are
%
r"
%
(
sys
.
argv
,)
common/lib/codejail/codejail/tests/test_jailpy.py
View file @
fb534323
...
...
@@ -11,9 +11,15 @@ dedent = textwrap.dedent
def
jailpy
(
*
args
,
**
kwargs
):
"""Run `jail_code` on Python."""
return
jail_code
(
"python"
,
*
args
,
**
kwargs
)
def
file_here
(
fname
):
"""Return the full path to a file alongside this code."""
return
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
fname
)
class
JailCodeHelpers
(
object
):
"""Assert helpers for jail_code tests."""
def
setUp
(
self
):
...
...
@@ -28,32 +34,32 @@ class JailCodeHelpers(object):
class
TestFeatures
(
JailCodeHelpers
,
unittest
.
TestCase
):
def
test_hello_world
(
self
):
res
=
jailpy
(
"print 'Hello, world!'"
)
res
=
jailpy
(
code
=
"print 'Hello, world!'"
)
self
.
assertResultOk
(
res
)
self
.
assertEqual
(
res
.
stdout
,
'Hello, world!
\n
'
)
def
test_argv
(
self
):
res
=
jailpy
(
"import sys; print ':'.join(sys.argv[1:])"
,
code
=
"import sys; print ':'.join(sys.argv[1:])"
,
argv
=
[
"Hello"
,
"world"
,
"-x"
]
)
self
.
assertResultOk
(
res
)
self
.
assertEqual
(
res
.
stdout
,
"Hello:world:-x
\n
"
)
def
test_ends_with_exception
(
self
):
res
=
jailpy
(
"""raise Exception('FAIL')"""
)
res
=
jailpy
(
code
=
"""raise Exception('FAIL')"""
)
self
.
assertNotEqual
(
res
.
status
,
0
)
self
.
assertEqual
(
res
.
stdout
,
""
)
self
.
assertEqual
(
res
.
stderr
,
dedent
(
"""
\
Traceback (most recent call last):
File "jailed_code
.py
", line 1, in <module>
File "jailed_code", line 1, in <module>
raise Exception('FAIL')
Exception: FAIL
"""
))
def
test_stdin_is_provided
(
self
):
res
=
jailpy
(
"import json,sys; print sum(json.load(sys.stdin))"
,
code
=
"import json,sys; print sum(json.load(sys.stdin))"
,
stdin
=
"[1, 2.5, 33]"
)
self
.
assertResultOk
(
res
)
...
...
@@ -61,27 +67,35 @@ class TestFeatures(JailCodeHelpers, unittest.TestCase):
def
test_files_are_copied
(
self
):
res
=
jailpy
(
"print 'Look:', open('hello.txt').read()"
,
files
=
[
os
.
path
.
dirname
(
__file__
)
+
"/hello.txt"
]
code
=
"print 'Look:', open('hello.txt').read()"
,
files
=
[
file_here
(
"hello.txt"
)
]
)
self
.
assertResultOk
(
res
)
self
.
assertEqual
(
res
.
stdout
,
'Look: Hello there.
\n\n
'
)
def
test_executing_a_copied_file
(
self
):
res
=
jailpy
(
files
=
[
file_here
(
"doit.py"
)],
argv
=
[
"doit.py"
,
"1"
,
"2"
,
"3"
]
)
self
.
assertResultOk
(
res
)
self
.
assertEqual
(
res
.
stdout
,
"This is doit.py!
\n
My args are ['doit.py', '1', '2', '3']
\n
"
)
class
TestLimits
(
JailCodeHelpers
,
unittest
.
TestCase
):
def
test_cant_use_too_much_memory
(
self
):
res
=
jailpy
(
"print sum(range(100000000))"
)
res
=
jailpy
(
code
=
"print sum(range(100000000))"
)
self
.
assertNotEqual
(
res
.
status
,
0
)
self
.
assertEqual
(
res
.
stdout
,
""
)
def
test_cant_use_too_much_cpu
(
self
):
res
=
jailpy
(
"print sum(xrange(100000000))"
)
res
=
jailpy
(
code
=
"print sum(xrange(100000000))"
)
self
.
assertNotEqual
(
res
.
status
,
0
)
self
.
assertEqual
(
res
.
stdout
,
""
)
def
test_cant_use_too_much_time
(
self
):
raise
SkipTest
# TODO: test this once we can kill sleeping processes.
res
=
jailpy
(
dedent
(
"""
\
res
=
jailpy
(
code
=
dedent
(
"""
\
import time
time.sleep(5)
print 'Done!'
...
...
@@ -90,7 +104,7 @@ class TestLimits(JailCodeHelpers, unittest.TestCase):
self
.
assertEqual
(
res
.
stdout
,
""
)
def
test_cant_write_files
(
self
):
res
=
jailpy
(
dedent
(
"""
\
res
=
jailpy
(
code
=
dedent
(
"""
\
print "Trying"
with open("mydata.txt", "w") as f:
f.write("hello")
...
...
@@ -102,7 +116,7 @@ class TestLimits(JailCodeHelpers, unittest.TestCase):
self
.
assertIn
(
"ermission denied"
,
res
.
stderr
)
def
test_cant_use_network
(
self
):
res
=
jailpy
(
dedent
(
"""
\
res
=
jailpy
(
code
=
dedent
(
"""
\
import urllib
print "Reading google"
u = urllib.urlopen("http://google.com")
...
...
@@ -121,7 +135,7 @@ class TestLimits(JailCodeHelpers, unittest.TestCase):
class
TestMalware
(
JailCodeHelpers
,
unittest
.
TestCase
):
def
test_crash_cpython
(
self
):
# http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html
res
=
jailpy
(
dedent
(
"""
\
res
=
jailpy
(
code
=
dedent
(
"""
\
import new, sys
crash_me = new.function(new.code(0,0,0,0,"KABOOM",(),(),(),"","",0,""), {})
print "Here we go..."
...
...
@@ -134,7 +148,7 @@ class TestMalware(JailCodeHelpers, unittest.TestCase):
self
.
assertEqual
(
res
.
stderr
,
""
)
def
test_read_etc_passwd
(
self
):
res
=
jailpy
(
dedent
(
"""
\
res
=
jailpy
(
code
=
dedent
(
"""
\
bytes = len(open('/etc/passwd').read())
print 'Gotcha', bytes
"""
))
...
...
@@ -143,7 +157,7 @@ class TestMalware(JailCodeHelpers, unittest.TestCase):
self
.
assertIn
(
"ermission denied"
,
res
.
stderr
)
def
test_find_other_sandboxes
(
self
):
res
=
jailpy
(
dedent
(
"""
res
=
jailpy
(
code
=
dedent
(
"""
import os;
places = [
"..", "/tmp", "/", "/home", "/etc",
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment