mirror of
https://github.com/python/cpython
synced 2024-09-16 08:26:36 +00:00
Address SF bug #577530: del __builtins__ breaks out of rexec
Using the suggestion there: add_module() forces __builtin__ back; this fixes r_exec, r_eval, r_execfile. The interactive console had to be fixed separately, because it doesn't use r_exec, but relies on the 'locals' dict having the right __builtins__. Fixed this by subclassing InteractiveConsole and overriding runcode(), which does the exec. This changes the banner output slightly: instead of starting with *** RESTRICTED ***, a subtler (RestrictedConsole) is printed before the first >>> prompt. Also import readline (if it exists) when the interactive console is used, for more convenient input editing and history. This does not mean that rexec is now considered safe! But for those willing to take the risk, it's safer than before. (Note that a safety analysis of the code module would be wise if you plan to use the interactive console for real -- I've only ever used it to play with restricted mode.) This should be backported to 2.2 and 2.1.
This commit is contained in:
parent
ad2bf5cb44
commit
7f7c3d0a9c
22
Lib/rexec.py
22
Lib/rexec.py
|
@ -288,9 +288,9 @@ def copy_none(self, src):
|
||||||
# Add a module -- return an existing module or create one
|
# Add a module -- return an existing module or create one
|
||||||
|
|
||||||
def add_module(self, mname):
|
def add_module(self, mname):
|
||||||
if mname in self.modules:
|
m = self.modules.get(mname)
|
||||||
return self.modules[mname]
|
if m is None:
|
||||||
self.modules[mname] = m = self.hooks.new_module(mname)
|
self.modules[mname] = m = self.hooks.new_module(mname)
|
||||||
m.__builtins__ = self.modules['__builtin__']
|
m.__builtins__ = self.modules['__builtin__']
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
@ -552,13 +552,17 @@ def test():
|
||||||
print "%s: can't open file %s" % (sys.argv[0], `args[0]`)
|
print "%s: can't open file %s" % (sys.argv[0], `args[0]`)
|
||||||
return 1
|
return 1
|
||||||
if fp.isatty():
|
if fp.isatty():
|
||||||
import code
|
|
||||||
try:
|
try:
|
||||||
code.interact(
|
import readline
|
||||||
"*** RESTRICTED *** Python %s on %s\n"
|
except ImportError:
|
||||||
'Type "help", "copyright", "credits" or "license" '
|
pass
|
||||||
"for more information." % (sys.version, sys.platform),
|
import code
|
||||||
local=r.modules['__main__'].__dict__)
|
class RestrictedConsole(code.InteractiveConsole):
|
||||||
|
def runcode(self, co):
|
||||||
|
self.locals['__builtins__'] = r.modules['__builtin__']
|
||||||
|
r.s_apply(code.InteractiveConsole.runcode, (self, co))
|
||||||
|
try:
|
||||||
|
RestrictedConsole(r.modules['__main__'].__dict__).interact()
|
||||||
except SystemExit, n:
|
except SystemExit, n:
|
||||||
return n
|
return n
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in a new issue