shellutils: fix tempfile issue in Execute, and deprecate it

Addresses CVE-2014-1839.

authorJulien Cristau <julien.cristau@logilab.fr>
changeset2df08b0202e1
branchdefault
phasedraft
hiddenyes
parent revision#32d122da03fc Use 'env' to run the interpreter.
child revision<not specified>
files modified by this revision
ChangeLog
shellutils.py
# HG changeset patch
# User Julien Cristau <julien.cristau@logilab.fr>
# Date 1391422066 -3600
# Mon Feb 03 11:07:46 2014 +0100
# Node ID 2df08b0202e14b98a439225f65b3f70560c31020
# Parent 32d122da03fc5d536d0ed6aa5f73fd775a24c935
shellutils: fix tempfile issue in Execute, and deprecate it

Addresses CVE-2014-1839.

diff --git a/ChangeLog b/ChangeLog
@@ -1,9 +1,12 @@
1  ChangeLog for logilab.common
2  ============================
3 
4  --
5 +   * shellutils: fix tempfile issue in Execute, and deprecate it
6 +     (CVE-2014-1839)
7 +
8     * pytest: use 'env' to run the python interpreter
9 
10     * graph: ensure output is ordered on node and graph ids (#202314)
11 
12 
diff --git a/shellutils.py b/shellutils.py
@@ -29,15 +29,17 @@
13  import time
14  import fnmatch
15  import errno
16  import string
17  import random
18 +import subprocess
19  from os.path import exists, isdir, islink, basename, join
20 
21  from logilab.common import STD_BLACKLIST, _handle_blacklist
22  from logilab.common.compat import raw_input
23  from logilab.common.compat import str_to_bytes
24 +from logilab.common.deprecation import deprecated
25 
26  try:
27      from logilab.common.proc import ProcInfo, NoSuchProcess
28  except ImportError:
29      # windows platform
@@ -222,24 +224,21 @@
30          else:
31              outfile = open(join(destdir, name), 'wb')
32              outfile.write(zfobj.read(name))
33              outfile.close()
34 
35 +@deprecated('Use subprocess.Popen instead')
36  class Execute:
37      """This is a deadlock safe version of popen2 (no stdin), that returns
38      an object with errorlevel, out and err.
39      """
40 
41      def __init__(self, command):
42 -        outfile = tempfile.mktemp()
43 -        errfile = tempfile.mktemp()
44 -        self.status = os.system("( %s ) >%s 2>%s" %
45 -                                (command, outfile, errfile)) >> 8
46 -        self.out = open(outfile, "r").read()
47 -        self.err = open(errfile, "r").read()
48 -        os.remove(outfile)
49 -        os.remove(errfile)
50 +        cmd = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
51 +        self.out, self.err = cmd.communicate()
52 +        self.status = os.WEXITSTATUS(cmd.returncode)
53 +
54 
55  def acquire_lock(lock_file, max_try=10, delay=10, max_delay=3600):
56      """Acquire a lock represented by a file on the file system
57 
58      If the process written in lock file doesn't exist anymore, we remove the