Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
codejail
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
codejail
Commits
a8a2de57
Commit
a8a2de57
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
543de052
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
46 additions
and
32 deletions
+46
-32
codejail/django_integration.py
+2
-2
codejail/jail_code.py
+28
-18
codejail/safe_exec.py
+3
-3
codejail/tests/test_jailpy.py
+13
-9
No files found.
codejail/django_integration.py
View file @
a8a2de57
...
@@ -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
codejail/jail
py
.py
→
codejail/jail
_code
.py
View file @
a8a2de57
...
@@ -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
,
...
...
codejail/safe_exec.py
View file @
a8a2de57
...
@@ -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
codejail/tests/test_jailpy.py
View file @
a8a2de57
"""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