Version in base suite: 5.17.2+dfsg-2 Base version: activemq_5.17.2+dfsg-2 Target version: activemq_5.17.2+dfsg-2+deb12u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/a/activemq/activemq_5.17.2+dfsg-2.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/a/activemq/activemq_5.17.2+dfsg-2+deb12u1.dsc changelog | 8 patches/0001-AMQ-9201-Update-Jolokia-default-access-configuration.patch | 70 patches/0001-AMQ-9370-Openwire-marshaller-should-validate-Throwab.patch | 729 ++++++++++ patches/series | 2 4 files changed, 809 insertions(+) diff -Nru activemq-5.17.2+dfsg/debian/changelog activemq-5.17.2+dfsg/debian/changelog --- activemq-5.17.2+dfsg/debian/changelog 2023-02-12 15:53:03.000000000 +0000 +++ activemq-5.17.2+dfsg/debian/changelog 2024-10-24 02:20:32.000000000 +0000 @@ -1,3 +1,11 @@ +activemq (5.17.2+dfsg-2+deb12u1) bookworm-security; urgency=medium + + * CVE-2022-41678: Potential arbitrary code execution via Jolokia + * CVE-2023-46604: The Java OpenWire protocol marshaller is vulnerable to + Remote Code Execution (Closes: #1054909). + + -- Santiago Ruano Rincón Wed, 23 Oct 2024 23:20:32 -0300 + activemq (5.17.2+dfsg-2) unstable; urgency=medium * Team upload. diff -Nru activemq-5.17.2+dfsg/debian/patches/0001-AMQ-9201-Update-Jolokia-default-access-configuration.patch activemq-5.17.2+dfsg/debian/patches/0001-AMQ-9201-Update-Jolokia-default-access-configuration.patch --- activemq-5.17.2+dfsg/debian/patches/0001-AMQ-9201-Update-Jolokia-default-access-configuration.patch 1970-01-01 00:00:00.000000000 +0000 +++ activemq-5.17.2+dfsg/debian/patches/0001-AMQ-9201-Update-Jolokia-default-access-configuration.patch 2024-10-24 02:20:32.000000000 +0000 @@ -0,0 +1,70 @@ +From bf65929fdc607d5bb953a507c2f0c7256ae8e5b6 Mon Sep 17 00:00:00 2001 +From: "Christopher L. Shannon (cshannon)" +Date: Wed, 1 Feb 2023 07:04:56 -0500 +Subject: [PATCH] AMQ-9201 - Update Jolokia default access configuration + +(cherry picked from commit 6120169e563b55323352431dfe9ac67a8b4de6c2) + +Bug: https://issues.apache.org/jira/browse/AMQ-9201 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2022-41678 + +--- + assembly/src/release/conf/jolokia-access.xml | 34 +++++++++++++++++++- + 1 file changed, 33 insertions(+), 1 deletion(-) + +diff --git a/assembly/src/release/conf/jolokia-access.xml b/assembly/src/release/conf/jolokia-access.xml +index 8cad1cd40e..97b099a5b7 100644 +--- a/assembly/src/release/conf/jolokia-access.xml ++++ b/assembly/src/release/conf/jolokia-access.xml +@@ -22,8 +22,35 @@ + + + +- ++ ++ ++ read ++ list ++ version ++ search ++ ++ ++ ++ ++ ++ org.apache.activemq:* ++ * ++ * ++ ++ ++ ++ jolokia:type=Config ++ * ++ ++ ++ ++ + ++ ++ org.apache.logging.log4j2:* ++ * ++ * ++ + + com.sun.management:type=DiagnosticCommand + * +@@ -34,6 +61,11 @@ + * + * + ++ ++ jdk.management.jfr:type=FlightRecorder ++ * ++ * ++ + + + +-- +2.39.5 + diff -Nru activemq-5.17.2+dfsg/debian/patches/0001-AMQ-9370-Openwire-marshaller-should-validate-Throwab.patch activemq-5.17.2+dfsg/debian/patches/0001-AMQ-9370-Openwire-marshaller-should-validate-Throwab.patch --- activemq-5.17.2+dfsg/debian/patches/0001-AMQ-9370-Openwire-marshaller-should-validate-Throwab.patch 1970-01-01 00:00:00.000000000 +0000 +++ activemq-5.17.2+dfsg/debian/patches/0001-AMQ-9370-Openwire-marshaller-should-validate-Throwab.patch 2024-10-24 02:20:32.000000000 +0000 @@ -0,0 +1,729 @@ +From d0ccdd31544ada83185554c87c7aa141064020f0 Mon Sep 17 00:00:00 2001 +From: "Christopher L. Shannon (cshannon)" +Date: Mon, 23 Oct 2023 18:24:38 -0400 +Subject: [PATCH] AMQ-9370 - Openwire marshaller should validate Throwable + class type + +(cherry picked from commit 3eaf3107f4fb9a3ce7ab45c175bfaeac7e866d5b) + +Bug-Debian: https://bugs.debian.org/1054909 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2023-46604 +--- + activemq-client/pom.xml | 11 ++ + .../activemq/openwire/OpenWireUtil.java | 32 ++++ + .../openwire/v1/BaseDataStreamMarshaller.java | 4 + + .../v10/BaseDataStreamMarshaller.java | 4 + + .../v11/BaseDataStreamMarshaller.java | 4 + + .../v12/BaseDataStreamMarshaller.java | 4 + + .../openwire/v9/BaseDataStreamMarshaller.java | 4 + + .../openwire/OpenWireValidationTest.java | 166 ++++++++++++++++++ + activemq-openwire-legacy/pom.xml | 12 ++ + .../openwire/v2/BaseDataStreamMarshaller.java | 4 + + .../openwire/v3/BaseDataStreamMarshaller.java | 4 + + .../openwire/v4/BaseDataStreamMarshaller.java | 4 + + .../openwire/v5/BaseDataStreamMarshaller.java | 4 + + .../openwire/v6/BaseDataStreamMarshaller.java | 4 + + .../openwire/v7/BaseDataStreamMarshaller.java | 4 + + .../openwire/v8/BaseDataStreamMarshaller.java | 4 + + .../OpenWireLegacyValidationTest.java | 129 ++++++++++++++ + pom.xml | 7 + + 18 files changed, 405 insertions(+) + create mode 100644 activemq-client/src/main/java/org/apache/activemq/openwire/OpenWireUtil.java + create mode 100644 activemq-client/src/test/java/org/apache/activemq/openwire/OpenWireValidationTest.java + create mode 100644 activemq-openwire-legacy/src/test/java/org/apache/activemq/openwire/OpenWireLegacyValidationTest.java + +Index: activemq/activemq-client/pom.xml +=================================================================== +--- activemq.orig/activemq-client/pom.xml ++++ activemq/activemq-client/pom.xml +@@ -278,6 +278,17 @@ + + + ++ ++ ++ maven-jar-plugin ++ ++ ++ ++ test-jar ++ ++ ++ ++ + + + +Index: activemq/activemq-client/src/main/java/org/apache/activemq/openwire/OpenWireUtil.java +=================================================================== +--- /dev/null ++++ activemq/activemq-client/src/main/java/org/apache/activemq/openwire/OpenWireUtil.java +@@ -0,0 +1,32 @@ ++/** ++ * Licensed to the Apache Software Foundation (ASF) under one or more ++ * contributor license agreements. See the NOTICE file distributed with ++ * this work for additional information regarding copyright ownership. ++ * The ASF licenses this file to You under the Apache License, Version 2.0 ++ * (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++package org.apache.activemq.openwire; ++ ++public class OpenWireUtil { ++ ++ /** ++ * Verify that the provided class extends {@link Throwable} and throw an ++ * {@link IllegalArgumentException} if it does not. ++ * ++ * @param clazz ++ */ ++ public static void validateIsThrowable(Class clazz) { ++ if (!Throwable.class.isAssignableFrom(clazz)) { ++ throw new IllegalArgumentException("Class " + clazz + " is not assignable to Throwable"); ++ } ++ } ++} +Index: activemq/activemq-client/src/main/java/org/apache/activemq/openwire/v1/BaseDataStreamMarshaller.java +=================================================================== +--- activemq.orig/activemq-client/src/main/java/org/apache/activemq/openwire/v1/BaseDataStreamMarshaller.java ++++ activemq/activemq-client/src/main/java/org/apache/activemq/openwire/v1/BaseDataStreamMarshaller.java +@@ -25,6 +25,7 @@ import org.apache.activemq.command.DataS + import org.apache.activemq.openwire.BooleanStream; + import org.apache.activemq.openwire.DataStreamMarshaller; + import org.apache.activemq.openwire.OpenWireFormat; ++import org.apache.activemq.openwire.OpenWireUtil; + import org.apache.activemq.util.ByteSequence; + + public abstract class BaseDataStreamMarshaller implements DataStreamMarshaller { +@@ -229,8 +230,11 @@ public abstract class BaseDataStreamMars + private Throwable createThrowable(String className, String message) { + try { + Class clazz = Class.forName(className, false, BaseDataStreamMarshaller.class.getClassLoader()); ++ OpenWireUtil.validateIsThrowable(clazz); + Constructor constructor = clazz.getConstructor(new Class[] {String.class}); + return (Throwable)constructor.newInstance(new Object[] {message}); ++ } catch (IllegalArgumentException e) { ++ return e; + } catch (Throwable e) { + return new Throwable(className + ": " + message); + } +Index: activemq/activemq-client/src/main/java/org/apache/activemq/openwire/v10/BaseDataStreamMarshaller.java +=================================================================== +--- activemq.orig/activemq-client/src/main/java/org/apache/activemq/openwire/v10/BaseDataStreamMarshaller.java ++++ activemq/activemq-client/src/main/java/org/apache/activemq/openwire/v10/BaseDataStreamMarshaller.java +@@ -24,6 +24,7 @@ import org.apache.activemq.command.DataS + import org.apache.activemq.openwire.BooleanStream; + import org.apache.activemq.openwire.DataStreamMarshaller; + import org.apache.activemq.openwire.OpenWireFormat; ++import org.apache.activemq.openwire.OpenWireUtil; + import org.apache.activemq.util.ByteSequence; + + public abstract class BaseDataStreamMarshaller implements DataStreamMarshaller { +@@ -228,8 +229,11 @@ public abstract class BaseDataStreamMars + private Throwable createThrowable(String className, String message) { + try { + Class clazz = Class.forName(className, false, BaseDataStreamMarshaller.class.getClassLoader()); ++ OpenWireUtil.validateIsThrowable(clazz); + Constructor constructor = clazz.getConstructor(new Class[] {String.class}); + return (Throwable)constructor.newInstance(new Object[] {message}); ++ } catch (IllegalArgumentException e) { ++ return e; + } catch (Throwable e) { + return new Throwable(className + ": " + message); + } +Index: activemq/activemq-client/src/main/java/org/apache/activemq/openwire/v11/BaseDataStreamMarshaller.java +=================================================================== +--- activemq.orig/activemq-client/src/main/java/org/apache/activemq/openwire/v11/BaseDataStreamMarshaller.java ++++ activemq/activemq-client/src/main/java/org/apache/activemq/openwire/v11/BaseDataStreamMarshaller.java +@@ -24,6 +24,7 @@ import org.apache.activemq.command.DataS + import org.apache.activemq.openwire.BooleanStream; + import org.apache.activemq.openwire.DataStreamMarshaller; + import org.apache.activemq.openwire.OpenWireFormat; ++import org.apache.activemq.openwire.OpenWireUtil; + import org.apache.activemq.util.ByteSequence; + + public abstract class BaseDataStreamMarshaller implements DataStreamMarshaller { +@@ -227,8 +228,11 @@ public abstract class BaseDataStreamMars + private Throwable createThrowable(String className, String message) { + try { + Class clazz = Class.forName(className, false, BaseDataStreamMarshaller.class.getClassLoader()); ++ OpenWireUtil.validateIsThrowable(clazz); + Constructor constructor = clazz.getConstructor(new Class[] {String.class}); + return (Throwable)constructor.newInstance(new Object[] {message}); ++ } catch (IllegalArgumentException e) { ++ return e; + } catch (Throwable e) { + return new Throwable(className + ": " + message); + } +Index: activemq/activemq-client/src/main/java/org/apache/activemq/openwire/v12/BaseDataStreamMarshaller.java +=================================================================== +--- activemq.orig/activemq-client/src/main/java/org/apache/activemq/openwire/v12/BaseDataStreamMarshaller.java ++++ activemq/activemq-client/src/main/java/org/apache/activemq/openwire/v12/BaseDataStreamMarshaller.java +@@ -24,6 +24,7 @@ import org.apache.activemq.command.DataS + import org.apache.activemq.openwire.BooleanStream; + import org.apache.activemq.openwire.DataStreamMarshaller; + import org.apache.activemq.openwire.OpenWireFormat; ++import org.apache.activemq.openwire.OpenWireUtil; + import org.apache.activemq.util.ByteSequence; + + public abstract class BaseDataStreamMarshaller implements DataStreamMarshaller { +@@ -227,8 +228,11 @@ public abstract class BaseDataStreamMars + private Throwable createThrowable(String className, String message) { + try { + Class clazz = Class.forName(className, false, BaseDataStreamMarshaller.class.getClassLoader()); ++ OpenWireUtil.validateIsThrowable(clazz); + Constructor constructor = clazz.getConstructor(new Class[] {String.class}); + return (Throwable)constructor.newInstance(new Object[] {message}); ++ } catch (IllegalArgumentException e) { ++ return e; + } catch (Throwable e) { + return new Throwable(className + ": " + message); + } +Index: activemq/activemq-client/src/main/java/org/apache/activemq/openwire/v9/BaseDataStreamMarshaller.java +=================================================================== +--- activemq.orig/activemq-client/src/main/java/org/apache/activemq/openwire/v9/BaseDataStreamMarshaller.java ++++ activemq/activemq-client/src/main/java/org/apache/activemq/openwire/v9/BaseDataStreamMarshaller.java +@@ -24,6 +24,7 @@ import org.apache.activemq.command.DataS + import org.apache.activemq.openwire.BooleanStream; + import org.apache.activemq.openwire.DataStreamMarshaller; + import org.apache.activemq.openwire.OpenWireFormat; ++import org.apache.activemq.openwire.OpenWireUtil; + import org.apache.activemq.util.ByteSequence; + + public abstract class BaseDataStreamMarshaller implements DataStreamMarshaller { +@@ -227,8 +228,11 @@ public abstract class BaseDataStreamMars + private Throwable createThrowable(String className, String message) { + try { + Class clazz = Class.forName(className, false, BaseDataStreamMarshaller.class.getClassLoader()); ++ OpenWireUtil.validateIsThrowable(clazz); + Constructor constructor = clazz.getConstructor(new Class[] {String.class}); + return (Throwable)constructor.newInstance(new Object[] {message}); ++ } catch (IllegalArgumentException e) { ++ return e; + } catch (Throwable e) { + return new Throwable(className + ": " + message); + } +Index: activemq/activemq-client/src/test/java/org/apache/activemq/openwire/OpenWireValidationTest.java +=================================================================== +--- /dev/null ++++ activemq/activemq-client/src/test/java/org/apache/activemq/openwire/OpenWireValidationTest.java +@@ -0,0 +1,166 @@ ++/** ++ * Licensed to the Apache Software Foundation (ASF) under one or more ++ * contributor license agreements. See the NOTICE file distributed with ++ * this work for additional information regarding copyright ownership. ++ * The ASF licenses this file to You under the Apache License, Version 2.0 ++ * (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++package org.apache.activemq.openwire; ++ ++import static org.junit.Assert.assertTrue; ++ ++import java.io.DataOutput; ++import java.io.IOException; ++import java.lang.reflect.Method; ++import java.util.ArrayList; ++import java.util.Collection; ++import java.util.List; ++import org.apache.activemq.command.CommandTypes; ++import org.apache.activemq.command.ExceptionResponse; ++import org.apache.activemq.util.ByteSequence; ++import org.junit.Test; ++import org.junit.runner.RunWith; ++import org.junit.runners.Parameterized; ++import org.junit.runners.Parameterized.Parameters; ++ ++/** ++ * Test that Openwire marshalling will validate Throwable types during ++ * unmarshalling commands that contain a Throwable ++ */ ++@RunWith(Parameterized.class) ++public class OpenWireValidationTest { ++ ++ protected final int version; ++ ++ @Parameters(name = "version={0}") ++ public static Collection data() { ++ List versions = List.of(1, 9, 10, 11, 12); ++ List versionObjs = new ArrayList<>(); ++ for (int i : versions) { ++ versionObjs.add(new Object[]{i}); ++ } ++ ++ // Sanity check to make sure the latest generated version is contained in the list ++ // This will make sure that we don't forget to update this test to include ++ // any future versions that are generated ++ assertTrue("List of Openwire versions does not include latest version", ++ versions.contains((int)CommandTypes.PROTOCOL_VERSION)); ++ ++ return versionObjs; ++ } ++ ++ public OpenWireValidationTest(int version) { ++ this.version = version; ++ } ++ ++ @Test ++ public void testOpenwireThrowableValidation() throws Exception { ++ // Create a format which will use loose encoding by default ++ // The code for handling exception creation is shared between both ++ // tight/loose encoding so only need to test 1 ++ OpenWireFormat format = new OpenWireFormat(); ++ ++ // Override the marshaller map with a custom impl to purposely marshal a class type that is ++ // not a Throwable for testing the unmarshaller ++ Class marshallerFactory = getMarshallerFactory(); ++ Method createMarshallerMap = marshallerFactory.getMethod("createMarshallerMap", OpenWireFormat.class); ++ DataStreamMarshaller[] map = (DataStreamMarshaller[]) createMarshallerMap.invoke(marshallerFactory, format); ++ map[ExceptionResponse.DATA_STRUCTURE_TYPE] = getExceptionMarshaller(); ++ // This will trigger updating the marshaller from the marshaller map with the right version ++ format.setVersion(version); ++ ++ // Build the response and try to unmarshal which should give an IllegalArgumentExeption on unmarshall ++ // as the test marshaller should have encoded a class type that is not a Throwable ++ ExceptionResponse r = new ExceptionResponse(); ++ r.setException(new Exception()); ++ ByteSequence bss = format.marshal(r); ++ ExceptionResponse response = (ExceptionResponse) format.unmarshal(bss); ++ ++ assertTrue(response.getException() instanceof IllegalArgumentException); ++ assertTrue(response.getException().getMessage().contains("is not assignable to Throwable")); ++ } ++ ++ static class NotAThrowable { ++ private String message; ++ ++ public NotAThrowable(String message) { ++ this.message = message; ++ } ++ ++ public NotAThrowable() { ++ } ++ } ++ ++ private Class getMarshallerFactory() throws ClassNotFoundException { ++ return Class.forName("org.apache.activemq.openwire.v" + version + ".MarshallerFactory"); ++ } ++ ++ // Create test marshallers for all non-legacy versions that will encode NotAThrowable ++ // instead of the exception type for testing purposes ++ protected DataStreamMarshaller getExceptionMarshaller() { ++ switch (version) { ++ case 12: ++ return new org.apache.activemq.openwire.v12.ExceptionResponseMarshaller() { ++ @Override ++ protected void looseMarshalThrowable(OpenWireFormat wireFormat, Throwable o, ++ DataOutput dataOut) throws IOException { ++ dataOut.writeBoolean(o != null); ++ looseMarshalString(NotAThrowable.class.getName(), dataOut); ++ looseMarshalString(o.getMessage(), dataOut); ++ } ++ }; ++ case 11: ++ return new org.apache.activemq.openwire.v11.ExceptionResponseMarshaller() { ++ @Override ++ protected void looseMarshalThrowable(OpenWireFormat wireFormat, Throwable o, ++ DataOutput dataOut) throws IOException { ++ dataOut.writeBoolean(o != null); ++ looseMarshalString(NotAThrowable.class.getName(), dataOut); ++ looseMarshalString(o.getMessage(), dataOut); ++ } ++ }; ++ case 10: ++ return new org.apache.activemq.openwire.v10.ExceptionResponseMarshaller() { ++ @Override ++ protected void looseMarshalThrowable(OpenWireFormat wireFormat, Throwable o, ++ DataOutput dataOut) throws IOException { ++ dataOut.writeBoolean(o != null); ++ looseMarshalString(NotAThrowable.class.getName(), dataOut); ++ looseMarshalString(o.getMessage(), dataOut); ++ } ++ }; ++ case 9: ++ return new org.apache.activemq.openwire.v9.ExceptionResponseMarshaller() { ++ @Override ++ protected void looseMarshalThrowable(OpenWireFormat wireFormat, Throwable o, ++ DataOutput dataOut) throws IOException { ++ dataOut.writeBoolean(o != null); ++ looseMarshalString(NotAThrowable.class.getName(), dataOut); ++ looseMarshalString(o.getMessage(), dataOut); ++ } ++ }; ++ case 1: ++ return new org.apache.activemq.openwire.v1.ExceptionResponseMarshaller() { ++ @Override ++ protected void looseMarshalThrowable(OpenWireFormat wireFormat, Throwable o, ++ DataOutput dataOut) throws IOException { ++ dataOut.writeBoolean(o != null); ++ looseMarshalString(NotAThrowable.class.getName(), dataOut); ++ looseMarshalString(o.getMessage(), dataOut); ++ } ++ }; ++ default: ++ throw new IllegalArgumentException("Unknown openwire version of " + version); ++ } ++ } ++ ++} +Index: activemq/activemq-openwire-legacy/pom.xml +=================================================================== +--- activemq.orig/activemq-openwire-legacy/pom.xml ++++ activemq/activemq-openwire-legacy/pom.xml +@@ -35,6 +35,20 @@ + org.apache.activemq + activemq-client + ++ ++ ++ ++ junit ++ junit ++ test ++ + + + +Index: activemq/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v2/BaseDataStreamMarshaller.java +=================================================================== +--- activemq.orig/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v2/BaseDataStreamMarshaller.java ++++ activemq/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v2/BaseDataStreamMarshaller.java +@@ -25,6 +25,7 @@ import org.apache.activemq.command.DataS + import org.apache.activemq.openwire.BooleanStream; + import org.apache.activemq.openwire.DataStreamMarshaller; + import org.apache.activemq.openwire.OpenWireFormat; ++import org.apache.activemq.openwire.OpenWireUtil; + import org.apache.activemq.util.ByteSequence; + + public abstract class BaseDataStreamMarshaller implements DataStreamMarshaller { +@@ -228,8 +229,11 @@ public abstract class BaseDataStreamMars + private Throwable createThrowable(String className, String message) { + try { + Class clazz = Class.forName(className, false, BaseDataStreamMarshaller.class.getClassLoader()); ++ OpenWireUtil.validateIsThrowable(clazz); + Constructor constructor = clazz.getConstructor(new Class[] {String.class}); + return (Throwable)constructor.newInstance(new Object[] {message}); ++ } catch (IllegalArgumentException e) { ++ return e; + } catch (Throwable e) { + return new Throwable(className + ": " + message); + } +Index: activemq/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v3/BaseDataStreamMarshaller.java +=================================================================== +--- activemq.orig/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v3/BaseDataStreamMarshaller.java ++++ activemq/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v3/BaseDataStreamMarshaller.java +@@ -25,6 +25,7 @@ import org.apache.activemq.command.DataS + import org.apache.activemq.openwire.BooleanStream; + import org.apache.activemq.openwire.DataStreamMarshaller; + import org.apache.activemq.openwire.OpenWireFormat; ++import org.apache.activemq.openwire.OpenWireUtil; + import org.apache.activemq.util.ByteSequence; + + public abstract class BaseDataStreamMarshaller implements DataStreamMarshaller { +@@ -228,8 +229,11 @@ public abstract class BaseDataStreamMars + private Throwable createThrowable(String className, String message) { + try { + Class clazz = Class.forName(className, false, BaseDataStreamMarshaller.class.getClassLoader()); ++ OpenWireUtil.validateIsThrowable(clazz); + Constructor constructor = clazz.getConstructor(new Class[] {String.class}); + return (Throwable)constructor.newInstance(new Object[] {message}); ++ } catch (IllegalArgumentException e) { ++ return e; + } catch (Throwable e) { + return new Throwable(className + ": " + message); + } +Index: activemq/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v4/BaseDataStreamMarshaller.java +=================================================================== +--- activemq.orig/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v4/BaseDataStreamMarshaller.java ++++ activemq/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v4/BaseDataStreamMarshaller.java +@@ -25,6 +25,7 @@ import org.apache.activemq.command.DataS + import org.apache.activemq.openwire.BooleanStream; + import org.apache.activemq.openwire.DataStreamMarshaller; + import org.apache.activemq.openwire.OpenWireFormat; ++import org.apache.activemq.openwire.OpenWireUtil; + import org.apache.activemq.util.ByteSequence; + + public abstract class BaseDataStreamMarshaller implements DataStreamMarshaller { +@@ -228,8 +229,11 @@ public abstract class BaseDataStreamMars + private Throwable createThrowable(String className, String message) { + try { + Class clazz = Class.forName(className, false, BaseDataStreamMarshaller.class.getClassLoader()); ++ OpenWireUtil.validateIsThrowable(clazz); + Constructor constructor = clazz.getConstructor(new Class[] {String.class}); + return (Throwable)constructor.newInstance(new Object[] {message}); ++ } catch (IllegalArgumentException e) { ++ return e; + } catch (Throwable e) { + return new Throwable(className + ": " + message); + } +Index: activemq/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v5/BaseDataStreamMarshaller.java +=================================================================== +--- activemq.orig/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v5/BaseDataStreamMarshaller.java ++++ activemq/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v5/BaseDataStreamMarshaller.java +@@ -25,6 +25,7 @@ import org.apache.activemq.command.DataS + import org.apache.activemq.openwire.BooleanStream; + import org.apache.activemq.openwire.DataStreamMarshaller; + import org.apache.activemq.openwire.OpenWireFormat; ++import org.apache.activemq.openwire.OpenWireUtil; + import org.apache.activemq.util.ByteSequence; + + public abstract class BaseDataStreamMarshaller implements DataStreamMarshaller { +@@ -228,8 +229,11 @@ public abstract class BaseDataStreamMars + private Throwable createThrowable(String className, String message) { + try { + Class clazz = Class.forName(className, false, BaseDataStreamMarshaller.class.getClassLoader()); ++ OpenWireUtil.validateIsThrowable(clazz); + Constructor constructor = clazz.getConstructor(new Class[] {String.class}); + return (Throwable)constructor.newInstance(new Object[] {message}); ++ } catch (IllegalArgumentException e) { ++ return e; + } catch (Throwable e) { + return new Throwable(className + ": " + message); + } +Index: activemq/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v6/BaseDataStreamMarshaller.java +=================================================================== +--- activemq.orig/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v6/BaseDataStreamMarshaller.java ++++ activemq/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v6/BaseDataStreamMarshaller.java +@@ -25,6 +25,7 @@ import org.apache.activemq.command.DataS + import org.apache.activemq.openwire.BooleanStream; + import org.apache.activemq.openwire.DataStreamMarshaller; + import org.apache.activemq.openwire.OpenWireFormat; ++import org.apache.activemq.openwire.OpenWireUtil; + import org.apache.activemq.util.ByteSequence; + + public abstract class BaseDataStreamMarshaller implements DataStreamMarshaller { +@@ -228,8 +229,11 @@ public abstract class BaseDataStreamMars + private Throwable createThrowable(String className, String message) { + try { + Class clazz = Class.forName(className, false, BaseDataStreamMarshaller.class.getClassLoader()); ++ OpenWireUtil.validateIsThrowable(clazz); + Constructor constructor = clazz.getConstructor(new Class[] {String.class}); + return (Throwable)constructor.newInstance(new Object[] {message}); ++ } catch (IllegalArgumentException e) { ++ return e; + } catch (Throwable e) { + return new Throwable(className + ": " + message); + } +Index: activemq/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v7/BaseDataStreamMarshaller.java +=================================================================== +--- activemq.orig/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v7/BaseDataStreamMarshaller.java ++++ activemq/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v7/BaseDataStreamMarshaller.java +@@ -24,6 +24,7 @@ import org.apache.activemq.command.DataS + import org.apache.activemq.openwire.BooleanStream; + import org.apache.activemq.openwire.DataStreamMarshaller; + import org.apache.activemq.openwire.OpenWireFormat; ++import org.apache.activemq.openwire.OpenWireUtil; + import org.apache.activemq.util.ByteSequence; + + public abstract class BaseDataStreamMarshaller implements DataStreamMarshaller { +@@ -227,8 +228,11 @@ public abstract class BaseDataStreamMars + private Throwable createThrowable(String className, String message) { + try { + Class clazz = Class.forName(className, false, BaseDataStreamMarshaller.class.getClassLoader()); ++ OpenWireUtil.validateIsThrowable(clazz); + Constructor constructor = clazz.getConstructor(new Class[] {String.class}); + return (Throwable)constructor.newInstance(new Object[] {message}); ++ } catch (IllegalArgumentException e) { ++ return e; + } catch (Throwable e) { + return new Throwable(className + ": " + message); + } +Index: activemq/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v8/BaseDataStreamMarshaller.java +=================================================================== +--- activemq.orig/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v8/BaseDataStreamMarshaller.java ++++ activemq/activemq-openwire-legacy/src/main/java/org/apache/activemq/openwire/v8/BaseDataStreamMarshaller.java +@@ -24,6 +24,7 @@ import org.apache.activemq.command.DataS + import org.apache.activemq.openwire.BooleanStream; + import org.apache.activemq.openwire.DataStreamMarshaller; + import org.apache.activemq.openwire.OpenWireFormat; ++import org.apache.activemq.openwire.OpenWireUtil; + import org.apache.activemq.util.ByteSequence; + + public abstract class BaseDataStreamMarshaller implements DataStreamMarshaller { +@@ -227,8 +228,11 @@ public abstract class BaseDataStreamMars + private Throwable createThrowable(String className, String message) { + try { + Class clazz = Class.forName(className, false, BaseDataStreamMarshaller.class.getClassLoader()); ++ OpenWireUtil.validateIsThrowable(clazz); + Constructor constructor = clazz.getConstructor(new Class[] {String.class}); + return (Throwable)constructor.newInstance(new Object[] {message}); ++ } catch (IllegalArgumentException e) { ++ return e; + } catch (Throwable e) { + return new Throwable(className + ": " + message); + } +Index: activemq/activemq-openwire-legacy/src/test/java/org/apache/activemq/openwire/OpenWireLegacyValidationTest.java +=================================================================== +--- /dev/null ++++ activemq/activemq-openwire-legacy/src/test/java/org/apache/activemq/openwire/OpenWireLegacyValidationTest.java +@@ -0,0 +1,129 @@ ++/** ++ * Licensed to the Apache Software Foundation (ASF) under one or more ++ * contributor license agreements. See the NOTICE file distributed with ++ * this work for additional information regarding copyright ownership. ++ * The ASF licenses this file to You under the Apache License, Version 2.0 ++ * (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++package org.apache.activemq.openwire; ++ ++import java.io.DataOutput; ++import java.io.IOException; ++import java.util.ArrayList; ++import java.util.Collection; ++import java.util.List; ++import org.junit.runner.RunWith; ++import org.junit.runners.Parameterized; ++import org.junit.runners.Parameterized.Parameters; ++ ++/** ++ * Test that Openwire marshalling for legacy versions will validate Throwable types during ++ * unmarshalling commands that contain a Throwable ++ */ ++@RunWith(Parameterized.class) ++public class OpenWireLegacyValidationTest extends OpenWireValidationTest { ++ ++ ++ // Run through version 2 - 8 which are legacy ++ @Parameters(name = "version={0}") ++ public static Collection data() { ++ List versions = new ArrayList<>(); ++ for (int i = 2; i <= 8; i++) { ++ versions.add(new Object[]{i}); ++ } ++ return versions; ++ } ++ ++ public OpenWireLegacyValidationTest(int version) { ++ super(version); ++ } ++ ++ // Create test marshallers for all legacy versions that will encode NotAThrowable ++ // instead of the exception type for testing purposes ++ protected DataStreamMarshaller getExceptionMarshaller() { ++ switch (version) { ++ case 2: ++ return new org.apache.activemq.openwire.v2.ExceptionResponseMarshaller() { ++ @Override ++ protected void looseMarshalThrowable(OpenWireFormat wireFormat, Throwable o, ++ DataOutput dataOut) throws IOException { ++ dataOut.writeBoolean(o != null); ++ looseMarshalString(NotAThrowable.class.getName(), dataOut); ++ looseMarshalString(o.getMessage(), dataOut); ++ } ++ }; ++ case 3: ++ return new org.apache.activemq.openwire.v3.ExceptionResponseMarshaller() { ++ @Override ++ protected void looseMarshalThrowable(OpenWireFormat wireFormat, Throwable o, ++ DataOutput dataOut) throws IOException { ++ dataOut.writeBoolean(o != null); ++ looseMarshalString(NotAThrowable.class.getName(), dataOut); ++ looseMarshalString(o.getMessage(), dataOut); ++ } ++ }; ++ case 4: ++ return new org.apache.activemq.openwire.v4.ExceptionResponseMarshaller() { ++ @Override ++ protected void looseMarshalThrowable(OpenWireFormat wireFormat, Throwable o, ++ DataOutput dataOut) throws IOException { ++ dataOut.writeBoolean(o != null); ++ looseMarshalString(NotAThrowable.class.getName(), dataOut); ++ looseMarshalString(o.getMessage(), dataOut); ++ } ++ }; ++ case 5: ++ return new org.apache.activemq.openwire.v5.ExceptionResponseMarshaller() { ++ @Override ++ protected void looseMarshalThrowable(OpenWireFormat wireFormat, Throwable o, ++ DataOutput dataOut) throws IOException { ++ dataOut.writeBoolean(o != null); ++ looseMarshalString(NotAThrowable.class.getName(), dataOut); ++ looseMarshalString(o.getMessage(), dataOut); ++ } ++ }; ++ case 6: ++ return new org.apache.activemq.openwire.v6.ExceptionResponseMarshaller() { ++ @Override ++ protected void looseMarshalThrowable(OpenWireFormat wireFormat, Throwable o, ++ DataOutput dataOut) throws IOException { ++ dataOut.writeBoolean(o != null); ++ looseMarshalString(NotAThrowable.class.getName(), dataOut); ++ looseMarshalString(o.getMessage(), dataOut); ++ } ++ }; ++ case 7: ++ return new org.apache.activemq.openwire.v7.ExceptionResponseMarshaller() { ++ @Override ++ protected void looseMarshalThrowable(OpenWireFormat wireFormat, Throwable o, ++ DataOutput dataOut) throws IOException { ++ dataOut.writeBoolean(o != null); ++ looseMarshalString(NotAThrowable.class.getName(), dataOut); ++ looseMarshalString(o.getMessage(), dataOut); ++ } ++ }; ++ case 8: ++ return new org.apache.activemq.openwire.v8.ExceptionResponseMarshaller() { ++ @Override ++ protected void looseMarshalThrowable(OpenWireFormat wireFormat, Throwable o, ++ DataOutput dataOut) throws IOException { ++ dataOut.writeBoolean(o != null); ++ looseMarshalString(NotAThrowable.class.getName(), dataOut); ++ looseMarshalString(o.getMessage(), dataOut); ++ } ++ }; ++ default: ++ throw new IllegalArgumentException("Unknown openwire version of " + version); ++ } ++ } ++ ++} +Index: activemq/pom.xml +=================================================================== +--- activemq.orig/pom.xml ++++ activemq/pom.xml +@@ -300,6 +300,13 @@ + + + org.apache.activemq ++ activemq-client ++ ${project.version} ++ test-jar ++ test ++ ++ ++ org.apache.activemq + activemq-openwire-legacy + ${project.version} + diff -Nru activemq-5.17.2+dfsg/debian/patches/series activemq-5.17.2+dfsg/debian/patches/series --- activemq-5.17.2+dfsg/debian/patches/series 2023-02-12 15:53:03.000000000 +0000 +++ activemq-5.17.2+dfsg/debian/patches/series 2024-10-24 02:20:32.000000000 +0000 @@ -5,3 +5,5 @@ java11.patch enable-activemq-jdbc-store-module.patch mising-dependency-in-stomp-pom.patch +0001-AMQ-9370-Openwire-marshaller-should-validate-Throwab.patch +0001-AMQ-9201-Update-Jolokia-default-access-configuration.patch