summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2015-01-26 14:33:32 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2015-01-26 14:33:32 +0000
commit30121953b1aea9493256d7b68f3164024ea7a9ff (patch)
treebe7fe21c31b7835eb63eb43952c6e722a118d97d
parentd67572957158d22d3e219a3ad5e4882eacebfdbe (diff)
downloadaports-30121953b1aea9493256d7b68f3164024ea7a9ff.tar.bz2
aports-30121953b1aea9493256d7b68f3164024ea7a9ff.tar.xz
main/py-pip: fix for CVE-2014-8991
fixes #3700
-rw-r--r--main/py-pip/APKBUILD15
-rw-r--r--main/py-pip/CVE-2014-8991.patch387
2 files changed, 397 insertions, 5 deletions
diff --git a/main/py-pip/APKBUILD b/main/py-pip/APKBUILD
index bd2aa1d50..96e6bef38 100644
--- a/main/py-pip/APKBUILD
+++ b/main/py-pip/APKBUILD
@@ -3,7 +3,7 @@
pkgname=py-pip
_pkgname=pip
pkgver=1.5.6
-pkgrel=1
+pkgrel=2
pkgdesc="A tool for installing and managing Python packages"
url="http://www.pip-installer.org"
arch="noarch"
@@ -13,7 +13,9 @@ depends_dev=""
makedepends="python-dev py-setuptools"
install=""
subpackages=""
-source="http://pypi.python.org/packages/source/${_pkgname:0:1}/$_pkgname/$_pkgname-$pkgver.tar.gz"
+source="http://pypi.python.org/packages/source/${_pkgname:0:1}/$_pkgname/$_pkgname-$pkgver.tar.gz
+ CVE-2014-8991.patch
+ "
_builddir="$srcdir"/$_pkgname-$pkgver
prepare() {
@@ -36,6 +38,9 @@ package() {
python setup.py install --prefix=/usr --root="$pkgdir" || return 1
}
-md5sums="01026f87978932060cc86c1dc527903e pip-1.5.6.tar.gz"
-sha256sums="b1a4ae66baf21b7eb05a5e4f37c50c2706fa28ea1f8780ce8efe14dcd9f1726c pip-1.5.6.tar.gz"
-sha512sums="cecd1da900e95bf3e6164e6d0c8c989e8ce17ef892beb9581a567857fe69dd3490b45d366cbb8e3bc84cebcf62ecf34420bcc1fae3fd8cf448927438ae257b68 pip-1.5.6.tar.gz"
+md5sums="01026f87978932060cc86c1dc527903e pip-1.5.6.tar.gz
+f42c20d82c616f4fa39281bb44b59bf0 CVE-2014-8991.patch"
+sha256sums="b1a4ae66baf21b7eb05a5e4f37c50c2706fa28ea1f8780ce8efe14dcd9f1726c pip-1.5.6.tar.gz
+ce935d1cf46891259d7eb540706daf367d358f07b049c9a5ec6f96eaa8a61068 CVE-2014-8991.patch"
+sha512sums="cecd1da900e95bf3e6164e6d0c8c989e8ce17ef892beb9581a567857fe69dd3490b45d366cbb8e3bc84cebcf62ecf34420bcc1fae3fd8cf448927438ae257b68 pip-1.5.6.tar.gz
+618c86fdee6e5ffb4a94643bd39fefc83aa15b4dfbbe06aefd5d5ec51efce30bc93463a27efb5b5d73f4473f0918ec7aa3a64f7b1b4939a79b0b1b4dec611aba CVE-2014-8991.patch"
diff --git a/main/py-pip/CVE-2014-8991.patch b/main/py-pip/CVE-2014-8991.patch
new file mode 100644
index 000000000..6f5f6137b
--- /dev/null
+++ b/main/py-pip/CVE-2014-8991.patch
@@ -0,0 +1,387 @@
+diff --git a/pip/cmdoptions.py b/pip/cmdoptions.py
+index 8ed3d91..01b2104 100644
+--- a/pip/cmdoptions.py
++++ b/pip/cmdoptions.py
+@@ -9,7 +9,7 @@ To be consistent, all options will follow this design.
+ """
+ import copy
+ from optparse import OptionGroup, SUPPRESS_HELP, Option
+-from pip.locations import build_prefix, default_log_file
++from pip.locations import default_log_file
+
+
+ def make_option_group(group, parser):
+@@ -297,10 +297,8 @@ build_dir = OptionMaker(
+ '-b', '--build', '--build-dir', '--build-directory',
+ dest='build_dir',
+ metavar='dir',
+- default=build_prefix,
+- help='Directory to unpack packages into and build in. '
+- 'The default in a virtualenv is "<venv path>/build". '
+- 'The default for global installs is "<OS temp dir>/pip_build_<username>".')
++ help='Directory to unpack packages into and build in.',
++)
+
+ install_options = OptionMaker(
+ '--install-option',
+diff --git a/pip/commands/install.py b/pip/commands/install.py
+index cbf22a0..cb7d0db 100644
+--- a/pip/commands/install.py
++++ b/pip/commands/install.py
+@@ -10,6 +10,7 @@ from pip.basecommand import Command
+ from pip.index import PackageFinder
+ from pip.exceptions import InstallationError, CommandError, PreviousBuildDirError
+ from pip import cmdoptions
++from pip.util import BuildDirectory
+
+
+ class InstallCommand(Command):
+@@ -188,7 +189,7 @@ class InstallCommand(Command):
+ if (
+ options.no_install or
+ options.no_download or
+- (options.build_dir != build_prefix) or
++ options.build_dir or
+ options.no_clean
+ ):
+ logger.deprecated('1.7', 'DEPRECATION: --no-install, --no-download, --build, '
+@@ -197,7 +198,16 @@ class InstallCommand(Command):
+ if options.download_dir:
+ options.no_install = True
+ options.ignore_installed = True
+- options.build_dir = os.path.abspath(options.build_dir)
++
++ # If we have --no-install or --no-download and no --build we use the
++ # legacy static build dir
++ if (options.build_dir is None
++ and (options.no_install or options.no_download)):
++ options.build_dir = build_prefix
++
++ if options.build_dir:
++ options.build_dir = os.path.abspath(options.build_dir)
++
+ options.src_dir = os.path.abspath(options.src_dir)
+ install_options = options.install_options or []
+ if options.use_user_site:
+@@ -237,69 +247,71 @@ class InstallCommand(Command):
+
+ finder = self._build_package_finder(options, index_urls, session)
+
+- requirement_set = RequirementSet(
+- build_dir=options.build_dir,
+- src_dir=options.src_dir,
+- download_dir=options.download_dir,
+- download_cache=options.download_cache,
+- upgrade=options.upgrade,
+- as_egg=options.as_egg,
+- ignore_installed=options.ignore_installed,
+- ignore_dependencies=options.ignore_dependencies,
+- force_reinstall=options.force_reinstall,
+- use_user_site=options.use_user_site,
+- target_dir=temp_target_dir,
+- session=session,
+- pycompile=options.compile,
+- )
+- for name in args:
+- requirement_set.add_requirement(
+- InstallRequirement.from_line(name, None))
+- for name in options.editables:
+- requirement_set.add_requirement(
+- InstallRequirement.from_editable(name, default_vcs=options.default_vcs))
+- for filename in options.requirements:
+- for req in parse_requirements(filename, finder=finder, options=options, session=session):
+- requirement_set.add_requirement(req)
+- if not requirement_set.has_requirements:
+- opts = {'name': self.name}
+- if options.find_links:
+- msg = ('You must give at least one requirement to %(name)s '
+- '(maybe you meant "pip %(name)s %(links)s"?)' %
+- dict(opts, links=' '.join(options.find_links)))
+- else:
+- msg = ('You must give at least one requirement '
+- 'to %(name)s (see "pip help %(name)s")' % opts)
+- logger.warn(msg)
+- return
+-
+- try:
+- if not options.no_download:
+- requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
+- else:
+- requirement_set.locate_files()
+-
+- if not options.no_install and not self.bundle:
+- requirement_set.install(install_options, global_options, root=options.root_path)
+- installed = ' '.join([req.name for req in
+- requirement_set.successfully_installed])
+- if installed:
+- logger.notify('Successfully installed %s' % installed)
+- elif not self.bundle:
+- downloaded = ' '.join([req.name for req in
+- requirement_set.successfully_downloaded])
+- if downloaded:
+- logger.notify('Successfully downloaded %s' % downloaded)
+- elif self.bundle:
+- requirement_set.create_bundle(self.bundle_filename)
+- logger.notify('Created bundle in %s' % self.bundle_filename)
+- except PreviousBuildDirError:
+- options.no_clean = True
+- raise
+- finally:
+- # Clean up
+- if (not options.no_clean) and ((not options.no_install) or options.download_dir):
+- requirement_set.cleanup_files(bundle=self.bundle)
++ build_delete = (not (options.no_clean or options.build_dir))
++ with BuildDirectory(options.build_dir, delete=build_delete) as build_dir:
++ requirement_set = RequirementSet(
++ build_dir=build_dir,
++ src_dir=options.src_dir,
++ download_dir=options.download_dir,
++ download_cache=options.download_cache,
++ upgrade=options.upgrade,
++ as_egg=options.as_egg,
++ ignore_installed=options.ignore_installed,
++ ignore_dependencies=options.ignore_dependencies,
++ force_reinstall=options.force_reinstall,
++ use_user_site=options.use_user_site,
++ target_dir=temp_target_dir,
++ session=session,
++ pycompile=options.compile,
++ )
++ for name in args:
++ requirement_set.add_requirement(
++ InstallRequirement.from_line(name, None))
++ for name in options.editables:
++ requirement_set.add_requirement(
++ InstallRequirement.from_editable(name, default_vcs=options.default_vcs))
++ for filename in options.requirements:
++ for req in parse_requirements(filename, finder=finder, options=options, session=session):
++ requirement_set.add_requirement(req)
++ if not requirement_set.has_requirements:
++ opts = {'name': self.name}
++ if options.find_links:
++ msg = ('You must give at least one requirement to %(name)s '
++ '(maybe you meant "pip %(name)s %(links)s"?)' %
++ dict(opts, links=' '.join(options.find_links)))
++ else:
++ msg = ('You must give at least one requirement '
++ 'to %(name)s (see "pip help %(name)s")' % opts)
++ logger.warn(msg)
++ return
++
++ try:
++ if not options.no_download:
++ requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
++ else:
++ requirement_set.locate_files()
++
++ if not options.no_install and not self.bundle:
++ requirement_set.install(install_options, global_options, root=options.root_path)
++ installed = ' '.join([req.name for req in
++ requirement_set.successfully_installed])
++ if installed:
++ logger.notify('Successfully installed %s' % installed)
++ elif not self.bundle:
++ downloaded = ' '.join([req.name for req in
++ requirement_set.successfully_downloaded])
++ if downloaded:
++ logger.notify('Successfully downloaded %s' % downloaded)
++ elif self.bundle:
++ requirement_set.create_bundle(self.bundle_filename)
++ logger.notify('Created bundle in %s' % self.bundle_filename)
++ except PreviousBuildDirError:
++ options.no_clean = True
++ raise
++ finally:
++ # Clean up
++ if (not options.no_clean) and ((not options.no_install) or options.download_dir):
++ requirement_set.cleanup_files(bundle=self.bundle)
+
+ if options.target_dir:
+ if not os.path.exists(options.target_dir):
+diff --git a/pip/commands/wheel.py b/pip/commands/wheel.py
+index 6527063..a96631a 100644
+--- a/pip/commands/wheel.py
++++ b/pip/commands/wheel.py
+@@ -8,7 +8,7 @@ from pip.index import PackageFinder
+ from pip.log import logger
+ from pip.exceptions import CommandError, PreviousBuildDirError
+ from pip.req import InstallRequirement, RequirementSet, parse_requirements
+-from pip.util import normalize_path
++from pip.util import BuildDirectory, normalize_path
+ from pip.wheel import WheelBuilder
+ from pip import cmdoptions
+
+@@ -123,6 +123,9 @@ class WheelCommand(Command):
+ "--extra-index-url is suggested.")
+ index_urls += options.mirrors
+
++ if options.build_dir:
++ options.build_dir = os.path.abspath(options.build_dir)
++
+ session = self._build_session(options)
+
+ finder = PackageFinder(find_links=options.find_links,
+@@ -137,59 +140,60 @@ class WheelCommand(Command):
+ session=session,
+ )
+
+- options.build_dir = os.path.abspath(options.build_dir)
+- requirement_set = RequirementSet(
+- build_dir=options.build_dir,
+- src_dir=None,
+- download_dir=None,
+- download_cache=options.download_cache,
+- ignore_dependencies=options.ignore_dependencies,
+- ignore_installed=True,
+- session=session,
+- wheel_download_dir=options.wheel_dir
+- )
+-
+- # make the wheelhouse
+- if not os.path.exists(options.wheel_dir):
+- os.makedirs(options.wheel_dir)
+-
+- #parse args and/or requirements files
+- for name in args:
+- requirement_set.add_requirement(
+- InstallRequirement.from_line(name, None))
+-
+- for filename in options.requirements:
+- for req in parse_requirements(
+- filename,
+- finder=finder,
+- options=options,
+- session=session):
+- if req.editable:
+- logger.notify("ignoring %s" % req.url)
+- continue
+- requirement_set.add_requirement(req)
+-
+- #fail if no requirements
+- if not requirement_set.has_requirements:
+- opts = {'name': self.name}
+- msg = ('You must give at least one requirement '
+- 'to %(name)s (see "pip help %(name)s")' % opts)
+- logger.error(msg)
+- return
++ build_delete = (not (options.no_clean or options.build_dir))
++ with BuildDirectory(options.build_dir, delete=build_delete) as build_dir:
++ requirement_set = RequirementSet(
++ build_dir=build_dir,
++ src_dir=None,
++ download_dir=None,
++ download_cache=options.download_cache,
++ ignore_dependencies=options.ignore_dependencies,
++ ignore_installed=True,
++ session=session,
++ wheel_download_dir=options.wheel_dir
++ )
+
+- try:
+- #build wheels
+- wb = WheelBuilder(
+- requirement_set,
+- finder,
+- options.wheel_dir,
+- build_options = options.build_options or [],
+- global_options = options.global_options or []
+- )
+- wb.build()
+- except PreviousBuildDirError:
+- options.no_clean = True
+- raise
+- finally:
+- if not options.no_clean:
+- requirement_set.cleanup_files()
++ # make the wheelhouse
++ if not os.path.exists(options.wheel_dir):
++ os.makedirs(options.wheel_dir)
++
++ #parse args and/or requirements files
++ for name in args:
++ requirement_set.add_requirement(
++ InstallRequirement.from_line(name, None))
++
++ for filename in options.requirements:
++ for req in parse_requirements(
++ filename,
++ finder=finder,
++ options=options,
++ session=session):
++ if req.editable:
++ logger.notify("ignoring %s" % req.url)
++ continue
++ requirement_set.add_requirement(req)
++
++ #fail if no requirements
++ if not requirement_set.has_requirements:
++ opts = {'name': self.name}
++ msg = ('You must give at least one requirement '
++ 'to %(name)s (see "pip help %(name)s")' % opts)
++ logger.error(msg)
++ return
++
++ try:
++ #build wheels
++ wb = WheelBuilder(
++ requirement_set,
++ finder,
++ options.wheel_dir,
++ build_options = options.build_options or [],
++ global_options = options.global_options or []
++ )
++ wb.build()
++ except PreviousBuildDirError:
++ options.no_clean = True
++ raise
++ finally:
++ if not options.no_clean:
++ requirement_set.cleanup_files()
+diff --git a/pip/util.py b/pip/util.py
+index f459bb2..f5edeeb 100644
+--- a/pip/util.py
++++ b/pip/util.py
+@@ -8,6 +8,7 @@ import zipfile
+ import tarfile
+ import subprocess
+ import textwrap
++import tempfile
+
+ from pip.exceptions import InstallationError, BadCommand, PipError
+ from pip.backwardcompat import(WindowsError, string_types, raw_input,
+@@ -718,3 +719,35 @@ def is_prerelease(vers):
+
+ parsed = version._normalized_key(normalized)
+ return any([any([y in set(["a", "b", "c", "rc", "dev"]) for y in x]) for x in parsed])
++
++
++class BuildDirectory(object):
++
++ def __init__(self, name=None, delete=None):
++ # If we were not given an explicit directory, and we were not given an
++ # explicit delete option, then we'll default to deleting.
++ if name is None and delete is None:
++ delete = True
++
++ if name is None:
++ name = tempfile.mkdtemp(prefix="pip-build-")
++ # If we were not given an explicit directory, and we were not given
++ # an explicit delete option, then we'll default to deleting.
++ if delete is None:
++ delete = True
++
++ self.name = name
++ self.delete = delete
++
++ def __repr__(self):
++ return "<{} {!r}>".format(self.__class__.__name__, self.name)
++
++ def __enter__(self):
++ return self.name
++
++ def __exit__(self, exc, value, tb):
++ self.cleanup()
++
++ def cleanup(self):
++ if self.delete:
++ rmtree(self.name)