diff --git a/SOURCES/CVE-2015-7501.patch b/SOURCES/CVE-2015-7501.patch new file mode 100644 index 0000000..2d47cda --- /dev/null +++ b/SOURCES/CVE-2015-7501.patch @@ -0,0 +1,552 @@ +From 448087c001fd302df4a8b73f1dd87631c2ae0e61 Mon Sep 17 00:00:00 2001 +From: Marian Koncek +Date: Wed, 14 Oct 2020 15:09:29 +0200 +Subject: [PATCH] CVE-2015-7501 + +--- + .../functors/CloneTransformer.java | 32 ++++++++++++- + .../collections4/functors/ForClosure.java | 33 ++++++++++++- + .../collections4/functors/FunctorUtils.java | 35 ++++++++++++++ + .../functors/InstantiateFactory.java | 32 ++++++++++++- + .../functors/InstantiateTransformer.java | 31 +++++++++++++ + .../functors/InvokerTransformer.java | 32 ++++++++++++- + .../functors/PrototypeFactory.java | 46 +++++++++++++++++++ + .../collections4/functors/WhileClosure.java | 33 ++++++++++++- + .../collections4/FactoryUtilsTest.java | 35 -------------- + .../collections4/TransformerUtilsTest.java | 1 - + 10 files changed, 269 insertions(+), 41 deletions(-) + +diff --git a/src/main/java/org/apache/commons/collections4/functors/CloneTransformer.java b/src/main/java/org/apache/commons/collections4/functors/CloneTransformer.java +index 87b080b..90fb3ef 100644 +--- a/src/main/java/org/apache/commons/collections4/functors/CloneTransformer.java ++++ b/src/main/java/org/apache/commons/collections4/functors/CloneTransformer.java +@@ -16,6 +16,9 @@ + */ + package org.apache.commons.collections4.functors; + ++import java.io.IOException; ++import java.io.ObjectInputStream; ++import java.io.ObjectOutputStream; + import java.io.Serializable; + + import org.apache.commons.collections4.Transformer; +@@ -24,7 +27,17 @@ import org.apache.commons.collections4.Transformer; + * Transformer implementation that returns a clone of the input object. + *

+ * Clone is performed using PrototypeFactory.prototypeFactory(input).create(). +- * ++ *

++ * WARNING: This class will throw an ++ * {@link UnsupportedOperationException} when trying to serialize or ++ * de-serialize an instance to prevent potential remote code execution exploits. ++ *

++ * In order to re-enable serialization support for {@code CloneTransformer} ++ * the following system property can be used (via -Dproperty=true): ++ *

