Now that file objects are subclassable, you can get at the file constructor

just by doing type(f) where f is any file object.  This left a hole in
restricted execution mode that rexec.py can't plug by itself (although it
can plug part of it; the rest is plugged in fileobject.c now).
This commit is contained in:
Tim Peters 2001-09-13 21:01:29 +00:00
parent 561f899d19
commit 8fa45677c1
3 changed files with 52 additions and 2 deletions

View File

@ -132,7 +132,7 @@ class RExec(ihooks._Verbose):
ok_sys_names = ('ps1', 'ps2', 'copyright', 'version',
'platform', 'exit', 'maxint')
nok_builtin_names = ('open', 'reload', '__import__')
nok_builtin_names = ('open', 'file', 'reload', '__import__')
def __init__(self, hooks = None, verbose = 0):
ihooks._Verbose.__init__(self, verbose)
@ -186,7 +186,7 @@ class RExec(ihooks._Verbose):
m = self.copy_except(__builtin__, self.nok_builtin_names)
m.__import__ = self.r_import
m.reload = self.r_reload
m.open = self.r_open
m.open = m.file = self.r_open
def make_main(self):
m = self.add_module('__main__')

View File

@ -1717,6 +1717,47 @@ def keywords():
raise TestFailed("expected TypeError from bogus keyword "
"argument to %r" % constructor)
def restricted():
import rexec
if verbose:
print "Testing interaction with restricted execution ..."
sandbox = rexec.RExec()
code1 = """f = open(%r, 'w')""" % TESTFN
code2 = """f = file(%r, 'w')""" % TESTFN
code3 = """\
f = open(%r)
t = type(f) # a sneaky way to get the file() constructor
f.close()
f = t(%r, 'w') # rexec can't catch this by itself
""" % (TESTFN, TESTFN)
f = open(TESTFN, 'w') # Create the file so code3 can find it.
f.close()
try:
for code in code1, code2, code3:
try:
sandbox.r_exec(code)
except IOError, msg:
if str(msg).find("restricted") >= 0:
outcome = "OK"
else:
outcome = "got an exception, but not an expected one"
else:
outcome = "expected a restricted-execution exception"
if outcome != "OK":
raise TestFailed("%s, in %r" % (outcome, code))
finally:
try:
import os
os.unlink(TESTFN)
except:
pass
def all():
lists()
dicts()
@ -1752,6 +1793,7 @@ def all():
supers()
inherits()
keywords()
restricted()
all()

View File

@ -92,6 +92,14 @@ open_the_file(PyFileObject *f, char *name, char *mode)
assert(name != NULL);
assert(mode != NULL);
/* rexec.py can't stop a user from getting the file() constructor --
all they have to do is get *any* file object f, and then do
type(f). Here we prevent them from doing damage with it. */
if (PyEval_GetRestricted()) {
PyErr_SetString(PyExc_IOError,
"file() constructor not accessible in restricted mode");
return NULL;
}
#ifdef HAVE_FOPENRF
if (*mode == '*') {
FILE *fopenRF();