From 4d4181e97c8eb35dbb021f4d6a8daca122aa52c3 Mon Sep 17 00:00:00 2001 From: James Le Cuirot Date: Thu, 31 Aug 2017 22:15:12 +0100 Subject: dev-java/jython: Patch against CVE-2016-4000 (bug #621876) Also unpeg the dev-java/asm version as 5.1 works fine. 5.0.3 was the latest when that restriction was put in place so a newer version could not have been breaking it. Package-Manager: Portage-2.3.8, Repoman-2.3.2 --- dev-java/jython/files/CVE-2016-4000.patch | 158 ++++++++++++++++++++++++++++++ dev-java/jython/jython-2.7.0-r1.ebuild | 150 ---------------------------- dev-java/jython/jython-2.7.0-r2.ebuild | 151 ++++++++++++++++++++++++++++ 3 files changed, 309 insertions(+), 150 deletions(-) create mode 100644 dev-java/jython/files/CVE-2016-4000.patch delete mode 100644 dev-java/jython/jython-2.7.0-r1.ebuild create mode 100644 dev-java/jython/jython-2.7.0-r2.ebuild (limited to 'dev-java/jython') diff --git a/dev-java/jython/files/CVE-2016-4000.patch b/dev-java/jython/files/CVE-2016-4000.patch new file mode 100644 index 000000000000..81785eb05b07 --- /dev/null +++ b/dev-java/jython/files/CVE-2016-4000.patch @@ -0,0 +1,158 @@ + +# HG changeset patch +# User Jim Baker +# Date 1454384221 25200 +# Node ID d06e29d100c04576735e86c75a26c5f33669bb72 +# Parent b6735606c13df95f770527e629954407f82808c5 +Do not deserialize PyFunction objects. Fixes #2454 + +Instead use standard Python pickling; or subclass PyFunction. + +diff --git a/Lib/test/test_java_integration.py b/Lib/test/test_java_integration.py +--- a/Lib/test/test_java_integration.py ++++ b/Lib/test/test_java_integration.py +@@ -14,8 +14,9 @@ import re + from collections import deque + from test import test_support + +-from java.lang import (ClassCastException, ExceptionInInitializerError, String, Runnable, System, +- Runtime, Math, Byte) ++from java.lang import ( ++ ClassCastException, ExceptionInInitializerError, UnsupportedOperationException, ++ String, Runnable, System, Runtime, Math, Byte) + from java.math import BigDecimal, BigInteger + from java.net import URI + from java.io import (ByteArrayInputStream, ByteArrayOutputStream, File, FileInputStream, +@@ -656,13 +657,30 @@ class SerializationTest(unittest.TestCas + self.assertEqual(date_list, roundtrip_serialization(date_list)) + + def test_java_serialization_pycode(self): +- + def universal_answer(): + return 42 + + serialized_code = roundtrip_serialization(universal_answer.func_code) + self.assertEqual(eval(serialized_code), universal_answer()) + ++ def test_java_serialization_pyfunction(self): ++ # Not directly supported due to lack of general utility ++ # (globals will usually be in the function object in ++ # func_globals), and problems with unserialization ++ # vulnerabilities. Users can always subclass from PyFunction ++ # for specific cases, as seen in PyCascading ++ import new ++ def f(): ++ return 6 * 7 + max(0, 1, 2) ++ # However, using the new module, it's possible to create a ++ # function with no globals, which means the globals will come ++ # from the current context ++ g = new.function(f.func_code, {}, "g") ++ # But still forbid Java deserialization of this function ++ # object. Use pickling or other support instead. ++ with self.assertRaises(UnsupportedOperationException): ++ roundtrip_serialization(g) ++ + def test_builtin_names(self): + import __builtin__ + names = [x for x in dir(__builtin__)] +@@ -872,7 +890,7 @@ class SingleMethodInterfaceTest(unittest + future.get() + self.assertEqual(x, [42]) + +- @unittest.skip("FIXME: not working") ++ @unittest.skip("FIXME: not working; see http://bugs.jython.org/issue2115") + def test_callable_object(self): + callable_obj = CallableObject() + future = self.executor.submit(callable_obj) +diff --git a/Lib/test/test_new.py b/Lib/test/test_new.py +--- a/Lib/test/test_new.py ++++ b/Lib/test/test_new.py +@@ -24,18 +24,10 @@ class NewTest(unittest.TestCase): + c = new.instance(C, {'yolks': 3}) + + o = new.instance(C) +- +- # __dict__ is a non dict mapping in Jython +- if test_support.is_jython: +- self.assertEqual(len(o.__dict__), 0, "new __dict__ should be empty") +- else: +- self.assertEqual(o.__dict__, {}, "new __dict__ should be empty") ++ self.assertEqual(o.__dict__, {}, "new __dict__ should be empty") + del o + o = new.instance(C, None) +- if test_support.is_jython: +- self.assertEqual(len(o.__dict__), 0, "new __dict__ should be empty") +- else: +- self.assertEqual(o.__dict__, {}, "new __dict__ should be empty") ++ self.assertEqual(o.__dict__, {}, "new __dict__ should be empty") + del o + + def break_yolks(self): +@@ -109,7 +101,14 @@ class NewTest(unittest.TestCase): + test_closure(g, (1, 1), ValueError) # closure is wrong size + test_closure(f, g.func_closure, ValueError) # no closure needed + +- if hasattr(new, 'code') and not test_support.is_jython: ++ # [Obsolete] Note: Jython will never have new.code() ++ # ++ # Who said that?!!! guess what, we do! :) ++ # ++ # Unfortunately we still need a way to compile to Python bytecode, ++ # so support is still incomplete, as seen in the fact that we need ++ # to get values from CPython 2.7. ++ if hasattr(new, 'code'): + def test_code(self): + # bogus test of new.code() + def f(a): pass +@@ -117,16 +116,16 @@ class NewTest(unittest.TestCase): + c = f.func_code + argcount = c.co_argcount + nlocals = c.co_nlocals +- stacksize = c.co_stacksize ++ stacksize = 1 # TODO c.co_stacksize + flags = c.co_flags +- codestring = c.co_code +- constants = c.co_consts +- names = c.co_names ++ codestring = 'd\x00\x00S' # TODO c.co_code ++ constants = (None,) # TODO c.co_consts ++ names = () # TODO c.co_names + varnames = c.co_varnames + filename = c.co_filename + name = c.co_name + firstlineno = c.co_firstlineno +- lnotab = c.co_lnotab ++ lnotab = '' # TODO c.co_lnotab, but also see http://bugs.jython.org/issue1638 + freevars = c.co_freevars + cellvars = c.co_cellvars + +diff --git a/src/org/python/core/PyBytecode.java b/src/org/python/core/PyBytecode.java +--- a/src/org/python/core/PyBytecode.java ++++ b/src/org/python/core/PyBytecode.java +@@ -66,6 +66,12 @@ public class PyBytecode extends PyBaseCo + + debug = defaultDebug; + ++ if (argcount < 0) { ++ throw Py.ValueError("code: argcount must not be negative"); ++ } else if (nlocals < 0) { ++ throw Py.ValueError("code: nlocals must not be negative"); ++ } ++ + co_argcount = nargs = argcount; + co_varnames = varnames; + co_nlocals = nlocals; // maybe assert = varnames.length; +diff --git a/src/org/python/core/PyFunction.java b/src/org/python/core/PyFunction.java +--- a/src/org/python/core/PyFunction.java ++++ b/src/org/python/core/PyFunction.java +@@ -545,6 +545,9 @@ public class PyFunction extends PyObject + @Override + public boolean isSequenceType() { return false; } + ++ private Object readResolve() { ++ throw new UnsupportedOperationException(); ++ } + + /* Traverseproc implementation */ + @Override + diff --git a/dev-java/jython/jython-2.7.0-r1.ebuild b/dev-java/jython/jython-2.7.0-r1.ebuild deleted file mode 100644 index d0870d8b4ac0..000000000000 --- a/dev-java/jython/jython-2.7.0-r1.ebuild +++ /dev/null @@ -1,150 +0,0 @@ -# Copyright 1999-2017 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 - -EAPI=6 -JAVA_PKG_IUSE="doc source" - -inherit eutils java-pkg-2 java-ant-2 python-utils-r1 flag-o-matic - -MY_PV=${PV/_beta/-b} -MY_P=${PN}-${MY_PV} - -DESCRIPTION="An implementation of Python written in Java" -HOMEPAGE="http://www.jython.org" -SRC_URI="http://search.maven.org/remotecontent?filepath=org/python/${PN}/${MY_PV}/${MY_P}-sources.jar" - -LICENSE="PSF-2" -SLOT="2.7" -KEYWORDS="~amd64 ~x86 ~amd64-linux ~x86-linux ~x86-macos" -IUSE="examples test" - -CP_DEPEND="dev-java/antlr:3 - dev-java/netty-transport:0 - =dev-java/asm-5.0.3:4 - dev-java/commons-compress:0 - dev-java/guava:20 - dev-java/jffi:1.2 - dev-java/jline:2 - dev-java/icu4j:52 - dev-java/jnr-constants:0 - dev-java/jnr-posix:3.0 - dev-java/jnr-netdb:1.0 - dev-java/stringtemplate:0 - dev-java/xerces:2 - java-virtuals/script-api:0 - java-virtuals/servlet-api:3.0" -RDEPEND="${CP_DEPEND} - >=virtual/jre-1.7" -DEPEND="${CP_DEPEND} - >=virtual/jdk-1.7 - app-arch/unzip - dev-java/ant-core:0 - test? ( - dev-java/junit:4 - dev-java/ant-junit:0 - )" - -S=${WORKDIR} - -RESTRICT="test" - -JAVA_ANT_REWRITE_CLASSPATH="yes" -JAVA_ANT_CLASSPATH_TAGS+=" java" - -EANT_BUILD_TARGET="developer-build" -EANT_TEST_EXTRA_ARGS="-Dpython.home=dist" - -# jdbc-informix and jdbc-oracle-bin (requires registration) aren't exposed. -# Uncomment and add to CDEPEND if you want either of them -#EANT_GENTOO_CLASSPATH+=",jdbc-informix" EANT_EXTRA_ARGS+=" -Dinformix.present" -#EANT_GENTOO_CLASSPATH+=",jdbc-oracle-bin" EANT_EXTRA_ARGS+=" -Doracle.present" - -PATCHES=( - "${FILESDIR}"/${PN}-2.5.2-distutils_scripts_location.patch - "${FILESDIR}"/${PN}-2.5.2-respect_PYTHONPATH.patch - "${FILESDIR}"/${PN}-2.7_beta1-ant.patch - "${FILESDIR}"/${PN}-2.7_beta1-dont-always-recompile-classes.patch - "${FILESDIR}"/${PN}-2.7_beta2-maxrepeat-import.patch - "${FILESDIR}"/${PN}-2.7.0-build.xml.patch -) - -src_prepare() { - default - - find \( -name '*.jar' -o -name '*.class' \ - -o -name '*.pyc' -o -name '*.exe' \) -delete - - # needed for launchertest - chmod +x tests/shell/test-jython.sh || die - - java-pkg-2_src_prepare -} - -src_configure() { - # apparently this can cause problems - append-flags -fno-stack-protector - - EANT_GENTOO_CLASSPATH_EXTRA="$(java-pkg_getjars --with-dependencies antlr-3,jnr-posix-3.0)" - EANT_GENTOO_CLASSPATH_EXTRA+=":$(java-pkg_getjars --build-only ant-core)" -} - -src_test() { - java-pkg-2_src_test -} - -src_install() { - local instdir=/usr/share/${PN}-${SLOT} - - java-pkg_newjar dist/${PN}-dev.jar - - java-pkg_register-optional-dependency jdbc-mysql - java-pkg_register-optional-dependency jdbc-postgresql - - insinto ${instdir} - doins -r dist/{Lib,registry} - - dodoc ACKNOWLEDGMENTS NEWS README.txt - - use doc && java-pkg_dohtml -r dist/Doc/javadoc - use source && java-pkg_dosrc src/* - use examples && java-pkg_doexamples Demo/* - - local java_args=( - -Dpython.home="${EPREFIX}"/usr/share/${PN}-${SLOT} - -Dpython.executable="${EPREFIX}"/usr/bin/jython${SLOT} - -Dpython.cachedir="\${HOME}/.jythoncachedir" - ) - - java-pkg_dolauncher jython${SLOT} \ - --main org.python.util.jython \ - --java_args "${java_args[*]}" - - # we need a wrapper to help python_optimize - cat <<-EOF > "${T}"/jython - exec java -cp "$(java-pkg_getjars "${EANT_GENTOO_CLASSPATH}"):${EANT_GENTOO_CLASSPATH_EXTRA}:dist/${PN}-dev.jar" \ - -Dpython.home="${ED}${instdir}" \ - -Dpython.cachedir="${T}/.jythoncachedir" \ - -Duser.home="${T}" \ - org.python.util.jython "\${@}" - EOF - chmod +x "${T}"/jython || die - - local -x PYTHON="${T}"/jython - # we can't get the path from the interpreter since it does some - # magic that fails on non-installed copy... - local PYTHON_SITEDIR=${EPREFIX}/usr/share/jython-${SLOT}/Lib/site-packages - python_export jython${SLOT} EPYTHON - - # compile tests (everything else is compiled already) - # we're keeping it quiet since jython reports errors verbosely - # and some of the tests are supposed to trigger compile errors - python_optimize "${ED}${instdir}"/Lib/test &>/dev/null - - # for python-exec - echo "EPYTHON='${EPYTHON}'" > epython.py || die - python_domodule epython.py - - # some of the class files end up with newer timestamps than the files they - # were generated from, make sure this doesn't happen - find "${ED}${instdir}"/Lib/ -name '*.class' | xargs touch -} diff --git a/dev-java/jython/jython-2.7.0-r2.ebuild b/dev-java/jython/jython-2.7.0-r2.ebuild new file mode 100644 index 000000000000..c0b7572345d4 --- /dev/null +++ b/dev-java/jython/jython-2.7.0-r2.ebuild @@ -0,0 +1,151 @@ +# Copyright 1999-2017 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +EAPI=6 +JAVA_PKG_IUSE="doc source" + +inherit eutils java-pkg-2 java-ant-2 python-utils-r1 flag-o-matic + +MY_PV=${PV/_beta/-b} +MY_P=${PN}-${MY_PV} + +DESCRIPTION="An implementation of Python written in Java" +HOMEPAGE="http://www.jython.org" +SRC_URI="http://search.maven.org/remotecontent?filepath=org/python/${PN}/${MY_PV}/${MY_P}-sources.jar" + +LICENSE="PSF-2" +SLOT="2.7" +KEYWORDS="~amd64 ~x86 ~amd64-linux ~x86-linux ~x86-macos" +IUSE="examples test" + +CP_DEPEND="dev-java/antlr:3 + dev-java/netty-transport:0 + >=dev-java/asm-5:4 + dev-java/commons-compress:0 + dev-java/guava:20 + dev-java/jffi:1.2 + dev-java/jline:2 + dev-java/icu4j:52 + dev-java/jnr-constants:0 + dev-java/jnr-posix:3.0 + dev-java/jnr-netdb:1.0 + dev-java/stringtemplate:0 + dev-java/xerces:2 + java-virtuals/script-api:0 + java-virtuals/servlet-api:3.0" +RDEPEND="${CP_DEPEND} + >=virtual/jre-1.7" +DEPEND="${CP_DEPEND} + >=virtual/jdk-1.7 + app-arch/unzip + dev-java/ant-core:0 + test? ( + dev-java/junit:4 + dev-java/ant-junit:0 + )" + +S=${WORKDIR} + +RESTRICT="test" + +JAVA_ANT_REWRITE_CLASSPATH="yes" +JAVA_ANT_CLASSPATH_TAGS+=" java" + +EANT_BUILD_TARGET="developer-build" +EANT_TEST_EXTRA_ARGS="-Dpython.home=dist" + +# jdbc-informix and jdbc-oracle-bin (requires registration) aren't exposed. +# Uncomment and add to CDEPEND if you want either of them +#EANT_GENTOO_CLASSPATH+=",jdbc-informix" EANT_EXTRA_ARGS+=" -Dinformix.present" +#EANT_GENTOO_CLASSPATH+=",jdbc-oracle-bin" EANT_EXTRA_ARGS+=" -Doracle.present" + +PATCHES=( + "${FILESDIR}"/${PN}-2.5.2-distutils_scripts_location.patch + "${FILESDIR}"/${PN}-2.5.2-respect_PYTHONPATH.patch + "${FILESDIR}"/${PN}-2.7_beta1-ant.patch + "${FILESDIR}"/${PN}-2.7_beta1-dont-always-recompile-classes.patch + "${FILESDIR}"/${PN}-2.7_beta2-maxrepeat-import.patch + "${FILESDIR}"/${PN}-2.7.0-build.xml.patch + "${FILESDIR}"/CVE-2016-4000.patch +) + +src_prepare() { + default + + find \( -name '*.jar' -o -name '*.class' \ + -o -name '*.pyc' -o -name '*.exe' \) -delete + + # needed for launchertest + chmod +x tests/shell/test-jython.sh || die + + java-pkg-2_src_prepare +} + +src_configure() { + # apparently this can cause problems + append-flags -fno-stack-protector + + EANT_GENTOO_CLASSPATH_EXTRA="$(java-pkg_getjars --with-dependencies antlr-3,jnr-posix-3.0)" + EANT_GENTOO_CLASSPATH_EXTRA+=":$(java-pkg_getjars --build-only ant-core)" +} + +src_test() { + java-pkg-2_src_test +} + +src_install() { + local instdir=/usr/share/${PN}-${SLOT} + + java-pkg_newjar dist/${PN}-dev.jar + + java-pkg_register-optional-dependency jdbc-mysql + java-pkg_register-optional-dependency jdbc-postgresql + + insinto ${instdir} + doins -r dist/{Lib,registry} + + dodoc ACKNOWLEDGMENTS NEWS README.txt + + use doc && java-pkg_dohtml -r dist/Doc/javadoc + use source && java-pkg_dosrc src/* + use examples && java-pkg_doexamples Demo/* + + local java_args=( + -Dpython.home="${EPREFIX}"/usr/share/${PN}-${SLOT} + -Dpython.executable="${EPREFIX}"/usr/bin/jython${SLOT} + -Dpython.cachedir="\${HOME}/.jythoncachedir" + ) + + java-pkg_dolauncher jython${SLOT} \ + --main org.python.util.jython \ + --java_args "${java_args[*]}" + + # we need a wrapper to help python_optimize + cat <<-EOF > "${T}"/jython + exec java -cp "$(java-pkg_getjars "${EANT_GENTOO_CLASSPATH}"):${EANT_GENTOO_CLASSPATH_EXTRA}:dist/${PN}-dev.jar" \ + -Dpython.home="${ED}${instdir}" \ + -Dpython.cachedir="${T}/.jythoncachedir" \ + -Duser.home="${T}" \ + org.python.util.jython "\${@}" + EOF + chmod +x "${T}"/jython || die + + local -x PYTHON="${T}"/jython + # we can't get the path from the interpreter since it does some + # magic that fails on non-installed copy... + local PYTHON_SITEDIR=${EPREFIX}/usr/share/jython-${SLOT}/Lib/site-packages + python_export jython${SLOT} EPYTHON + + # compile tests (everything else is compiled already) + # we're keeping it quiet since jython reports errors verbosely + # and some of the tests are supposed to trigger compile errors + python_optimize "${ED}${instdir}"/Lib/test &>/dev/null + + # for python-exec + echo "EPYTHON='${EPYTHON}'" > epython.py || die + python_domodule epython.py + + # some of the class files end up with newer timestamps than the files they + # were generated from, make sure this doesn't happen + find "${ED}${instdir}"/Lib/ -name '*.class' | xargs touch +} -- cgit v1.2.3