++ * org.apache.commons.collections.enableUnsafeSerialization
++ * 
++ * + * @since 3.0 + * @version $Id: CloneTransformer.java 1543950 2013-11-20 21:13:35Z tn $ + */ +@@ -73,4 +86,21 @@ public class CloneTransformer implements Transformer, Serializable { + return INSTANCE; + } + ++ /** ++ * Overrides the default writeObject implementation to prevent ++ * serialization (see COLLECTIONS-580). ++ */ ++ private void writeObject(ObjectOutputStream os) throws IOException { ++ FunctorUtils.checkUnsafeSerialization(CloneTransformer.class); ++ os.defaultWriteObject(); ++ } ++ ++ /** ++ * Overrides the default readObject implementation to prevent ++ * de-serialization (see COLLECTIONS-580). ++ */ ++ private void readObject(ObjectInputStream is) throws ClassNotFoundException, IOException { ++ FunctorUtils.checkUnsafeSerialization(CloneTransformer.class); ++ is.defaultReadObject(); ++ } + } +diff --git a/src/main/java/org/apache/commons/collections4/functors/ForClosure.java b/src/main/java/org/apache/commons/collections4/functors/ForClosure.java +index ef5a4d1..fdf1d80 100644 +--- a/src/main/java/org/apache/commons/collections4/functors/ForClosure.java ++++ b/src/main/java/org/apache/commons/collections4/functors/ForClosure.java +@@ -16,13 +16,26 @@ + */ + package org.apache.commons.collections4.functors; + ++import java.io.IOException; ++import java.io.ObjectInputStream; ++import java.io.ObjectOutputStream; + import java.io.Serializable; + + import org.apache.commons.collections4.Closure; + + /** + * Closure implementation that calls another closure n times, like a for loop. +- * ++ *

++ * WARNING: This class will throw an ++ * {@link UnsupportedOperationException} when trying to serialize or ++ * de-serialize an instance to prevent potential remote code execution exploits. ++ *

++ * In order to re-enable serialization support for {@code ForClosure} ++ * the following system property can be used (via -Dproperty=true): ++ *

++ * org.apache.commons.collections.enableUnsafeSerialization
++ * 
++ * + * @since 3.0 + * @version $Id: ForClosure.java 1477798 2013-04-30 19:49:02Z tn $ + */ +@@ -102,4 +115,22 @@ public class ForClosure implements Closure, Serializable { + return iCount; + } + ++ /** ++ * Overrides the default writeObject implementation to prevent ++ * serialization (see COLLECTIONS-580). ++ */ ++ private void writeObject(ObjectOutputStream os) throws IOException { ++ FunctorUtils.checkUnsafeSerialization(ForClosure.class); ++ os.defaultWriteObject(); ++ } ++ ++ /** ++ * Overrides the default readObject implementation to prevent ++ * de-serialization (see COLLECTIONS-580). ++ */ ++ private void readObject(ObjectInputStream is) throws ClassNotFoundException, IOException { ++ FunctorUtils.checkUnsafeSerialization(ForClosure.class); ++ is.defaultReadObject(); ++ } ++ + } +diff --git a/src/main/java/org/apache/commons/collections4/functors/FunctorUtils.java b/src/main/java/org/apache/commons/collections4/functors/FunctorUtils.java +index de3ccbd..57da174 100644 +--- a/src/main/java/org/apache/commons/collections4/functors/FunctorUtils.java ++++ b/src/main/java/org/apache/commons/collections4/functors/FunctorUtils.java +@@ -16,6 +16,8 @@ + */ + package org.apache.commons.collections4.functors; + ++import java.security.AccessController; ++import java.security.PrivilegedAction; + import java.util.Collection; + + import org.apache.commons.collections4.Closure; +@@ -30,6 +32,10 @@ import org.apache.commons.collections4.Transformer; + */ + class FunctorUtils { + ++ /** System property key to enable unsafe serialization */ ++ final static String UNSAFE_SERIALIZABLE_PROPERTY ++ = "org.apache.commons.collections.enableUnsafeSerialization"; ++ + /** + * Restricted constructor. + */ +@@ -204,4 +210,33 @@ class FunctorUtils { + return (Transformer) transformer; + } + ++ /** ++ * Package-private helper method to check if serialization support is ++ * enabled for unsafe classes. ++ * ++ * @param clazz the clazz to check for serialization support ++ * @throws UnsupportedOperationException if unsafe serialization is disabled ++ */ ++ static void checkUnsafeSerialization(Class clazz) { ++ String unsafeSerializableProperty; ++ ++ try { ++ unsafeSerializableProperty = ++ (String) AccessController.doPrivileged(new PrivilegedAction() { ++ public Object run() { ++ return System.getProperty(UNSAFE_SERIALIZABLE_PROPERTY); ++ } ++ }); ++ } catch (SecurityException ex) { ++ unsafeSerializableProperty = null; ++ } ++ ++ if (!"true".equalsIgnoreCase(unsafeSerializableProperty)) { ++ throw new UnsupportedOperationException( ++ "Serialization support for " + clazz.getName() + " is disabled for security reasons. " + ++ "To enable it set system property '" + UNSAFE_SERIALIZABLE_PROPERTY + "' to 'true', " + ++ "but you must ensure that your application does not de-serialize objects from untrusted sources."); ++ } ++ } ++ + } +diff --git a/src/main/java/org/apache/commons/collections4/functors/InstantiateFactory.java b/src/main/java/org/apache/commons/collections4/functors/InstantiateFactory.java +index dd6c548..a9fb91f 100644 +--- a/src/main/java/org/apache/commons/collections4/functors/InstantiateFactory.java ++++ b/src/main/java/org/apache/commons/collections4/functors/InstantiateFactory.java +@@ -16,6 +16,9 @@ + */ + package org.apache.commons.collections4.functors; + ++import java.io.IOException; ++import java.io.ObjectInputStream; ++import java.io.ObjectOutputStream; + import java.io.Serializable; + import java.lang.reflect.Constructor; + import java.lang.reflect.InvocationTargetException; +@@ -25,7 +28,17 @@ import org.apache.commons.collections4.FunctorException; + + /** + * Factory implementation that creates a new object instance by reflection. +- * ++ *

++ * WARNING: This class will throw an ++ * {@link UnsupportedOperationException} when trying to serialize or ++ * de-serialize an instance to prevent potential remote code execution exploits. ++ *

++ * In order to re-enable serialization support for {@code InstantiateTransformer} ++ * the following system property can be used (via -Dproperty=true): ++ *

++ * org.apache.commons.collections.enableUnsafeSerialization
++ * 
++ * + * @since 3.0 + * @version $Id: InstantiateFactory.java 1477798 2013-04-30 19:49:02Z tn $ + */ +@@ -133,4 +146,21 @@ public class InstantiateFactory implements Factory, Serializable { + } + } + ++ /** ++ * Overrides the default writeObject implementation to prevent ++ * serialization (see COLLECTIONS-580). ++ */ ++ private void writeObject(ObjectOutputStream os) throws IOException { ++ FunctorUtils.checkUnsafeSerialization(InstantiateFactory.class); ++ os.defaultWriteObject(); ++ } ++ ++ /** ++ * Overrides the default readObject implementation to prevent ++ * de-serialization (see COLLECTIONS-580). ++ */ ++ private void readObject(ObjectInputStream is) throws ClassNotFoundException, IOException { ++ FunctorUtils.checkUnsafeSerialization(InstantiateFactory.class); ++ is.defaultReadObject(); ++ } + } +diff --git a/src/main/java/org/apache/commons/collections4/functors/InstantiateTransformer.java b/src/main/java/org/apache/commons/collections4/functors/InstantiateTransformer.java +index ce3d662..0595316 100644 +--- a/src/main/java/org/apache/commons/collections4/functors/InstantiateTransformer.java ++++ b/src/main/java/org/apache/commons/collections4/functors/InstantiateTransformer.java +@@ -16,6 +16,9 @@ + */ + package org.apache.commons.collections4.functors; + ++import java.io.IOException; ++import java.io.ObjectInputStream; ++import java.io.ObjectOutputStream; + import java.io.Serializable; + import java.lang.reflect.Constructor; + import java.lang.reflect.InvocationTargetException; +@@ -25,6 +28,16 @@ import org.apache.commons.collections4.Transformer; + + /** + * Transformer implementation that creates a new object instance by reflection. ++ *

++ * WARNING: This class will throw an ++ * {@link UnsupportedOperationException} when trying to serialize or ++ * de-serialize an instance to prevent potential remote code execution exploits. ++ *

++ * In order to re-enable serialization support for {@code InstantiateTransformer} ++ * the following system property can be used (via -Dproperty=true): ++ *

++ * org.apache.commons.collections.enableUnsafeSerialization
++ * 
+ * + * @since 3.0 + * @version $Id: InstantiateTransformer.java 1543950 2013-11-20 21:13:35Z tn $ +@@ -125,4 +138,22 @@ public class InstantiateTransformer implements Transformer + } + } + ++ /** ++ * Overrides the default writeObject implementation to prevent ++ * serialization (see COLLECTIONS-580). ++ */ ++ private void writeObject(ObjectOutputStream os) throws IOException { ++ FunctorUtils.checkUnsafeSerialization(InstantiateTransformer.class); ++ os.defaultWriteObject(); ++ } ++ ++ /** ++ * Overrides the default readObject implementation to prevent ++ * de-serialization (see COLLECTIONS-580). ++ */ ++ private void readObject(ObjectInputStream is) throws ClassNotFoundException, IOException { ++ FunctorUtils.checkUnsafeSerialization(InstantiateTransformer.class); ++ is.defaultReadObject(); ++ } ++ + } +diff --git a/src/main/java/org/apache/commons/collections4/functors/InvokerTransformer.java b/src/main/java/org/apache/commons/collections4/functors/InvokerTransformer.java +index bd2d67d..f77f164 100644 +--- a/src/main/java/org/apache/commons/collections4/functors/InvokerTransformer.java ++++ b/src/main/java/org/apache/commons/collections4/functors/InvokerTransformer.java +@@ -16,6 +16,9 @@ + */ + package org.apache.commons.collections4.functors; + ++import java.io.IOException; ++import java.io.ObjectInputStream; ++import java.io.ObjectOutputStream; + import java.io.Serializable; + import java.lang.reflect.InvocationTargetException; + import java.lang.reflect.Method; +@@ -25,7 +28,17 @@ import org.apache.commons.collections4.Transformer; + + /** + * Transformer implementation that creates a new object instance by reflection. +- * ++ *

++ * WARNING: This class will throw an ++ * {@link UnsupportedOperationException} when trying to serialize or ++ * de-serialize an instance to prevent potential remote code execution exploits. ++ *

++ * In order to re-enable serialization support for {@code InvokerTransformer} ++ * the following system property can be used (via -Dproperty=true): ++ *

++ * org.apache.commons.collections.enableUnsafeSerialization
++ * 
++ * + * @since 3.0 + * @version $Id: InvokerTransformer.java 1543247 2013-11-19 00:36:51Z ggregory $ + */ +@@ -139,4 +152,21 @@ public class InvokerTransformer implements Transformer, Serializable + } + } + ++ /** ++ * Overrides the default writeObject implementation to prevent ++ * serialization (see COLLECTIONS-580). ++ */ ++ private void writeObject(ObjectOutputStream os) throws IOException { ++ FunctorUtils.checkUnsafeSerialization(InvokerTransformer.class); ++ os.defaultWriteObject(); ++ } ++ ++ /** ++ * Overrides the default readObject implementation to prevent ++ * de-serialization (see COLLECTIONS-580). ++ */ ++ private void readObject(ObjectInputStream is) throws ClassNotFoundException, IOException { ++ FunctorUtils.checkUnsafeSerialization(InvokerTransformer.class); ++ is.defaultReadObject(); ++ } + } +diff --git a/src/main/java/org/apache/commons/collections4/functors/PrototypeFactory.java b/src/main/java/org/apache/commons/collections4/functors/PrototypeFactory.java +index 8922d15..696fa35 100644 +--- a/src/main/java/org/apache/commons/collections4/functors/PrototypeFactory.java ++++ b/src/main/java/org/apache/commons/collections4/functors/PrototypeFactory.java +@@ -47,6 +47,16 @@ public class PrototypeFactory { + *
  • public copy constructor + *
  • serialization clone + *
      ++ *

      ++ * WARNING: This method will return a {@code Factory} ++ * that will throw an {@link UnsupportedOperationException} when trying to serialize ++ * or de-serialize it to prevent potential remote code execution exploits. ++ *

      ++ * In order to re-enable serialization support the following system property ++ * can be used (via -Dproperty=true): ++ *

      ++     * org.apache.commons.collections.enableUnsafeSerialization
      ++     * 
      + * + * @param the type the factory creates + * @param prototype the object to clone each time in the factory +@@ -141,6 +151,24 @@ public class PrototypeFactory { + throw new FunctorException("PrototypeCloneFactory: Clone method threw an exception", ex); + } + } ++ ++ /** ++ * Overrides the default writeObject implementation to prevent ++ * serialization (see COLLECTIONS-580). ++ */ ++ private void writeObject(ObjectOutputStream os) throws IOException { ++ FunctorUtils.checkUnsafeSerialization(PrototypeCloneFactory.class); ++ os.defaultWriteObject(); ++ } ++ ++ /** ++ * Overrides the default readObject implementation to prevent ++ * de-serialization (see COLLECTIONS-580). ++ */ ++ private void readObject(ObjectInputStream is) throws ClassNotFoundException, IOException { ++ FunctorUtils.checkUnsafeSerialization(PrototypeCloneFactory.class); ++ is.defaultReadObject(); ++ } + } + + // PrototypeSerializationFactory +@@ -200,6 +228,24 @@ public class PrototypeFactory { + } + } + } ++ ++ /** ++ * Overrides the default writeObject implementation to prevent ++ * serialization (see COLLECTIONS-580). ++ */ ++ private void writeObject(ObjectOutputStream os) throws IOException { ++ FunctorUtils.checkUnsafeSerialization(PrototypeSerializationFactory.class); ++ os.defaultWriteObject(); ++ } ++ ++ /** ++ * Overrides the default readObject implementation to prevent ++ * de-serialization (see COLLECTIONS-580). ++ */ ++ private void readObject(ObjectInputStream is) throws ClassNotFoundException, IOException { ++ FunctorUtils.checkUnsafeSerialization(PrototypeSerializationFactory.class); ++ is.defaultReadObject(); ++ } + } + + } +diff --git a/src/main/java/org/apache/commons/collections4/functors/WhileClosure.java b/src/main/java/org/apache/commons/collections4/functors/WhileClosure.java +index b169d44..8c8eb91 100644 +--- a/src/main/java/org/apache/commons/collections4/functors/WhileClosure.java ++++ b/src/main/java/org/apache/commons/collections4/functors/WhileClosure.java +@@ -16,6 +16,9 @@ + */ + package org.apache.commons.collections4.functors; + ++import java.io.IOException; ++import java.io.ObjectInputStream; ++import java.io.ObjectOutputStream; + import java.io.Serializable; + + import org.apache.commons.collections4.Closure; +@@ -24,7 +27,17 @@ import org.apache.commons.collections4.Predicate; + /** + * Closure implementation that executes a closure repeatedly until a condition is met, + * like a do-while or while loop. +- * ++ *

      ++ * WARNING: This class will throw an ++ * {@link UnsupportedOperationException} when trying to serialize or ++ * de-serialize an instance to prevent potential remote code execution exploits. ++ *

      ++ * In order to re-enable serialization support for {@code WhileClosure} ++ * the following system property can be used (via -Dproperty=true): ++ *

      ++ * org.apache.commons.collections.enableUnsafeSerialization
      ++ * 
      ++ * + * @since 3.0 + * @version $Id: WhileClosure.java 1477798 2013-04-30 19:49:02Z tn $ + */ +@@ -120,4 +133,22 @@ public class WhileClosure implements Closure, Serializable { + return iDoLoop; + } + ++ /** ++ * Overrides the default writeObject implementation to prevent ++ * serialization (see COLLECTIONS-580). ++ */ ++ private void writeObject(ObjectOutputStream os) throws IOException { ++ FunctorUtils.checkUnsafeSerialization(WhileClosure.class); ++ os.defaultWriteObject(); ++ } ++ ++ /** ++ * Overrides the default readObject implementation to prevent ++ * de-serialization (see COLLECTIONS-580). ++ */ ++ private void readObject(ObjectInputStream is) throws ClassNotFoundException, IOException { ++ FunctorUtils.checkUnsafeSerialization(WhileClosure.class); ++ is.defaultReadObject(); ++ } ++ + } +diff --git a/src/test/java/org/apache/commons/collections4/FactoryUtilsTest.java b/src/test/java/org/apache/commons/collections4/FactoryUtilsTest.java +index 941cd40..7394ede 100644 +--- a/src/test/java/org/apache/commons/collections4/FactoryUtilsTest.java ++++ b/src/test/java/org/apache/commons/collections4/FactoryUtilsTest.java +@@ -112,15 +112,6 @@ public class FactoryUtilsTest extends junit.framework.TestCase { + final Date created = factory.create(); + assertTrue(proto != created); + assertEquals(proto, created); +- +- // check serialisation works +- final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); +- final ObjectOutputStream out = new ObjectOutputStream(buffer); +- out.writeObject(factory); +- out.close(); +- final ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray())); +- in.readObject(); +- in.close(); + } + + public void testPrototypeFactoryPublicCopyConstructor() throws Exception { +@@ -130,23 +121,6 @@ public class FactoryUtilsTest extends junit.framework.TestCase { + final Object created = factory.create(); + assertTrue(proto != created); + assertEquals(proto, created); +- +- // check serialisation works +- ByteArrayOutputStream buffer = new ByteArrayOutputStream(); +- ObjectOutputStream out = new ObjectOutputStream(buffer); +- try { +- out.writeObject(factory); +- } catch (final NotSerializableException ex) { +- out.close(); +- } +- factory = FactoryUtils.prototypeFactory(new Mock2("S")); +- buffer = new ByteArrayOutputStream(); +- out = new ObjectOutputStream(buffer); +- out.writeObject(factory); +- out.close(); +- final ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray())); +- in.readObject(); +- in.close(); + } + + public void testPrototypeFactoryPublicSerialization() throws Exception { +@@ -156,15 +130,6 @@ public class FactoryUtilsTest extends junit.framework.TestCase { + final Integer created = factory.create(); + assertTrue(proto != created); + assertEquals(proto, created); +- +- // check serialisation works +- final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); +- final ObjectOutputStream out = new ObjectOutputStream(buffer); +- out.writeObject(factory); +- out.close(); +- final ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray())); +- in.readObject(); +- in.close(); + } + + public void testPrototypeFactoryPublicSerializationError() { +diff --git a/src/test/java/org/apache/commons/collections4/TransformerUtilsTest.java b/src/test/java/org/apache/commons/collections4/TransformerUtilsTest.java +index 9c0c530..a924e05 100644 +--- a/src/test/java/org/apache/commons/collections4/TransformerUtilsTest.java ++++ b/src/test/java/org/apache/commons/collections4/TransformerUtilsTest.java +@@ -431,7 +431,6 @@ public class TransformerUtilsTest extends junit.framework.TestCase { + */ + public void testSingletonPatternInSerialization() { + final Object[] singletones = new Object[] { +- CloneTransformer.INSTANCE, + ExceptionTransformer.INSTANCE, + NOPTransformer.INSTANCE, + StringValueTransformer.stringValueTransformer(), +-- +2.26.2 + diff --git a/SPECS/apache-commons-collections4.spec b/SPECS/apache-commons-collections4.spec index 4ecb1b4..35f9ffa 100644 --- a/SPECS/apache-commons-collections4.spec +++ b/SPECS/apache-commons-collections4.spec @@ -4,13 +4,15 @@ Summary: Extension of the Java Collections Framework Name: %{?scl_prefix}apache-commons-collections4 Version: 4.0 -Release: 7.2%{?dist} +Release: 7.3%{?dist} License: ASL 2.0 URL: http://commons.apache.org/proper/commons-collections/ BuildArch: noarch Source0: http://www.apache.org/dist/commons/collections/source/commons-collections4-4.0-src.tar.gz +Patch0: CVE-2015-7501.patch + BuildRequires: %{?scl_prefix}maven-local BuildRequires: %{?scl_prefix}mvn(junit:junit) BuildRequires: %{?scl_prefix}mvn(org.apache.commons:commons-parent:pom:) @@ -29,6 +31,9 @@ This package provides %{summary}. %prep %setup -q -n commons-collections4-%{version}-src + +%patch0 -p1 + %mvn_file : %{pkg_name} commons-collections4 %build @@ -45,6 +50,10 @@ This package provides %{summary}. %doc LICENSE.txt NOTICE.txt %changelog +* Wed Oct 14 2020 Marian Koncek - 4.0-7.3 +- Fix security vulnerabilities +- Resolves: CVE-2015-7501 + * Thu Jun 22 2017 Michael Simacek - 4.0-7.2 - Mass rebuild 2017-06-22