Skip to content

Commit d31a803

Browse files
committed
Backport of 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.
1 parent a1a5a89 commit d31a803

File tree

1 file changed

+6
-21
lines changed

1 file changed

+6
-21
lines changed

Lib/os.py

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -301,16 +301,17 @@ def execvpe(file, args, env):
301301

302302
__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
303303

304-
_notfound = None
305304
def _execvpe(file, args, env=None):
305+
from errno import ENOENT, ENOTDIR
306+
306307
if env is not None:
307308
func = execve
308309
argrest = (args, env)
309310
else:
310311
func = execv
311312
argrest = (args,)
312313
env = environ
313-
global _notfound
314+
314315
head, tail = path.split(file)
315316
if head:
316317
apply(func, (file,) + argrest)
@@ -320,30 +321,14 @@ def _execvpe(file, args, env=None):
320321
else:
321322
envpath = defpath
322323
PATH = envpath.split(pathsep)
323-
if not _notfound:
324-
if sys.platform[:4] == 'beos':
325-
# Process handling (fork, wait) under BeOS (up to 5.0)
326-
# doesn't interoperate reliably with the thread interlocking
327-
# that happens during an import. The actual error we need
328-
# is the same on BeOS for posix.open() et al., ENOENT.
329-
try: unlink('/_#.# ## #.#')
330-
except error, _notfound: pass
331-
else:
332-
import tempfile
333-
t = tempfile.mktemp()
334-
# Exec a file that is guaranteed not to exist
335-
try: execv(t, ('blah',))
336-
except error, _notfound: pass
337-
exc, arg = error, _notfound
338324
for dir in PATH:
339325
fullname = path.join(dir, file)
340326
try:
341327
apply(func, (fullname,) + argrest)
342328
except error, (errno, msg):
343-
if errno != arg[0]:
344-
exc, arg = error, (errno, msg)
345-
raise exc, arg
346-
329+
if errno != ENOENT and errno != ENOTDIR:
330+
raise
331+
raise error, (errno, msg)
347332

348333
# Change environ to automatically call putenv() if it exists
349334
try:

0 commit comments

Comments
 (0)