diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2015-01-26 14:33:32 +0000 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2015-01-26 14:33:32 +0000 |
commit | 30121953b1aea9493256d7b68f3164024ea7a9ff (patch) | |
tree | be7fe21c31b7835eb63eb43952c6e722a118d97d | |
parent | d67572957158d22d3e219a3ad5e4882eacebfdbe (diff) | |
download | aports-30121953b1aea9493256d7b68f3164024ea7a9ff.tar.bz2 aports-30121953b1aea9493256d7b68f3164024ea7a9ff.tar.xz |
main/py-pip: fix for CVE-2014-8991
fixes #3700
-rw-r--r-- | main/py-pip/APKBUILD | 15 | ||||
-rw-r--r-- | main/py-pip/CVE-2014-8991.patch | 387 |
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) |