openedx / codejail

Secure code execution
Apache License 2.0
390 stars 74 forks source link

Installation OSError: [Errno 2] No such file or directory #29

Open morenopc opened 10 years ago

morenopc commented 10 years ago

Hi,

I'm trying to follow the installation guide but when I tried to run the using codejail code on xserver devstack vangrat server:

import codejail.jail_code
codejail.jail_code.configure('python', '/bin/python')
import codejail.safe_exec
codejail.safe_exec.safe_exec("import os\nos.system('ls /etc')", {})

I got (OSError: [Errno 2] No such file or directory) error:

(xserver)xserver@precise64:/edx/app/xserver/xserver$ python
Python 2.7.3 (default, Feb 27 2014, 19:58:35) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import codejail.jail_code                                                                                                                         
>>> codejail.jail_code.configure('python', '/edx/app/xserver/venvs/xserver/bin/python')                                                   
>>> import codejail.safe_exec
>>> codejail.safe_exec.safe_exec("import os\nos.system('ls /etc')", {})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/edx/app/edxapp/venvs/edxapp/src/codejail/codejail/safe_exec.py", line 137, in safe_exec
    "python", code=jailed_code, stdin=stdin, files=files, slug=slug,
  File "/edx/app/edxapp/venvs/edxapp/src/codejail/codejail/jail_code.py", line 208, in jail_code
    stdout=subprocess.PIPE, stderr=subprocess.PIPE,
  File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1249, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

Debugging codejail I found that if user is None at def configure(command, bin_path, user=None): master/codejail/jail_code.py#L26

The commands cmd at subproc = subprocess.Popen master/codejail/jail_code.py#L219 is ['TMPDIR=tmp', '/edx/app/xserver/venvs/xserver/bin/python', '-E', '-B', 'jailed_code']. Because 'TMPDIR=tmp' is the first parameter to subprocess.Popen subprocess return OSError: [Errno 2] No such file or directory.

Otherwise if I add an user (sandbox) it seems to work:

>>> codejail.jail_code.configure('python', '/edx/app/xserver/venvs/xserver/bin/python', 'sandbox')
>>> codejail.safe_exec.safe_exec("import os\nos.system('ls /etc')", {})

cmd at subproc = subprocess.Popenmaster/codejail/jail_code.py#L219 is ['sudo', '-u', 'sandbox', 'TMPDIR=tmp', '/edx/app/xserver/venvs/xserver-sandbox/bin/python', '-E', '-B', 'jailed_code']

Is codejail work without an user?

morenopc commented 10 years ago

Moving on I'm trying to build an xserver grader test using https://github.com/antoviaque/xserver-grader. After install and test it I changed master/graders/grade.py to

import logging

import codejail.jail_code
import codejail.safe_exec

log = logging.getLogger(__name__)

def grade(grader_path, grader_config, student_response, sandbox):
    """Handle code grader submitions"""
    errors = []
    codejail.jail_code.configure(
        command='python',
        bin_path='/edx/app/edxapp/venvs/edxapp-sandbox/bin/python',
        user='sandbox')
    try:
        codejail.safe_exec.safe_exec(student_response, {})
    except Exception, e:
        errors.append(e)

    results = {
        'correct': False,
        'score': 1,
        'tests': [],
        'errors': errors
    }
    return results

But when this code runs after a POST submit from (open demo course) code grader I got:

vagrant@precise64:/edx/app$ less /edx/var/log/supervisor/xservertderr.log
2014-10-17 18:45:24 [17287] [INFO] Worker exiting (pid: 17287)
2014-10-17 18:45:24 [17286] [INFO] Worker exiting (pid: 17286)
2014-10-17 18:45:24 [21168] [INFO] Handling signal: term
2014-10-17 18:45:24 [21168] [INFO] Shutting down: Master
2014-10-17 18:45:27 [7337] [INFO] Starting gunicorn 0.17.4
2014-10-17 18:45:27 [7337] [INFO] Listening at: http://127.0.0.1:8050 (7337)
2014-10-17 18:45:27 [7337] [INFO] Using worker: sync
2014-10-17 18:45:27 [7344] [INFO] Booting worker with pid: 7344
2014-10-17 18:45:27 [7347] [INFO] Booting worker with pid: 7347
sudo: no tty present and no askpass program specified
Sorry, try again.
sudo: no tty present and no askpass program specified
Sorry, try again.
sudo: no tty present and no askpass program specified
Sorry, try again.
sudo: 3 incorrect password attempts

and

vagrant@precise64:/edx/app$ less /edx/var/log/supervisor/xservertdout.log
2014-10-17 18:45:24,829 INFO 17287 [gunicorn.error] glogging.py:213 - Worker exiting (pid: 17287)
2014-10-17 18:45:24,829 INFO 17286 [gunicorn.error] glogging.py:213 - Worker exiting (pid: 17286)
2014-10-17 18:45:24,833 INFO 21168 [gunicorn.error] glogging.py:213 - Handling signal: term
2014-10-17 18:45:24,835 INFO 21168 [gunicorn.error] glogging.py:213 - Shutting down: Master
Opening env.json file
2014-10-17 18:45:27,335 INFO 7337 [gunicorn.error] glogging.py:213 - Starting gunicorn 0.17.4
2014-10-17 18:45:27,336 INFO 7337 [gunicorn.error] glogging.py:213 - Listening at: http://127.0.0.1:8050 (7337)
2014-10-17 18:45:27,337 INFO 7337 [gunicorn.error] glogging.py:213 - Using worker: sync
2014-10-17 18:45:27,339 INFO 7344 [gunicorn.error] glogging.py:213 - Booting worker with pid: 7344
2014-10-17 18:45:27,366 INFO 7347 [gunicorn.error] glogging.py:213 - Booting worker with pid: 7347
2014-10-17 18:47:08,367 INFO 7347 [xserver.pyxserver_wsgi] pyxserver_wsgi.py:179 - Starting application
2014-10-17 18:47:08,368 INFO 7347 [grade] grade.py:13 - /edx/var/xserver/data/content-test-xserver/graders/graders/grade_bisect.py - {u'grader': u'gra
ders/grade_bisect.py'} - 27 - <module 'sandbox.sandbox' from '/edx/app/xserver/xserver/sandbox/sandbox.py'>
2014-10-17 18:47:08,390 ERROR 7347 [xserver.pyxserver_wsgi] pyxserver_wsgi.py:191 - Error processing request: {"xqueue_files": "{}", "xqueue_body": "{\"student_info\": \"{\\\"anonymous_student_id\\\": \\\"a87ff679a2f3e71d9181a67b7542122c\\\", \\\"submission_time\\\": \\\"20141017184708\\\"}\", \"grader_payload\": \"\\n{\\\"grader\\\": \\\"graders/grade_bisect.py\\\"}\\n\", \"student_response\": \"27\"}"}
Traceback (most recent call last):
  File "/edx/app/xserver/xserver/pyxserver_wsgi.py", line 189, in post_wrapper
    return do_POST(data)
  File "/edx/app/xserver/xserver/pyxserver_wsgi.py", line 169, in do_POST
    'msg': render_results(results) }
  File "/edx/app/xserver/xserver/pyxserver_wsgi.py", line 120, in render_results
    errors = format_errors(results['errors'])
  File "/edx/app/xserver/xserver/pyxserver_wsgi.py", line 79, in format_errors
    error_list = [esc(e) for e in errors or []]
  File "/usr/lib/python2.7/cgi.py", line 1035, in escape
    s = s.replace("&", "&amp;") # Must be done first!
AttributeError: 'SafeExecException' object has no attribute 'replace'

the SafeExecException is

[SafeExecException("Couldn't execute jailed code: sudo: no tty present and no askpass program specified\nSorry, try again.\nsudo: no tty present and no askpass program specified\nSorry, try again.\nsudo: no tty present and no askpass program specified\nSorry, try again.\nsudo: 3 incorrect password attempts\n",)]
feanil commented 10 years ago

@morenopc Code-Jail does not work without a user. The jailed code is run as a user that has limited capabilities. The one that is automatically created by the edx configuration scripts is 'sandbox' ati it has to be in your settings for XServer as you already discovered.

morenopc commented 10 years ago

