summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2002-08-05 16:13:24 (GMT)
committerGuido van Rossum <guido@python.org>2002-08-05 16:13:24 (GMT)
commitaed51d8121f321e37274171b695cd0e3876465c6 (patch)
tree83e17c55398e4add85a2ed179e3c36ddf77cd776
parentaaebdd6a02dd4d650b14e2192e327336ecb62a98 (diff)
downloadcpython-aed51d8121f321e37274171b695cd0e3876465c6.zip
cpython-aed51d8121f321e37274171b695cd0e3876465c6.tar.gz
cpython-aed51d8121f321e37274171b695cd0e3876465c6.tar.bz2
SF patch 590294: os._execvpe security fix (Zack Weinberg).
1) Do not attempt to exec a file which does not exist just to find out what error the operating system returns. This is an exploitable race on all platforms that support symbolic links. 2) Immediately re-raise the exception if we get an error other than errno.ENOENT or errno.ENOTDIR. This may need to be adapted for other platforms. (As a security issue, this should be considered for 2.1 and 2.2 as well as 2.3.)
-rw-r--r--Lib/os.py27
1 files changed, 6 insertions, 21 deletions
diff --git a/Lib/os.py b/Lib/os.py
index f7929b4..9df1ba3 100644
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -319,8 +319,9 @@ def execvpe(file, args, env):
__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
-_notfound = None
def _execvpe(file, args, env=None):
+ from errno import ENOENT, ENOTDIR
+
if env is not None:
func = execve
argrest = (args, env)
@@ -328,7 +329,7 @@ def _execvpe(file, args, env=None):
func = execv
argrest = (args,)
env = environ
- global _notfound
+
head, tail = path.split(file)
if head:
apply(func, (file,) + argrest)
@@ -338,30 +339,14 @@ def _execvpe(file, args, env=None):
else:
envpath = defpath
PATH = envpath.split(pathsep)
- if not _notfound:
- if sys.platform[:4] == 'beos':
- # Process handling (fork, wait) under BeOS (up to 5.0)
- # doesn't interoperate reliably with the thread interlocking
- # that happens during an import. The actual error we need
- # is the same on BeOS for posix.open() et al., ENOENT.
- try: unlink('/_#.# ## #.#')
- except error, _notfound: pass
- else:
- import tempfile
- t = tempfile.mktemp()
- # Exec a file that is guaranteed not to exist
- try: execv(t, ('blah',))
- except error, _notfound: pass
- exc, arg = error, _notfound
for dir in PATH:
fullname = path.join(dir, file)
try:
apply(func, (fullname,) + argrest)
except error, (errno, msg):
- if errno != arg[0]:
- exc, arg = error, (errno, msg)
- raise exc, arg
-
+ if errno != ENOENT and errno != ENOTDIR:
+ raise
+ raise error, (errno, msg)
# Change environ to automatically call putenv() if it exists
try: