Applying patch

[#636769] Fix for major rexec bugs

* Lib/rexec.py
  (FileBase): Added 'xreadlines' and '__iter__' to allowed file methods.
  (FileWrapper.__init__): Removed unnecessary self.f variable, which gave
  direct access to the file object.
  (RExec): Added 'xreadlines' and '_weakref' to allowed modules.
  (RExec.r_open): Convert string subclasses to a real string classes
  before doing comparisons with mode parameter.

* Lib/ihooks.py
  (BasicModuleImporter.import_module/reload/unload): Convert the module
  name to a real string before working with it.
  (ModuleImporter.import_module/import_it/reload): Convert the module
  name to a real strings before working with it.

* Misc/NEWS
  Document the change.
This commit is contained in:
Gustavo Niemeyer 2002-12-16 13:11:57 +00:00
parent 822a77fcc7
commit d5ae01a803
3 changed files with 15 additions and 7 deletions

View File

@ -352,6 +352,7 @@ class BasicModuleImporter(_Verbose):
return self.loader.set_hooks(hooks) return self.loader.set_hooks(hooks)
def import_module(self, name, globals={}, locals={}, fromlist=[]): def import_module(self, name, globals={}, locals={}, fromlist=[]):
name = str(name)
if name in self.modules: if name in self.modules:
return self.modules[name] # Fast path return self.modules[name] # Fast path
stuff = self.loader.find_module(name) stuff = self.loader.find_module(name)
@ -360,14 +361,14 @@ class BasicModuleImporter(_Verbose):
return self.loader.load_module(name, stuff) return self.loader.load_module(name, stuff)
def reload(self, module, path = None): def reload(self, module, path = None):
name = module.__name__ name = str(module.__name__)
stuff = self.loader.find_module(name, path) stuff = self.loader.find_module(name, path)
if not stuff: if not stuff:
raise ImportError, "Module %s not found for reload" % name raise ImportError, "Module %s not found for reload" % name
return self.loader.load_module(name, stuff) return self.loader.load_module(name, stuff)
def unload(self, module): def unload(self, module):
del self.modules[module.__name__] del self.modules[str(module.__name__)]
# XXX Should this try to clear the module's namespace? # XXX Should this try to clear the module's namespace?
def install(self): def install(self):
@ -394,7 +395,7 @@ class ModuleImporter(BasicModuleImporter):
def import_module(self, name, globals=None, locals=None, fromlist=None): def import_module(self, name, globals=None, locals=None, fromlist=None):
parent = self.determine_parent(globals) parent = self.determine_parent(globals)
q, tail = self.find_head_package(parent, name) q, tail = self.find_head_package(parent, str(name))
m = self.load_tail(q, tail) m = self.load_tail(q, tail)
if not fromlist: if not fromlist:
return q return q
@ -480,16 +481,18 @@ class ModuleImporter(BasicModuleImporter):
path = parent and parent.__path__ path = parent and parent.__path__
except AttributeError: except AttributeError:
return None return None
partname = str(partname)
stuff = self.loader.find_module(partname, path) stuff = self.loader.find_module(partname, path)
if not stuff: if not stuff:
return None return None
fqname = str(fqname)
m = self.loader.load_module(fqname, stuff) m = self.loader.load_module(fqname, stuff)
if parent: if parent:
setattr(parent, partname, m) setattr(parent, partname, m)
return m return m
def reload(self, module): def reload(self, module):
name = module.__name__ name = str(module.__name__)
if '.' not in name: if '.' not in name:
return self.import_it(name, name, None, force_load=1) return self.import_it(name, name, None, force_load=1)
i = name.rfind('.') i = name.rfind('.')

View File

@ -29,7 +29,8 @@ __all__ = ["RExec"]
class FileBase: class FileBase:
ok_file_methods = ('fileno', 'flush', 'isatty', 'read', 'readline', ok_file_methods = ('fileno', 'flush', 'isatty', 'read', 'readline',
'readlines', 'seek', 'tell', 'write', 'writelines') 'readlines', 'seek', 'tell', 'write', 'writelines', 'xreadlines',
'__iter__')
class FileWrapper(FileBase): class FileWrapper(FileBase):
@ -37,7 +38,6 @@ class FileWrapper(FileBase):
# XXX This is just like a Bastion -- should use that! # XXX This is just like a Bastion -- should use that!
def __init__(self, f): def __init__(self, f):
self.f = f
for m in self.ok_file_methods: for m in self.ok_file_methods:
if not hasattr(self, m) and hasattr(f, m): if not hasattr(self, m) and hasattr(f, m):
setattr(self, m, getattr(f, m)) setattr(self, m, getattr(f, m))
@ -137,7 +137,8 @@ class RExec(ihooks._Verbose):
'cmath', 'errno', 'imageop', 'cmath', 'errno', 'imageop',
'marshal', 'math', 'md5', 'operator', 'marshal', 'math', 'md5', 'operator',
'parser', 'regex', 'pcre', 'rotor', 'select', 'parser', 'regex', 'pcre', 'rotor', 'select',
'sha', '_sre', 'strop', 'struct', 'time') 'sha', '_sre', 'strop', 'struct', 'time',
'xreadlines', '_weakref')
ok_posix_names = ('error', 'fstat', 'listdir', 'lstat', 'readlink', ok_posix_names = ('error', 'fstat', 'listdir', 'lstat', 'readlink',
'stat', 'times', 'uname', 'getpid', 'getppid', 'stat', 'times', 'uname', 'getpid', 'getppid',
@ -515,6 +516,7 @@ class RExec(ihooks._Verbose):
used to change the policies enforced by a restricted environment. used to change the policies enforced by a restricted environment.
""" """
mode = str(mode)
if mode not in ('r', 'rb'): if mode not in ('r', 'rb'):
raise IOError, "can't open files for writing in restricted mode" raise IOError, "can't open files for writing in restricted mode"
return open(file, mode, buf) return open(file, mode, buf)

View File

@ -667,6 +667,9 @@ Library
unix environment even if DISPLAY was not set. Also, support for unix environment even if DISPLAY was not set. Also, support for
skipstone browser was included. skipstone browser was included.
- Fixed bug #636769: rexec would run unallowed code if subclasses of
strings were used as parameters for certain functions.
Tools/Demos Tools/Demos
----------- -----------