churchyard / rpms / python2

Forked from rpms/python2 6 years ago
Clone
0dfe623
From add531a1e55b0a739b0f42582f1c9747e5649ace Mon Sep 17 00:00:00 2001
0dfe623
From: Benjamin Peterson <benjamin@python.org>
0dfe623
Date: Tue, 28 Aug 2018 22:12:56 -0700
0dfe623
Subject: [PATCH] closes bpo-34540: Convert shutil._call_external_zip to use
0dfe623
 subprocess rather than distutils.spawn.
0dfe623
0dfe623
---
0dfe623
 Lib/shutil.py                                    | 16 ++++++++++------
0dfe623
 .../2018-08-28-22-11-54.bpo-34540.gfQ0TM.rst     |  3 +++
0dfe623
 2 files changed, 13 insertions(+), 6 deletions(-)
0dfe623
 create mode 100644 Misc/NEWS.d/next/Security/2018-08-28-22-11-54.bpo-34540.gfQ0TM.rst
0dfe623
0dfe623
diff --git a/Lib/shutil.py b/Lib/shutil.py
0dfe623
index 3462f7c5e91c..0ab1a06f5260 100644
0dfe623
--- a/Lib/shutil.py
0dfe623
+++ b/Lib/shutil.py
0dfe623
@@ -413,17 +413,21 @@ def _set_uid_gid(tarinfo):
0dfe623
 
0dfe623
     return archive_name
0dfe623
 
0dfe623
-def _call_external_zip(base_dir, zip_filename, verbose=False, dry_run=False):
0dfe623
+def _call_external_zip(base_dir, zip_filename, verbose, dry_run, logger):
0dfe623
     # XXX see if we want to keep an external call here
0dfe623
     if verbose:
0dfe623
         zipoptions = "-r"
0dfe623
     else:
0dfe623
         zipoptions = "-rq"
0dfe623
-    from distutils.errors import DistutilsExecError
0dfe623
-    from distutils.spawn import spawn
0dfe623
+    cmd = ["zip", zipoptions, zip_filename, base_dir]
0dfe623
+    if logger is not None:
0dfe623
+        logger.info(' '.join(cmd))
0dfe623
+    if dry_run:
0dfe623
+        return
0dfe623
+    import subprocess
0dfe623
     try:
0dfe623
-        spawn(["zip", zipoptions, zip_filename, base_dir], dry_run=dry_run)
0dfe623
-    except DistutilsExecError:
0dfe623
+        subprocess.check_call(cmd)
0dfe623
+    except subprocess.CalledProcessError:
0dfe623
         # XXX really should distinguish between "couldn't find
0dfe623
         # external 'zip' command" and "zip failed".
0dfe623
         raise ExecError, \
0dfe623
@@ -458,7 +462,7 @@ def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None):
0dfe623
         zipfile = None
0dfe623
 
0dfe623
     if zipfile is None:
0dfe623
-        _call_external_zip(base_dir, zip_filename, verbose, dry_run)
0dfe623
+        _call_external_zip(base_dir, zip_filename, verbose, dry_run, logger)
0dfe623
     else:
0dfe623
         if logger is not None:
0dfe623
             logger.info("creating '%s' and adding '%s' to it",
0dfe623
diff --git a/Misc/NEWS.d/next/Security/2018-08-28-22-11-54.bpo-34540.gfQ0TM.rst b/Misc/NEWS.d/next/Security/2018-08-28-22-11-54.bpo-34540.gfQ0TM.rst
0dfe623
new file mode 100644
0dfe623
index 000000000000..4f686962a87b
0dfe623
--- /dev/null
0dfe623
+++ b/Misc/NEWS.d/next/Security/2018-08-28-22-11-54.bpo-34540.gfQ0TM.rst
0dfe623
@@ -0,0 +1,3 @@
0dfe623
+When ``shutil.make_archive`` falls back to the external ``zip`` problem, it
0dfe623
+uses :mod:`subprocess` to invoke it rather than :mod:`distutils.spawn`. This
0dfe623
+closes a possible shell injection vector.