[scipy/el5] Add patch for CVE-2013-4251 (bug #1018353)
Orion Poplawski
orion at fedoraproject.org
Tue Oct 15 04:12:10 UTC 2013
commit 23b903f2a3bb42a21da7faf721509a554c584cc8
Author: Orion Poplawski <orion at nwra.com>
Date: Mon Oct 14 22:11:56 2013 -0600
Add patch for CVE-2013-4251 (bug #1018353)
scipy-CVE-2013-4251.patch | 294 +++++++++++++++++++++++++++++++++++++++++++++
scipy.spec | 13 ++-
2 files changed, 306 insertions(+), 1 deletions(-)
---
diff --git a/scipy-CVE-2013-4251.patch b/scipy-CVE-2013-4251.patch
new file mode 100644
index 0000000..f0e012b
--- /dev/null
+++ b/scipy-CVE-2013-4251.patch
@@ -0,0 +1,294 @@
+diff -up scipy-0.6.0/scipy/weave/catalog.py.CVE-2013-4251 scipy-0.6.0/scipy/weave/catalog.py
+--- scipy-0.6.0/scipy/weave/catalog.py.CVE-2013-4251 2007-09-22 01:56:36.000000000 -0600
++++ scipy-0.6.0/scipy/weave/catalog.py 2013-10-14 21:51:14.759104170 -0600
+@@ -32,6 +32,7 @@
+ """
+
+ import os,sys,string
++import stat
+ import pickle
+ import socket
+ import tempfile
+@@ -140,7 +141,7 @@ def is_writable(dir):
+
+ # Do NOT use a hardcoded name here due to the danger from race conditions
+ # on NFS when multiple processes are accessing the same base directory in
+- # parallel. We use both hostname and pocess id for the prefix in an
++ # parallel. We use both hostname and process id for the prefix in an
+ # attempt to ensure that there can really be no name collisions (tempfile
+ # appends 6 random chars to this prefix).
+ prefix = 'dummy_%s_%s_' % (socket.gethostname(),os.getpid())
+@@ -157,6 +158,88 @@ def whoami():
+ """return a string identifying the user."""
+ return os.environ.get("USER") or os.environ.get("USERNAME") or "unknown"
+
++
++def _create_dirs(path):
++ """ create provided path, ignore errors """
++ try:
++ os.makedirs(path, mode=0700)
++ except OSError:
++ pass
++
++
++def default_dir_posix(tmp_dir=None):
++ """
++ Create or find default catalog store for posix systems
++
++ purpose of 'tmp_dir' is to enable way how to test this function easily
++ """
++ path_candidates = []
++ python_name = "python%d%d_compiled" % tuple(sys.version_info[:2])
++
++ if tmp_dir:
++ home_dir = tmp_dir
++ else:
++ home_dir = os.path.expanduser('~')
++ tmp_dir = tmp_dir or tempfile.gettempdir()
++
++ home_temp_dir_name = '.' + python_name
++ home_temp_dir = os.path.join(home_dir, home_temp_dir_name)
++ path_candidates.append(home_temp_dir)
++
++ temp_dir_name = repr(os.getuid()) + '_' + python_name
++ temp_dir_path = os.path.join(tmp_dir, temp_dir_name)
++ path_candidates.append(temp_dir_path)
++
++ for path in path_candidates:
++ _create_dirs(path)
++ if check_dir(path):
++ return path
++
++ # since we got here, both dirs are not useful
++ tmp_dir_path = find_valid_temp_dir(temp_dir_name, tmp_dir)
++ if not tmp_dir_path:
++ tmp_dir_path = create_temp_dir(temp_dir_name, tmp_dir=tmp_dir)
++ return tmp_dir_path
++
++
++def default_dir_win(tmp_dir=None):
++ """
++ Create or find default catalog store for Windows systems
++
++ purpose of 'tmp_dir' is to enable way how to test this function easily
++ """
++ def create_win_temp_dir(prefix, inner_dir=None, tmp_dir=None):
++ """
++ create temp dir starting with 'prefix' in 'tmp_dir' or
++ 'tempfile.gettempdir'; if 'inner_dir' is specified, it should be
++ created inside
++ """
++ tmp_dir_path = find_valid_temp_dir(prefix, tmp_dir)
++ if tmp_dir_path:
++ if inner_dir:
++ tmp_dir_path = os.path.join(tmp_dir_path, inner_dir)
++ if not os.path.isdir(tmp_dir_path):
++ os.mkdir(tmp_dir_path, 0700)
++ else:
++ tmp_dir_path = create_temp_dir(prefix, inner_dir, tmp_dir)
++ return tmp_dir_path
++
++ python_name = "python%d%d_compiled" % tuple(sys.version_info[:2])
++ tmp_dir = tmp_dir or tempfile.gettempdir()
++
++ temp_dir_name = "%s" % whoami()
++ temp_root_dir = os.path.join(tmp_dir, temp_dir_name)
++ temp_dir_path = os.path.join(temp_root_dir, python_name)
++ _create_dirs(temp_dir_path)
++ if check_dir(temp_dir_path) and check_dir(temp_root_dir):
++ return temp_dir_path
++ else:
++ if check_dir(temp_root_dir):
++ return create_win_temp_dir(python_name, tmp_dir=temp_root_dir)
++ else:
++ return create_win_temp_dir(temp_dir_name, python_name, tmp_dir)
++
++
+ def default_dir():
+ """ Return a default location to store compiled files and catalogs.
+
+@@ -171,36 +254,19 @@ def default_dir():
+ in the user's home, /tmp/<uid>_pythonXX_compiled is used. If it
+ doesn't exist, it is created. The directory is marked rwx------
+ to try and keep people from being able to sneak a bad module
+- in on you.
++ in on you. If the directory already exists in /tmp/ and is not
++ secure, new one is created.
+
+ """
+-
+ # Use a cached value for fast return if possible
+- if hasattr(default_dir,"cached_path") and \
+- os.path.exists(default_dir.cached_path):
++ if hasattr(default_dir, "cached_path") and \
++ check_dir(default_dir.cached_path):
+ return default_dir.cached_path
+
+- python_name = "python%d%d_compiled" % tuple(sys.version_info[:2])
+- if sys.platform != 'win32':
+- try:
+- path = os.path.join(os.environ['HOME'],'.' + python_name)
+- except KeyError:
+- temp_dir = `os.getuid()` + '_' + python_name
+- path = os.path.join(tempfile.gettempdir(),temp_dir)
+-
+- # add a subdirectory for the OS.
+- # It might be better to do this at a different location so that
+- # it wasn't only the default directory that gets this behavior.
+- #path = os.path.join(path,sys.platform)
++ if sys.platform == 'win32':
++ path = default_dir_win()
+ else:
+- path = os.path.join(tempfile.gettempdir(),"%s"%whoami(),python_name)
+-
+- if not os.path.exists(path):
+- create_dir(path)
+- os.chmod(path,0700) # make it only accessible by this user.
+- if not is_writable(path):
+- print 'warning: default directory is not write accessible.'
+- print 'default:', path
++ path = default_dir_posix()
+
+ # Cache the default dir path so that this function returns quickly after
+ # being called once (nothing in it should change after the first call)
+@@ -208,15 +274,131 @@ def default_dir():
+
+ return path
+
+-def intermediate_dir():
+- """ Location in temp dir for storing .cpp and .o files during
+- builds.
+- """
+- python_name = "python%d%d_intermediate" % tuple(sys.version_info[:2])
+- path = os.path.join(tempfile.gettempdir(),"%s"%whoami(),python_name)
+- if not os.path.exists(path):
+- create_dir(path)
+- return path
++def check_dir(im_dir):
++ """
++ Check if dir is safe; if it is, return True.
++ These checks make sense only on posix:
++ * directory has correct owner
++ * directory has correct permissions (0700)
++ * directory is not a symlink
++ """
++ def check_is_dir():
++ return os.path.isdir(im_dir)
++
++ def check_permissions():
++ """ If on posix, permissions should be 0700. """
++ writable = is_writable(im_dir)
++ if sys.platform != 'win32':
++ try:
++ im_dir_stat = os.stat(im_dir)
++ except OSError:
++ return False
++ writable &= stat.S_IMODE(im_dir_stat.st_mode) == 00700
++ return writable
++
++ def check_ownership():
++ """ Intermediate dir owner should be same as owner of process. """
++ if sys.platform != 'win32':
++ try:
++ im_dir_stat = os.stat(im_dir)
++ except OSError:
++ return False
++ proc_uid = os.getuid()
++ return proc_uid == im_dir_stat.st_uid
++ return True
++
++ def check_is_symlink():
++ """ Check if intermediate dir is symlink. """
++ try:
++ return not os.path.islink(im_dir)
++ except OSError:
++ return False
++
++ checks = [check_is_dir, check_permissions,
++ check_ownership, check_is_symlink]
++
++ for check in checks:
++ if not check():
++ return False
++
++ return True
++
++
++def create_temp_dir(prefix, inner_dir=None, tmp_dir=None):
++ """
++ Create intermediate dirs <tmp>/<prefix+random suffix>/<inner_dir>/
++
++ argument 'tmp_dir' is used in unit tests
++ """
++ if not tmp_dir:
++ tmp_dir_path = tempfile.mkdtemp(prefix=prefix)
++ else:
++ tmp_dir_path = tempfile.mkdtemp(prefix=prefix, dir=tmp_dir)
++ if inner_dir:
++ tmp_dir_path = os.path.join(tmp_dir_path, inner_dir)
++ os.mkdir(tmp_dir_path, 0700)
++ return tmp_dir_path
++
++
++def intermediate_dir_prefix():
++ """ Prefix of root intermediate dir (<tmp>/<root_im_dir>). """
++ return "%s-%s-" % ("scipy", whoami())
++
++
++def find_temp_dir(prefix, tmp_dir=None):
++ """ Find temp dirs in 'tmp_dir' starting with 'prefix'"""
++ matches = []
++ tmp_dir = tmp_dir or tempfile.gettempdir()
++ for tmp_file in os.listdir(tmp_dir):
++ if tmp_file.startswith(prefix):
++ matches.append(os.path.join(tmp_dir, tmp_file))
++ return matches
++
++
++def find_valid_temp_dir(prefix, tmp_dir=None):
++ """
++ Try to look for existing temp dirs.
++ If there is one suitable found, return it, otherwise return None.
++ """
++ matches = find_temp_dir(prefix, tmp_dir)
++ for match in matches:
++ if check_dir(match):
++ # as soon as we find correct dir, we can stop searching
++ return match
++
++
++def py_intermediate_dir():
++ """
++ Name of intermediate dir for current python interpreter:
++ <temp dir>/<name>/pythonXY_intermediate/
++ """
++ name = "python%d%d_intermediate" % tuple(sys.version_info[:2])
++ return name
++
++
++def create_intermediate_dir(tmp_dir=None):
++ py_im_dir = py_intermediate_dir()
++ return create_temp_dir(intermediate_dir_prefix(), py_im_dir, tmp_dir)
++
++
++def intermediate_dir(tmp_dir=None):
++ """
++ Temporary directory for storing .cpp and .o files during builds.
++
++ First, try to find the dir and if it exists, verify it is safe.
++ Otherwise, create it.
++ """
++ im_dir = find_valid_temp_dir(intermediate_dir_prefix(), tmp_dir)
++ py_im_dir = py_intermediate_dir()
++ if im_dir is None:
++ py_im_dir = py_intermediate_dir()
++ im_dir = create_intermediate_dir(tmp_dir)
++ else:
++ im_dir = os.path.join(im_dir, py_im_dir)
++ if not os.path.isdir(im_dir):
++ os.mkdir(im_dir, 0700)
++ return im_dir
++
+
+ def default_temp_dir():
+ path = os.path.join(default_dir(),'temp')
diff --git a/scipy.spec b/scipy.spec
index 95a7106..59c21f6 100644
--- a/scipy.spec
+++ b/scipy.spec
@@ -3,12 +3,13 @@
Summary: Scipy: Scientific Tools for Python
Name: scipy
Version: 0.6.0
-Release: 6%{?dist}
+Release: 7%{?dist}
Group: Development/Libraries
License: BSD and LGPLv2+
Url: http://www.scipy.org
Source0: http://prdownloads.sourceforge.net/scipy/%{name}-%{version}.tar.gz
+Patch0: scipy-CVE-2013-4251.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -32,6 +33,7 @@ leading scientists and engineers.
%prep
%setup -q
+%patch0 -p1 -b .CVE-2013-4251
cat > site.cfg << EOF
[amd]
library_dirs = %{_libdir}
@@ -53,6 +55,12 @@ rm -rf $RPM_BUILD_ROOT
env CFLAGS="$RPM_OPT_FLAGS" ATLAS=%{_libdir} FFTW=%{_libdir} BLAS=%{_libdir} LAPACK=%{_libdir} python setup.py install --root=$RPM_BUILD_ROOT
+%check
+mkdir test
+cd test
+PYTHONPATH=$RPM_BUILD_ROOT%{python_sitearch} python -c "import scipy; scipy.test('full')"
+
+
%clean
rm -rf $RPM_BUILD_ROOT
@@ -65,6 +73,9 @@ rm -rf $RPM_BUILD_ROOT
%changelog
+* Mon Oct 14 2013 Orion Poplawski <orion at cora.nwra.com> -0.6.0-7
+- Add patch for CVE-2013-4251 (bug #1018353)
+
* Wed May 7 2008 Jef Spaleta <jspaleta at fedoraproject.org> - 0.6.0-6
- rebuild for EL-5
More information about the scm-commits
mailing list