0da69615f6
Zack Weinberg found a vulnerability in the way the exevpe() method from the os.py module uses a temporary file name. A file which supposedly should not exist is created in a unsafe way and the method tries to execute it. The objective of such code is to discover what error the operating system returns in a portable way. By exploiting this vulnerability a local attacker can execute arbitrary code with the privileges of the user running python code which uses the execvpe() method. http://python.org/sf/590294 http://python.org/sf/601077
80 lines
2.6 KiB
Plaintext
80 lines
2.6 KiB
Plaintext
$OpenBSD: patch-Lib_os_py,v 1.1 2002/10/08 02:52:25 brad Exp $
|
|
--- Lib/os.py.orig Mon Oct 7 22:16:49 2002
|
|
+++ Lib/os.py Mon Oct 7 22:16:51 2002
|
|
@@ -298,7 +298,7 @@ def execvp(file, args):
|
|
_execvpe(file, args)
|
|
|
|
def execvpe(file, args, env):
|
|
- """execv(file, args, env)
|
|
+ """execvpe(file, args, env)
|
|
|
|
Execute the executable file (which is searched for along $PATH)
|
|
with argument list args and environment env , replacing the
|
|
@@ -308,8 +308,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)
|
|
@@ -317,7 +318,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)
|
|
@@ -327,30 +328,21 @@ 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
|
|
+ saved_exc = None
|
|
+ saved_tb = None
|
|
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
|
|
-
|
|
+ except error, e:
|
|
+ tb = sys.exc_info()[2]
|
|
+ if (e.errno != ENOENT and e.errno != ENOTDIR
|
|
+ and saved_exc is None):
|
|
+ saved_exc = e
|
|
+ saved_tb = tb
|
|
+ if saved_exc:
|
|
+ raise error, saved_exc, saved_tb
|
|
+ raise error, e, tb
|
|
|
|
# Change environ to automatically call putenv() if it exists
|
|
try:
|
|
@@ -618,3 +610,4 @@ try:
|
|
_make_statvfs_result)
|
|
except NameError: # statvfs_result may not exist
|
|
pass
|
|
+
|