os.execve(pth,args,env) and os.chroot(pth) = problems

  • Thread starter goodnamesalltaken
  • Start date
G

goodnamesalltaken

Hello fellow python users,

I've been working on a basic implementation of a privilege separated
web server, and I've goto the point of running a basic cgi script.
Basically when the execCGI function in my Unpriv.py program is called a
few things should happen, it should fork (which it does), the stdout of
the child should be redirected to a given pipe (which it does), and the
script should execute using execve(which is has problems with). Also
before the execCGI() fucntion is executed, a few important things
happen in __init__: os.chroot('/var/www/webroot/') the path is web
server root and os.setuid(33) where 33 is the uid of a user on my
machine. It seems me that the os.chroot() call is messing up the
os.execve() (which executes the cgi script). os.execve(pth, args,
envVariables) is only executed if os.path.exists(pth) returns True.
But when I run a CGI script that os.path.exists(pth) returns True for,
then os.execve(pth) python throws back the error:

File "/***/***/***/Unpriv.py", line 201, in execCGI
OSError: [Errno 2] No such file or directory

However I don't see how this is possible if os.path.exists(pth) returns
True, why is it os.execve() has problems finding it.

I thought it might be a user permission problem, but I've run it
without the chroot and with the setuid and it works fine. So I'm
pretty sure its something to do with the chroot conflicting with the
os.execve(). Also execution privileges for the script file are also
checked before execution.


Any insight would be greatly appreciated


Here are the relevant functions of Unpriv.py


class Unpriv(object):

def __init__(self):
pipes = sys.argv
self.fromParent, self.toParent = os.pipe()
# this is just how http requested are recieved from a privilege
part and sent back
os.dup2(int(pipes[2]), self. toParent) ##write
os.dup2(int(pipes[1]), self.fromParent) ##read

os.chroot('/var/www/webroot/') ##chrooting
os.setuid(33) ##setuid


def checkFileExists(self, pth): ## just calls os.path.exists()
return os.path.exists(pth)


def execCGI(self, pth):
##
x = pth.rfind('?')
if x > -1:
path = pth[:x]
query = pth[x+1:]
query = query.replace('+', ' ')
else:
path = pth
query = ''

##populate enviroment variables, not yet implemented
envVariables = {}

readEnd, writeEnd = os.pipe()
parentStout = sys.stdout.fileno()
args = ['']
args.append(query)

pid = os.fork()

if pid == 0:
##child

os.dup2(writeEnd, sys.stdout.fileno()) ##this works

## this is the problem!
if self.checkFileExists(pth):
os.execve(pth , args, envVariables)
else:
## just some debug info for me.
## in fact part of pth is there
##however for some reason execve doesn't see
print 'the directory listing is:',
os.listdir(os.getcwd())

os._exit(0)

else: #parent
#read the output from the script
scriptOutPut = os.read(readEnd, 100000)
#just some debug info for me
print 'OUTPUT FROM SCRIPT EXECUTION: ' , scriptOutPut
return scriptOutPut

Please excuse any problems with the formatting.
Thanks in advance.
 
D

Donn Cave

... It seems me that the os.chroot() call is messing up the
os.execve() (which executes the cgi script). os.execve(pth, args,
envVariables) is only executed if os.path.exists(pth) returns True.
But when I run a CGI script that os.path.exists(pth) returns True for,
then os.execve(pth) python throws back the error:

File "/***/***/***/Unpriv.py", line 201, in execCGI
OSError: [Errno 2] No such file or directory

However I don't see how this is possible if os.path.exists(pth) returns
True, why is it os.execve() has problems finding it.

I haven't used chroot enough to know all the pitfalls, but
here's one guess: suppose the CGI script file `pth' might
actually be a script, with a `#!' top line that points to
an interpreter that isn't there, in your chroot space?

Donn Cave, (e-mail address removed)
 
G

goodnamesalltaken

Thanks for the reply Donn,
It seems logical enough to me that finding #!/usr/bin/env python in the
script file with the chroot I have used, is the problem. Once again
thank you for the help.

Regards,
Gavin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top