Thanks @feanil. Can you tell me what is wrong with my configure files (https://github.com/edx/codejail/issues/17#issuecomment-59561395) that I'm keep getting the "sudo: no tty present and no askpass program specified" error using 'sandbox' user? The sandbox user is already able to act like sudo inside my devstack server.

vagrant@precise64:~$ sudo -u sandbox bash
sandbox@precise64:~$ sudo find / -name "codejail" -type d
/edx/app/edxapp/venvs/edxapp/src/codejail
/edx/app/edxapp/venvs/edxapp/src/codejail/codejail
/edx/app/xserver/venvs/xserver/src/codejail
/edx/app/xserver/venvs/xserver/src/codejail/codejail
sandbox@precise64:~$
e0d commented 10 years ago

I looks like your sudoers config isn't correct for the code jail user and you are being prompted for a password.

morenopc commented 10 years ago

Right @e0d. Can you see where this bug is based on my config files https://github.com/edx/codejail/issues/17#issuecomment-59561395?

e0d commented 10 years ago

What is the value of settings.DO_SANDBOXING? See settings.py for context.

morenopc commented 10 years ago
vagrant@precise64:/edx/app/xserver$ source venvs/xserver/bin/activate
(xserver)vagrant@precise64:/edx/app/xserver$
(xserver)vagrant@precise64:/edx/app/xserver$ python
Python 2.7.3 (default, Feb 27 2014, 19:58:35) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from xserver import settings
Opening env.json file
>>> settings.DO_SANDBOXING
True
>>> 

env.json

(xserver)vagrant@precise64:/edx/app/xserver$ vi env.json
{
    "GRADER_ROOT": "/edx/var/xserver/data/content-test-xserver/graders",
    "LOGGING_ENV": "sandbox",
    "LOG_DIR": "/edx/var/log/xserver",
    "RUN_URL": "",
    "SANDBOX_PYTHON": "/edx/app/xserver/venvs/xserver-sandbox/bin/python",
    "SYSLOG_SERVER": ""
}
~ 

The xserver settings.py is the same of the repository.

feanil commented 10 years ago

Also what are the settings in /etc/sudoers.d/ for the sandbox user. It should be set to not prompt for password when you try to sudo from the edxapp user to the sandbox user.

morenopc commented 10 years ago

/etc/sudoers.d/

(xserver)vagrant@precise64:/edx/app/xserver$ ls -la /etc/sudoers.d/
total 36
drwxr-xr-x   2 root root 4096 Oct 20 17:28 .
drwxr-xr-x 103 root root 4096 Oct 21 02:04 ..
-r--r-----   1 root root  326 Oct 17 19:07 01-sandbox
-r--r-----   1 root root  276 Oct 20 17:26 95-sandbox
-r--r-----   1 root root    1 Jun 27 15:08 99-restricted
-r--r-----   1 root root   32 Jun 27 15:08 edxadmin
-r--r-----   1 root root  753 Jan 31  2012 README
-r--r-----   1 root root   40 Jun 27 15:08 ssh_key_forward
-r--r-----   1 root root   34 Jun 27 16:02 x11_display

/etc/sudoers.d/01-sandbox

(xserver)vagrant@precise64:/edx/app/xserver$ sudo visudo -f /etc/sudoers.d/01-sandbox

edxapp ALL=(sandbox) SETENV:NOPASSWD:/edx/app/xserver/venvs/xserver-sandbox/bin/python
xserver ALL=(sandbox) SETENV:NOPASSWD:/edx/app/xserver/venvs/xserver-sandbox/bin/python
xserver ALL=(sandbox) SETENV:NOPASSWD:/usr/bin/find
xserver ALL=(ALL) NOPASSWD:/usr/bin/pkill
makeitso ALL=(sandbox) NOPASSWD:/usr/bin/python-sandbox

/etc/sudoers.d/95-sandbox

(xserver)vagrant@precise64:/edx/app/xserver$ sudo visudo -f /etc/sudoers.d/95-sandbox

edxapp ALL=(sandbox) SETENV:NOPASSWD:/edx/app/edxapp/venvs/edxapp-sandbox/bin/pyth
edxapp ALL=(sandbox) SETENV:NOPASSWD:/bin/rm /tmp/codejail-*/tmp
edxapp ALL=(sandbox) SETENV:NOPASSWD:/usr/bin/find
edxapp ALL=(ALL) NOPASSWD:/bin/kill
edxapp ALL=(ALL) NOPASSWD:/usr/bin/pkill
nedbat commented 10 years ago

@morenopc the 95-sandbox file you're showing here has a truncated filename:

edxapp ALL=(sandbox) SETENV:NOPASSWD:/edx/app/edxapp/venvs/edxapp-sandbox/bin/pyth

Does it really end with "pyth", or is that a copy-paste problem?

morenopc commented 10 years ago

Hi @nedbat. Right, I saw this today too and fixed it. Today I also granted root permission for 'xserver', 'edxapp' and 'sandbox' users in order to check why it keeps asking for sudo password but it didn't work.

Let me show you:

vagrant@precise64:/edx/app$ sudo -u xserver bash
bash: /home/vagrant/share_x11: Permission denied
xserver@precise64:/edx/app$ sudo -l
Matching Defaults entries for xserver on this host:
    env_reset, exempt_group=admin, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, env_keep+=SSH_AUTH_SOCK,
    env_keep+=DISPLAY

User xserver may run the following commands on this host:
    (sandbox) SETENV: NOPASSWD: /edx/app/xserver/venvs/xserver-sandbox/bin/python
    (sandbox) SETENV: NOPASSWD: /usr/bin/find
    (sandbox) SETENV: NOPASSWD: /bin/rm /tmp/codejail-*/tmp
    (ALL) NOPASSWD: /bin/kill
    (ALL) NOPASSWD: /usr/bin/pkill
    (ALL) NOPASSWD: ALL
    (ALL : ALL) ALL
xserver@precise64:/edx/app$
vagrant@precise64:/edx/app$ sudo -u edxapp bash
bash: /home/vagrant/share_x11: Permission denied
edxapp@precise64:/edx/app$ 
edxapp@precise64:/edx/app$ 
edxapp@precise64:/edx/app$ sudo -l
Matching Defaults entries for edxapp on this host:
    env_reset, exempt_group=admin, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, env_keep+=SSH_AUTH_SOCK,
    env_keep+=DISPLAY

User edxapp may run the following commands on this host:
    (sandbox) SETENV: NOPASSWD: /edx/app/edxapp/venvs/edxapp-sandbox/bin/python
    (sandbox) SETENV: NOPASSWD: /bin/rm /tmp/codejail-*/tmp
    (sandbox) SETENV: NOPASSWD: /usr/bin/find
    (ALL) NOPASSWD: /bin/kill
    (ALL) NOPASSWD: /usr/bin/pkill
    (ALL) NOPASSWD: ALL
    (ALL : ALL) ALL
edxapp@precise64:/edx/app$ 
vagrant@precise64:/edx/app$ sudo -u sandbox bash
bash: /home/vagrant/share_x11: Permission denied
sandbox@precise64:/edx/app$ sudo -l
Matching Defaults entries for sandbox on this host:
    env_reset, exempt_group=admin, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, env_keep+=SSH_AUTH_SOCK,
    env_keep+=DISPLAY

User sandbox may run the following commands on this host:
    (ALL) NOPASSWD: ALL
    (ALL : ALL) ALL
sandbox@precise64:/edx/app$

but

edxapp@precise64:~/edx-platform$ ./manage.py lms shell --settings=dev_pt_br
Python 2.7.3 (default, Feb 27 2014, 19:58:35) 
Type "copyright", "credits" or "license" for more information.

IPython 2.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: import codejail.jail_code

In [2]: import codejail.safe_exec

In [3]: codejail.jail_code.configure('python', '/edx/app/edxapp/venvs/edxapp-sandbox/bin/python', 'sandbox')                                           

In [4]: codejail.safe_exec.safe_exec('1+1', {})                                                                                                        
---------------------------------------------------------------------------
SafeExecException                         Traceback (most recent call last)
/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/core/management/commands/shell.pyc in <module>()
----> 1 codejail.safe_exec.safe_exec('1+1', {})

/edx/app/edxapp/venvs/edxapp/src/codejail/codejail/safe_exec.pyc in safe_exec(code, globals_dict, files, python_path, slug)
    139     if res.status != 0:
    140         raise SafeExecException(
--> 141             "Couldn't execute jailed code: %s" % res.stderr
    142         )
    143     globals_dict.update(json.loads(res.stdout))

SafeExecException: Couldn't execute jailed code: sudo: no tty present and no askpass program specified
Sorry, try again.
sudo: no tty present and no askpass program specified
Sorry, try again.
sudo: no tty present and no askpass program specified
Sorry, try again.
sudo: 3 incorrect password attempts