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
bde976da
Commit
bde976da
authored
Apr 09, 2013
by
Ned Batchelder
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor code_jail to accommodate non-Python code.
parent
55e910aa
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
47 additions
and
33 deletions
+47
-33
common/lib/capa/capa/safe_exec/safe_exec.py
+1
-1
common/lib/codejail/codejail/django_integration.py
+2
-2
common/lib/codejail/codejail/jail_code.py
+28
-18
common/lib/codejail/codejail/safe_exec.py
+3
-3
common/lib/codejail/codejail/tests/test_jailpy.py
+13
-9
No files found.
common/lib/capa/capa/safe_exec/safe_exec.py
View file @
bde976da
...
@@ -30,7 +30,7 @@ ASSUMED_IMPORTS=[
...
@@ -30,7 +30,7 @@ ASSUMED_IMPORTS=[
(
"draganddrop"
,
"verifiers.draganddrop"
),
(
"draganddrop"
,
"verifiers.draganddrop"
),
]
]
# We'll need the code from lazymod.py for use in
jailpy
, so read it now.
# We'll need the code from lazymod.py for use in
safe_exec
, so read it now.
lazymod_py_file
=
lazymod
.
__file__
lazymod_py_file
=
lazymod
.
__file__
if
lazymod_py_file
.
endswith
(
"c"
):
if
lazymod_py_file
.
endswith
(
"c"
):
lazymod_py_file
=
lazymod_py_file
[:
-
1
]
lazymod_py_file
=
lazymod_py_file
[:
-
1
]
...
...
common/lib/codejail/codejail/django_integration.py
View file @
bde976da
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
from
django.core.exceptions
import
MiddlewareNotUsed
from
django.core.exceptions
import
MiddlewareNotUsed
from
django.conf
import
settings
from
django.conf
import
settings
import
codejail.jail
py
import
codejail.jail
_code
class
ConfigureCodeJailMiddleware
(
object
):
class
ConfigureCodeJailMiddleware
(
object
):
...
@@ -13,5 +13,5 @@ class ConfigureCodeJailMiddleware(object):
...
@@ -13,5 +13,5 @@ class ConfigureCodeJailMiddleware(object):
python_bin
=
settings
.
CODE_JAIL
.
get
(
'python_bin'
)
python_bin
=
settings
.
CODE_JAIL
.
get
(
'python_bin'
)
if
python_bin
:
if
python_bin
:
user
=
settings
.
CODE_JAIL
[
'user'
]
user
=
settings
.
CODE_JAIL
[
'user'
]
codejail
.
jail
py
.
configure
(
python_bin
,
user
=
user
)
codejail
.
jail
_code
.
configure
(
"python"
,
python_bin
,
user
=
user
)
raise
MiddlewareNotUsed
raise
MiddlewareNotUsed
common/lib/codejail/codejail/jail
py
.py
→
common/lib/codejail/codejail/jail
_code
.py
View file @
bde976da
...
@@ -19,39 +19,49 @@ log = logging.getLogger(__name__)
...
@@ -19,39 +19,49 @@ log = logging.getLogger(__name__)
# TODO: limit too much stdout data?
# TODO: limit too much stdout data?
# Configure the
Python command
# Configure the
commands
PYTHON_CMD
=
None
# COMMANDS is a map from an abstract command name to a list of command-line
# pieces, such as subprocess.Popen wants.
COMMANDS
=
{}
def
configure
(
python_bin
,
user
=
None
):
def
configure
(
command
,
bin_path
,
user
=
None
):
"""Configure the jailpy module."""
"""Configure a command for jail_code to use.
global
PYTHON_CMD
PYTHON_CMD
=
[]
`command` is the abstract command you're configuring, such as "python" or
"node". `bin_path` is the path to the binary. `user`, if provided, is
the user name to run the command under.
"""
cmd_argv
=
[]
if
user
:
if
user
:
PYTHON_CMD
.
extend
([
'sudo'
,
'-u'
,
'sandbox'
])
cmd_argv
.
extend
([
'sudo'
,
'-u'
,
'sandbox'
])
PYTHON_CMD
.
extend
([
python_bin
,
'-E'
])
cmd_argv
.
extend
([
bin_path
,
'-E'
])
COMMANDS
[
command
]
=
cmd_argv
def
is_configured
():
def
is_configured
(
command
):
return
bool
(
PYTHON_CMD
)
return
command
in
COMMANDS
# By default, look where our current Python is, and maybe there's a
# By default, look where our current Python is, and maybe there's a
# python-sandbox alongside. Only do this if running in a virtualenv.
# python-sandbox alongside. Only do this if running in a virtualenv.
if
hasattr
(
sys
,
'real_prefix'
):
if
hasattr
(
sys
,
'real_prefix'
):
if
os
.
path
.
isdir
(
sys
.
prefix
+
"-sandbox"
):
if
os
.
path
.
isdir
(
sys
.
prefix
+
"-sandbox"
):
configure
(
sys
.
prefix
+
"-sandbox/bin/python"
,
"sandbox"
)
configure
(
"python"
,
sys
.
prefix
+
"-sandbox/bin/python"
,
"sandbox"
)
class
JailResult
(
object
):
class
JailResult
(
object
):
"""A passive object for us to return from jail
py
."""
"""A passive object for us to return from jail
_code
."""
def
__init__
(
self
):
def
__init__
(
self
):
self
.
stdout
=
self
.
stderr
=
self
.
status
=
None
self
.
stdout
=
self
.
stderr
=
self
.
status
=
None
def
jailpy
(
code
,
files
=
None
,
argv
=
None
,
stdin
=
None
):
def
jail_code
(
command
,
code
,
files
=
None
,
argv
=
None
,
stdin
=
None
):
"""
"""Run code in a jailed subprocess.
Run Python 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 Python code to run.
...
@@ -64,8 +74,8 @@ def jailpy(code, files=None, argv=None, stdin=None):
...
@@ -64,8 +74,8 @@ def jailpy(code, files=None, argv=None, stdin=None):
.status: return status of the process: an int, 0 for successful
.status: return status of the process: an int, 0 for successful
"""
"""
if
not
PYTHON_CMD
:
if
not
is_configured
(
command
)
:
raise
Exception
(
"jail
py needs to be configured"
)
raise
Exception
(
"jail
_code needs to be configured for
%
r"
%
command
)
with
temp_directory
(
delete_when_done
=
True
)
as
tmpdir
:
with
temp_directory
(
delete_when_done
=
True
)
as
tmpdir
:
...
@@ -83,7 +93,7 @@ def jailpy(code, files=None, argv=None, stdin=None):
...
@@ -83,7 +93,7 @@ def jailpy(code, files=None, argv=None, stdin=None):
with
open
(
os
.
path
.
join
(
tmpdir
,
"jailed_code.py"
),
"w"
)
as
jailed
:
with
open
(
os
.
path
.
join
(
tmpdir
,
"jailed_code.py"
),
"w"
)
as
jailed
:
jailed
.
write
(
code
)
jailed
.
write
(
code
)
cmd
=
PYTHON_CMD
+
[
'jailed_code.py'
]
+
(
argv
or
[])
cmd
=
COMMANDS
[
command
]
+
[
'jailed_code.py'
]
+
(
argv
or
[])
subproc
=
subprocess
.
Popen
(
subproc
=
subprocess
.
Popen
(
cmd
,
preexec_fn
=
set_process_limits
,
cwd
=
tmpdir
,
cmd
,
preexec_fn
=
set_process_limits
,
cwd
=
tmpdir
,
...
...
common/lib/codejail/codejail/safe_exec.py
View file @
bde976da
...
@@ -7,7 +7,7 @@ import shutil
...
@@ -7,7 +7,7 @@ import shutil
import
sys
import
sys
import
textwrap
import
textwrap
from
codejail
import
jail
py
from
codejail
import
jail
_code
from
codejail.util
import
temp_directory
,
change_directory
from
codejail.util
import
temp_directory
,
change_directory
log
=
logging
.
getLogger
(
__name__
)
log
=
logging
.
getLogger
(
__name__
)
...
@@ -85,7 +85,7 @@ def safe_exec(code, globals_dict, files=None, python_path=None):
...
@@ -85,7 +85,7 @@ def safe_exec(code, globals_dict, files=None, python_path=None):
log
.
debug
(
"Exec:
%
s"
,
code
)
log
.
debug
(
"Exec:
%
s"
,
code
)
log
.
debug
(
"Stdin:
%
s"
,
stdin
)
log
.
debug
(
"Stdin:
%
s"
,
stdin
)
res
=
jail
py
.
jailpy
(
jailed_code
,
stdin
=
stdin
,
files
=
files
)
res
=
jail
_code
.
jail_code
(
"python"
,
jailed_code
,
stdin
=
stdin
,
files
=
files
)
if
res
.
status
!=
0
:
if
res
.
status
!=
0
:
raise
Exception
(
"Couldn't execute jailed code:
%
s"
%
res
.
stderr
)
raise
Exception
(
"Couldn't execute jailed code:
%
s"
%
res
.
stderr
)
globals_dict
.
update
(
json
.
loads
(
res
.
stdout
))
globals_dict
.
update
(
json
.
loads
(
res
.
stdout
))
...
@@ -144,5 +144,5 @@ def not_safe_exec(code, globals_dict, files=None, python_path=None):
...
@@ -144,5 +144,5 @@ def not_safe_exec(code, globals_dict, files=None, python_path=None):
# Running Python code in the sandbox makes it difficult to debug.
# Running Python code in the sandbox makes it difficult to debug.
# Change 0 to 1 to run the code directly.
# Change 0 to 1 to run the code directly.
if
0
or
not
jail
py
.
is_configured
(
):
if
0
or
not
jail
_code
.
is_configured
(
"python"
):
safe_exec
=
not_safe_exec
safe_exec
=
not_safe_exec
common/lib/codejail/codejail/tests/test_jailpy.py
View file @
bde976da
"""Test jail
py
.py"""
"""Test jail
_code
.py"""
import
os.path
import
os.path
import
textwrap
import
textwrap
import
unittest
import
unittest
from
nose.plugins.skip
import
SkipTest
from
nose.plugins.skip
import
SkipTest
from
codejail.jail
py
import
jailpy
,
is_configured
from
codejail.jail
_code
import
jail_code
,
is_configured
dedent
=
textwrap
.
dedent
dedent
=
textwrap
.
dedent
class
JailPyHelpers
(
object
):
def
jailpy
(
*
args
,
**
kwargs
):
"""Assert helpers for jailpy tests."""
return
jail_code
(
"python"
,
*
args
,
**
kwargs
)
class
JailCodeHelpers
(
object
):
"""Assert helpers for jail_code tests."""
def
setUp
(
self
):
def
setUp
(
self
):
super
(
Jail
Py
Helpers
,
self
)
.
setUp
()
super
(
Jail
Code
Helpers
,
self
)
.
setUp
()
if
not
is_configured
():
if
not
is_configured
(
"python"
):
raise
SkipTest
raise
SkipTest
def
assertResultOk
(
self
,
res
):
def
assertResultOk
(
self
,
res
):
...
@@ -22,7 +26,7 @@ class JailPyHelpers(object):
...
@@ -22,7 +26,7 @@ class JailPyHelpers(object):
self
.
assertEqual
(
res
.
status
,
0
)
self
.
assertEqual
(
res
.
status
,
0
)
class
TestFeatures
(
Jail
Py
Helpers
,
unittest
.
TestCase
):
class
TestFeatures
(
Jail
Code
Helpers
,
unittest
.
TestCase
):
def
test_hello_world
(
self
):
def
test_hello_world
(
self
):
res
=
jailpy
(
"print 'Hello, world!'"
)
res
=
jailpy
(
"print 'Hello, world!'"
)
self
.
assertResultOk
(
res
)
self
.
assertResultOk
(
res
)
...
@@ -64,7 +68,7 @@ class TestFeatures(JailPyHelpers, unittest.TestCase):
...
@@ -64,7 +68,7 @@ class TestFeatures(JailPyHelpers, unittest.TestCase):
self
.
assertEqual
(
res
.
stdout
,
'Look: Hello there.
\n\n
'
)
self
.
assertEqual
(
res
.
stdout
,
'Look: Hello there.
\n\n
'
)
class
TestLimits
(
Jail
Py
Helpers
,
unittest
.
TestCase
):
class
TestLimits
(
Jail
Code
Helpers
,
unittest
.
TestCase
):
def
test_cant_use_too_much_memory
(
self
):
def
test_cant_use_too_much_memory
(
self
):
res
=
jailpy
(
"print sum(range(100000000))"
)
res
=
jailpy
(
"print sum(range(100000000))"
)
self
.
assertNotEqual
(
res
.
status
,
0
)
self
.
assertNotEqual
(
res
.
status
,
0
)
...
@@ -114,7 +118,7 @@ class TestLimits(JailPyHelpers, unittest.TestCase):
...
@@ -114,7 +118,7 @@ class TestLimits(JailPyHelpers, unittest.TestCase):
# TODO: fork
# TODO: fork
class
TestMalware
(
Jail
Py
Helpers
,
unittest
.
TestCase
):
class
TestMalware
(
Jail
Code
Helpers
,
unittest
.
TestCase
):
def
test_crash_cpython
(
self
):
def
test_crash_cpython
(
self
):
# http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html
# http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html
res
=
jailpy
(
dedent
(
"""
\
res
=
jailpy
(
dedent
(
"""
\
...
...
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