Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 59b2a74

Browse files
committed
SF bug 533625 (Armin Rigo). rexec: potential security hole
If a rexec instance allows writing in the current directory (a common thing to do), there's a way to execute bogus bytecode. Fix this by not allowing imports from .pyc files (in a way that allows a site to configure things so that .pyc files *are* allowed, if writing is not allowed). I'll apply this to 2.2 and 2.1 too.
1 parent 9788384 commit 59b2a74

2 files changed

Lines changed: 23 additions & 1 deletion

File tree

Doc/lib/librexec.tex

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,18 @@ \subsection{Defining restricted environments \label{rexec-extension}}
211211
'copyright', 'version', 'platform', 'exit', 'maxint')}.
212212
\end{memberdesc}
213213

214+
\begin{memberdesc}{ok_file_types}
215+
Contains the file types from which modules are allowed to be loaded.
216+
Each file type is an integer constant defined in the \refmodule{imp} module.
217+
The meaningful values are \constant{PY_SOURCE}, \constant{PY_COMPILED}, and
218+
\constant{C_EXTENSION}. The value for \class{RExec} is \code{(C_EXTENSION,
219+
PY_SOURCE)}. Adding \constant{PY_COMPILED} in subclasses is not recommended;
220+
an attacker could exit the restricted execution mode by putting a forged
221+
byte-compiled file (\file{.pyc}) anywhere in your file system, for example
222+
by writing it to \file{/tmp} or uploading it to the \file{/incoming}
223+
directory of your public FTP server.
224+
\end{memberdesc}
225+
214226

215227
\subsection{An example}
216228

Lib/rexec.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import __builtin__
2323
import os
2424
import ihooks
25+
import imp
2526

2627
__all__ = ["RExec"]
2728

@@ -83,6 +84,9 @@ def set_rexec(self, rexec):
8384
# Called by RExec instance to complete initialization
8485
self.rexec = rexec
8586

87+
def get_suffixes(self):
88+
return self.rexec.get_suffixes()
89+
8690
def is_builtin(self, name):
8791
return self.rexec.is_builtin(name)
8892

@@ -144,6 +148,8 @@ class RExec(ihooks._Verbose):
144148

145149
nok_builtin_names = ('open', 'file', 'reload', '__import__')
146150

151+
ok_file_types = (imp.C_EXTENSION, imp.PY_SOURCE)
152+
147153
def __init__(self, hooks = None, verbose = 0):
148154
"""Returns an instance of the RExec class.
149155
@@ -203,7 +209,6 @@ def load_dynamic(self, name, filename, file):
203209
if sys.modules.has_key(name):
204210
src = sys.modules[name]
205211
else:
206-
import imp
207212
src = imp.load_dynamic(name, filename, file)
208213
dst = self.copy_except(src, [])
209214
return dst
@@ -214,6 +219,11 @@ def make_initial_modules(self):
214219

215220
# Helpers for RHooks
216221

222+
def get_suffixes(self):
223+
return [item # (suff, mode, type)
224+
for item in imp.get_suffixes()
225+
if item[2] in self.ok_file_types]
226+
217227
def is_builtin(self, mname):
218228
return mname in self.ok_builtin_modules
219229

0 commit comments

Comments
 (0)