mirror of
https://github.com/python/cpython.git
synced 2025-12-04 16:43:27 +00:00
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.)
This commit is contained in:
parent
aaebdd6a02
commit
aed51d8121
1 changed files with 6 additions and 21 deletions
27
Lib/os.py
27
Lib/os.py
|
|
@ -319,8 +319,9 @@ def execvpe(file, args, env):
|
||||||
|
|
||||||
__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
|
__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
|
||||||
|
|
||||||
_notfound = None
|
|
||||||
def _execvpe(file, args, env=None):
|
def _execvpe(file, args, env=None):
|
||||||
|
from errno import ENOENT, ENOTDIR
|
||||||
|
|
||||||
if env is not None:
|
if env is not None:
|
||||||
func = execve
|
func = execve
|
||||||
argrest = (args, env)
|
argrest = (args, env)
|
||||||
|
|
@ -328,7 +329,7 @@ def _execvpe(file, args, env=None):
|
||||||
func = execv
|
func = execv
|
||||||
argrest = (args,)
|
argrest = (args,)
|
||||||
env = environ
|
env = environ
|
||||||
global _notfound
|
|
||||||
head, tail = path.split(file)
|
head, tail = path.split(file)
|
||||||
if head:
|
if head:
|
||||||
apply(func, (file,) + argrest)
|
apply(func, (file,) + argrest)
|
||||||
|
|
@ -338,30 +339,14 @@ def _execvpe(file, args, env=None):
|
||||||
else:
|
else:
|
||||||
envpath = defpath
|
envpath = defpath
|
||||||
PATH = envpath.split(pathsep)
|
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:
|
for dir in PATH:
|
||||||
fullname = path.join(dir, file)
|
fullname = path.join(dir, file)
|
||||||
try:
|
try:
|
||||||
apply(func, (fullname,) + argrest)
|
apply(func, (fullname,) + argrest)
|
||||||
except error, (errno, msg):
|
except error, (errno, msg):
|
||||||
if errno != arg[0]:
|
if errno != ENOENT and errno != ENOTDIR:
|
||||||
exc, arg = error, (errno, msg)
|
raise
|
||||||
raise exc, arg
|
raise error, (errno, msg)
|
||||||
|
|
||||||
|
|
||||||
# Change environ to automatically call putenv() if it exists
|
# Change environ to automatically call putenv() if it exists
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue