[Git][java-team/apache-log4j1.2][master] 11 commits: Mitigate the impact of CVE-2022-23302 CVE-2022-23305 CVE-2022-23307

Markus Koschany (@apo) gitlab at salsa.debian.org
Mon Jan 31 10:51:10 GMT 2022



Markus Koschany pushed to branch master at Debian Java Maintainers / apache-log4j1.2


Commits:
e2a5a6ac by Markus Koschany at 2022-01-30T22:32:35+01:00
Mitigate the impact of CVE-2022-23302 CVE-2022-23305 CVE-2022-23307

- - - - -
30d8e2a9 by Markus Koschany at 2022-01-30T22:36:09+01:00
Mitigate against CVE-2021-4104

- - - - -
2fe693e9 by Markus Koschany at 2022-01-31T10:35:06+01:00
Revert "Mitigate against CVE-2021-4104"

This reverts commit 30d8e2a9c61c27323273639d5945087500b18503.

- - - - -
b9b7e74a by Markus Koschany at 2022-01-31T10:35:18+01:00
Revert "Mitigate the impact of CVE-2022-23302 CVE-2022-23305 CVE-2022-23307"

This reverts commit e2a5a6ac82c8d848790b4c84b25280fa41700499.

- - - - -
4a12a82d by Markus Koschany at 2022-01-31T11:27:53+01:00
Fix CVE-2021-4104 and CVE-2022-23305

- - - - -
0316ea5e by Markus Koschany at 2022-01-31T11:39:33+01:00
Fix CVE-2022-23302 and CVE-2022-23307

- - - - -
b70b897b by Markus Koschany at 2022-01-31T11:39:55+01:00
Declare compliance with Debian Policy 4.6.0.

- - - - -
01f42865 by Markus Koschany at 2022-01-31T11:41:34+01:00
Update changelog

- - - - -
8bf15e32 by Markus Koschany at 2022-01-31T11:45:27+01:00
Rename README.Debian-source to README.source

- - - - -
fcadf171 by Markus Koschany at 2022-01-31T11:46:53+01:00
Update README.source and mention reload4j project

- - - - -
430143f9 by Markus Koschany at 2022-01-31T11:49:05+01:00
Really apply the patches

- - - - -


8 changed files:

- debian/README.Debian-source → debian/README.source
- debian/changelog
- debian/control
- + debian/patches/CVE-2021-4104.patch
- + debian/patches/CVE-2022-23302.patch
- + debian/patches/CVE-2022-23305.patch
- + debian/patches/CVE-2022-23307.patch
- debian/patches/series


Changes:

=====================================
debian/README.Debian-source → debian/README.source
=====================================
@@ -6,3 +6,9 @@ included in the original tarball. The orig-tar.sh in this directory is
 used to recreate a clean tarball by removing the jar and DLL.
 
  -- Kumar Appaiah <akumar at ee.iitm.ac.in>, Wed, 26 Sep 2007 13:03:52 +0530
+
+
+log4j1.2 has been officially EOL since August 2015. Security patches were taken
+from the forked reload4j project at
+
+https://github.com/qos-ch/reload4j


=====================================
debian/changelog
=====================================
@@ -1,3 +1,12 @@
+apache-log4j1.2 (1.2.17-11) unstable; urgency=high
+
+  * Team upload.
+  * Fix CVE-2021-4104, CVE-2022-23305, CVE-2022-23302 and CVE-2022-23307..
+    (Closes: #1004482)
+  * Declare compliance with Debian Policy 4.6.0.
+
+ -- Markus Koschany <apo at debian.org>  Mon, 31 Jan 2022 11:40:47 +0100
+
 apache-log4j1.2 (1.2.17-10) unstable; urgency=medium
 
   * No longer build the examples to fix the build failure with OpenJDK 17


=====================================
debian/control
=====================================
@@ -16,7 +16,7 @@ Build-Depends:
  default-jdk-doc,
  libmail-java,
  maven-repo-helper
-Standards-Version: 4.5.1
+Standards-Version: 4.6.0
 Vcs-Git: https://salsa.debian.org/java-team/apache-log4j1.2.git
 Vcs-Browser: https://salsa.debian.org/java-team/apache-log4j1.2
 Homepage: http://logging.apache.org/log4j/1.2/


=====================================
debian/patches/CVE-2021-4104.patch
=====================================
@@ -0,0 +1,166 @@
+From: Markus Koschany <apo at debian.org>
+Date: Mon, 31 Jan 2022 11:18:33 +0100
+Subject: CVE-2021-4104
+
+Origin: https://github.com/qos-ch/reload4j/commit/fb7b1ff1c8beb8544933248d00a46e9e30547e87
+Origin: https://github.com/qos-ch/reload4j/commit/e65c98bbba48cb877e057992847114f1f0923da6
+---
+ .../java/org/apache/log4j/net/JMSAppender.java     | 11 ++---
+ src/main/java/org/apache/log4j/net/JNDIUtil.java   | 54 +++++++++++++++++++++
+ .../java/org/apache/log4j/net/JNDIUtilTest.java    | 55 ++++++++++++++++++++++
+ 3 files changed, 114 insertions(+), 6 deletions(-)
+ create mode 100755 src/main/java/org/apache/log4j/net/JNDIUtil.java
+ create mode 100755 src/test/java/org/apache/log4j/net/JNDIUtilTest.java
+
+diff --git a/src/main/java/org/apache/log4j/net/JMSAppender.java b/src/main/java/org/apache/log4j/net/JMSAppender.java
+index 3482702..c390aef 100644
+--- a/src/main/java/org/apache/log4j/net/JMSAppender.java
++++ b/src/main/java/org/apache/log4j/net/JMSAppender.java
+@@ -32,7 +32,6 @@ import javax.jms.TopicPublisher;
+ import javax.jms.TopicSession;
+ import javax.naming.Context;
+ import javax.naming.InitialContext;
+-import javax.naming.NameNotFoundException;
+ import javax.naming.NamingException;
+ import java.util.Properties;
+ 
+@@ -241,12 +240,12 @@ public class JMSAppender extends AppenderSkeleton {
+   }
+ 
+   protected Object lookup(Context ctx, String name) throws NamingException {
+-    try {
+-      return ctx.lookup(name);
+-    } catch(NameNotFoundException e) {
+-      LogLog.error("Could not find name ["+name+"].");
+-      throw e;
++    Object result = JNDIUtil.lookupObject(ctx, name);
++        if (result == null) {
++            String msg = "Could not find name [" + name + "].";
++            throw new NamingException(msg);
+     }
++    return result;
+   }
+ 
+   protected boolean checkEntryConditions() {
+diff --git a/src/main/java/org/apache/log4j/net/JNDIUtil.java b/src/main/java/org/apache/log4j/net/JNDIUtil.java
+new file mode 100755
+index 0000000..3a66a05
+--- /dev/null
++++ b/src/main/java/org/apache/log4j/net/JNDIUtil.java
+@@ -0,0 +1,54 @@
++/*
++ * 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.log4j.net;
++
++import javax.naming.Context;
++import javax.naming.NamingException;
++
++public class JNDIUtil {
++
++	// See https://jakarta.ee/specifications/platform/8/platform-spec-8.html#a616
++	// there are the java:comp, java:module, java:app, java:global namespaces
++	public static final String JNDI_JAVA_NAMESPACE = "java:";
++
++	static final String RESTRICTION_MSG = "JNDI name must start with " + JNDI_JAVA_NAMESPACE + " but was ";
++
++	public static Object lookupObject(Context ctx, String name) throws NamingException {
++		if (ctx == null) {
++			return null;
++		}
++
++		if (isNullOrEmpty(name)) {
++			return null;
++		}
++
++		jndiNameSecurityCheck(name);
++
++		Object lookup = ctx.lookup(name);
++		return lookup;
++	}
++
++	private static boolean isNullOrEmpty(String str) {
++		return ((str == null) || str.trim().length() == 0);
++	}
++
++	public static void jndiNameSecurityCheck(String name) throws NamingException {
++		if (!name.startsWith(JNDI_JAVA_NAMESPACE)) {
++			throw new NamingException(RESTRICTION_MSG + name);
++		}
++	}
++}
+diff --git a/src/test/java/org/apache/log4j/net/JNDIUtilTest.java b/src/test/java/org/apache/log4j/net/JNDIUtilTest.java
+new file mode 100755
+index 0000000..2439bc7
+--- /dev/null
++++ b/src/test/java/org/apache/log4j/net/JNDIUtilTest.java
+@@ -0,0 +1,55 @@
++/*
++ * 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.log4j.net;
++
++import static org.junit.Assert.fail;
++
++import javax.naming.Context;
++import javax.naming.InitialContext;
++import javax.naming.NamingException;
++
++import org.junit.Test;
++
++
++/**
++ * Test copied form the logback project with permission.
++ * 
++ * @author Ceki Gulcu
++ *
++ */
++public class JNDIUtilTest {
++
++	@Test
++	public void ensureJavaNameSpace() throws NamingException {
++
++		try {
++			Context ctxt = new InitialContext();
++			JNDIUtil.lookupObject(ctxt, "ldap:...");
++		} catch (NamingException e) {
++			String excaptionMsg = e.getMessage();
++			if (excaptionMsg.startsWith(JNDIUtil.RESTRICTION_MSG))
++				return;
++			else {
++				fail("unexpected exception " + e);
++			}
++		}
++
++		fail("Should aNot yet implemented");
++	}
++
++
++}
+\ No newline at end of file


=====================================
debian/patches/CVE-2022-23302.patch
=====================================
@@ -0,0 +1,48 @@
+From: Markus Koschany <apo at debian.org>
+Date: Mon, 31 Jan 2022 11:30:35 +0100
+Subject: CVE-2022-23302
+
+Origin: https://github.com/qos-ch/reload4j/commit/f221f2427c45134cf5768f46279ddf72fe1407c9
+---
+ src/main/java/org/apache/log4j/net/JMSSink.java | 14 ++------------
+ 1 file changed, 2 insertions(+), 12 deletions(-)
+
+diff --git a/src/main/java/org/apache/log4j/net/JMSSink.java b/src/main/java/org/apache/log4j/net/JMSSink.java
+index 6a02831..c25b4a3 100644
+--- a/src/main/java/org/apache/log4j/net/JMSSink.java
++++ b/src/main/java/org/apache/log4j/net/JMSSink.java
+@@ -88,8 +88,7 @@ public class JMSSink implements javax.jms.MessageListener {
+     try {
+       Context ctx = new InitialContext();
+       TopicConnectionFactory topicConnectionFactory;
+-      topicConnectionFactory = (TopicConnectionFactory) lookup(ctx,
+-                                                               tcfBindingName);
++      topicConnectionFactory = (TopicConnectionFactory) JNDIUtil.lookupObject(ctx, tcfBindingName);
+ 
+       TopicConnection topicConnection =
+ 	                        topicConnectionFactory.createTopicConnection(username,
+@@ -99,7 +98,7 @@ public class JMSSink implements javax.jms.MessageListener {
+       TopicSession topicSession = topicConnection.createTopicSession(false,
+                                                        Session.AUTO_ACKNOWLEDGE);
+ 
+-      Topic topic = (Topic)ctx.lookup(topicBindingName);
++      Topic topic = (Topic) JNDIUtil.lookupObject(ctx, topicBindingName);
+ 
+       TopicSubscriber topicSubscriber = topicSession.createSubscriber(topic);
+     
+@@ -135,15 +134,6 @@ public class JMSSink implements javax.jms.MessageListener {
+   }
+ 
+ 
+-  protected static Object lookup(Context ctx, String name) throws NamingException {
+-    try {
+-      return ctx.lookup(name);
+-    } catch(NameNotFoundException e) {
+-      logger.error("Could not find name ["+name+"].");
+-      throw e;
+-    }
+-  }
+-
+   static void usage(String msg) {
+     System.err.println(msg);
+     System.err.println("Usage: java " + JMSSink.class.getName()


=====================================
debian/patches/CVE-2022-23305.patch
=====================================
@@ -0,0 +1,631 @@
+From: Markus Koschany <apo at debian.org>
+Date: Mon, 31 Jan 2022 10:55:04 +0100
+Subject: CVE-2022-23305
+
+Origin: https://github.com/qos-ch/reload4j/pull/26/commits/33d1697bb13b8cf869c450a64f8550b1593f8035
+---
+ pom.xml                                            |   6 +
+ .../java/org/apache/log4j/jdbc/JDBCAppender.java   |  97 ++++++++--
+ .../org/apache/log4j/jdbc/JdbcPatternParser.java   | 101 ++++++++++
+ src/test/input/jdbc_h2_bufferSize1.properties      |  25 +++
+ src/test/input/jdbc_h2_bufferSize2.properties      |  25 +++
+ .../org/apache/log4j/jdbc/JdbcAppenderTest.java    | 208 +++++++++++++++++++++
+ .../apache/log4j/jdbc/JdbcPatternParserTest.java   |  50 +++++
+ 7 files changed, 495 insertions(+), 17 deletions(-)
+ create mode 100644 src/main/java/org/apache/log4j/jdbc/JdbcPatternParser.java
+ create mode 100644 src/test/input/jdbc_h2_bufferSize1.properties
+ create mode 100644 src/test/input/jdbc_h2_bufferSize2.properties
+ create mode 100644 src/test/java/org/apache/log4j/jdbc/JdbcAppenderTest.java
+ create mode 100644 src/test/java/org/apache/log4j/jdbc/JdbcPatternParserTest.java
+
+diff --git a/pom.xml b/pom.xml
+index 93881cd..3ec2ccc 100644
+--- a/pom.xml
++++ b/pom.xml
+@@ -577,6 +577,12 @@ target platform and specify -Dntdll_target=msbuild on the mvn command line.
+       <version>1.0</version>
+       <optional>true</optional>
+     </dependency>
++     <dependency>
++      <groupId>com.h2database</groupId>
++      <artifactId>h2</artifactId>
++      <version>2.1.210</version>
++      <scope>test</scope>
++    </dependency>
+  </dependencies>
+   <distributionManagement>
+     <repository>
+diff --git a/src/main/java/org/apache/log4j/jdbc/JDBCAppender.java b/src/main/java/org/apache/log4j/jdbc/JDBCAppender.java
+index ad35f65..2f979ae 100644
+--- a/src/main/java/org/apache/log4j/jdbc/JDBCAppender.java
++++ b/src/main/java/org/apache/log4j/jdbc/JDBCAppender.java
+@@ -18,6 +18,7 @@ package org.apache.log4j.jdbc;
+ 
+ import java.sql.Connection;
+ import java.sql.DriverManager;
++import java.sql.PreparedStatement;
+ import java.sql.SQLException;
+ import java.sql.Statement;
+ import java.util.ArrayList;
+@@ -78,6 +79,12 @@ import org.apache.log4j.spi.LoggingEvent;
+ public class JDBCAppender extends org.apache.log4j.AppenderSkeleton
+     implements org.apache.log4j.Appender {
+ 
++    private final Boolean secureSqlReplacement =
++        Boolean.parseBoolean(System.getProperty("org.apache.log4j.jdbc.JDBCAppender.secure_jdbc_replacement", "true"));
++
++    private static final IllegalArgumentException ILLEGAL_PATTERN_FOR_SECURE_EXEC =
++        new IllegalArgumentException("Only org.apache.log4j.PatternLayout is supported for now due to CVE-2022-23305");
++
+   /**
+    * URL of the DB for default connection handling
+    */
+@@ -113,6 +120,8 @@ public class JDBCAppender extends org.apache.log4j.AppenderSkeleton
+    */
+   protected String sqlStatement = "";
+ 
++  private JdbcPatternParser preparedStatementParser = new JdbcPatternParser();
++
+   /**
+    * size of LoggingEvent buffer before writting to the database.
+    * Default is 1.
+@@ -245,11 +254,11 @@ public class JDBCAppender extends org.apache.log4j.AppenderSkeleton
+    */
+   protected Connection getConnection() throws SQLException {
+       if (!DriverManager.getDrivers().hasMoreElements())
+-	     setDriver("sun.jdbc.odbc.JdbcOdbcDriver");
++         setDriver("sun.jdbc.odbc.JdbcOdbcDriver");
+ 
+       if (connection == null) {
+         connection = DriverManager.getConnection(databaseURL, databaseUser,
+-					databasePassword);
++                    databasePassword);
+       }
+ 
+       return connection;
+@@ -280,29 +289,83 @@ public class JDBCAppender extends org.apache.log4j.AppenderSkeleton
+    * If a statement fails the LoggingEvent stays in the buffer!
+    */
+   public void flushBuffer() {
++        if (buffer.isEmpty()) {
++            return;
++        }
+     //Do the actual logging
+     removes.ensureCapacity(buffer.size());
+-    for (Iterator i = buffer.iterator(); i.hasNext();) {
+-      LoggingEvent logEvent = (LoggingEvent)i.next();
+-      try {
+-	    String sql = getLogStatement(logEvent);
+-	    execute(sql);
+-      }
+-      catch (SQLException e) {
+-	    errorHandler.error("Failed to excute sql", e,
+-			   ErrorCode.FLUSH_FAILURE);
+-      } finally {
+-        removes.add(logEvent);
+-      }
++    if (secureSqlReplacement) {
++         flushBufferSecure();
++    } else {
++         flushBufferInsecure();
+     }
+-    
+     // remove from the buffer any events that were reported
+     buffer.removeAll(removes);
+-    
++
+     // clear the buffer of reported events
+     removes.clear();
+   }
+ 
++    private void flushBufferInsecure() {
++        for (Iterator i = buffer.iterator(); i.hasNext(); ) {
++            LoggingEvent logEvent = (LoggingEvent) i.next();
++            try {
++                String sql = getLogStatement(logEvent);
++                execute(sql);
++            } catch (SQLException e) {
++                errorHandler.error("Failed to excute sql", e, ErrorCode.FLUSH_FAILURE);
++            } finally {
++                removes.add(logEvent);
++            }
++        }
++    }
++
++    private void flushBufferSecure() {
++        // Prepare events that we will store to the DB
++        removes.addAll(buffer);
++
++        if (layout.getClass() != PatternLayout.class) {
++            errorHandler.error("Failed to convert pattern " + layout + " to SQL", ILLEGAL_PATTERN_FOR_SECURE_EXEC, ErrorCode.MISSING_LAYOUT);
++            return;
++        }
++        PatternLayout patternLayout = (PatternLayout) layout;
++        preparedStatementParser.setPattern(patternLayout.getConversionPattern());
++        Connection con = null;
++        boolean useBatch = removes.size() > 1;
++        try {
++            con = getConnection();
++            PreparedStatement ps = con.prepareStatement(preparedStatementParser.getParameterizedSql());
++            try {
++                for (Iterator i = removes.iterator(); i.hasNext(); ) {
++                    LoggingEvent logEvent = (LoggingEvent) i.next();
++                    try {
++                        preparedStatementParser.setParameters(ps, logEvent);
++                        if (useBatch) {
++                            ps.addBatch();
++                        }
++                    } catch (SQLException e) {
++                        errorHandler.error("Failed to append parameters", e, ErrorCode.FLUSH_FAILURE);
++                    }
++                }
++                if (useBatch) {
++                    ps.executeBatch();
++                } else {
++                    ps.execute();
++                }
++            } finally {
++                try {
++                    ps.close();
++                } catch (SQLException ignored) {
++                }
++            }
++        } catch (SQLException e) {
++            errorHandler.error("Failed to append messages sql", e, ErrorCode.FLUSH_FAILURE);
++        } finally {
++            if (con != null) {
++                closeConnection(con);
++            }
++        }
++    }
+ 
+   /** closes the appender before disposal */
+   public void finalize() {
+@@ -391,7 +454,7 @@ public class JDBCAppender extends org.apache.log4j.AppenderSkeleton
+       Class.forName(driverClass);
+     } catch (Exception e) {
+       errorHandler.error("Failed to load driver", e,
+-			 ErrorCode.GENERIC_FAILURE);
++             ErrorCode.GENERIC_FAILURE);
+     }
+   }
+ }
+diff --git a/src/main/java/org/apache/log4j/jdbc/JdbcPatternParser.java b/src/main/java/org/apache/log4j/jdbc/JdbcPatternParser.java
+new file mode 100644
+index 0000000..691ed56
+--- /dev/null
++++ b/src/main/java/org/apache/log4j/jdbc/JdbcPatternParser.java
+@@ -0,0 +1,101 @@
++/*
++ * 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.log4j.jdbc;
++
++import org.apache.log4j.helpers.PatternConverter;
++import org.apache.log4j.helpers.PatternParser;
++import org.apache.log4j.spi.LoggingEvent;
++
++import java.sql.PreparedStatement;
++import java.sql.SQLException;
++import java.util.ArrayList;
++import java.util.List;
++import java.util.regex.Matcher;
++import java.util.regex.Pattern;
++
++class JdbcPatternParser {
++    private final static Pattern STRING_LITERAL_PATTERN = Pattern.compile("'((?>[^']|'')+)'");
++
++    private String lastPattern;
++    private String parameterizedSql;
++    private final List<String> argPatterns = new ArrayList<String>();
++    private final List<PatternConverter> args = new ArrayList<PatternConverter>();
++    private StringBuffer buffer = new StringBuffer();
++
++    public String getParameterizedSql() {
++        return parameterizedSql;
++    }
++
++    @Override
++    public String toString() {
++        return "JdbcPatternParser{sql=" + parameterizedSql + ",args=" + argPatterns + "}";
++    }
++
++    /**
++     * Converts '....' literals into bind variables in JDBC.
++     */
++    void setPattern(String pattern) {
++        if (pattern == null) {
++            throw new IllegalArgumentException("Null pattern");
++        }
++        if (pattern.equals(lastPattern)) {
++            return;
++        }
++        Matcher m = STRING_LITERAL_PATTERN.matcher(pattern);
++        StringBuffer sb = new StringBuffer();
++        args.clear();
++        argPatterns.clear();
++        while (m.find()) {
++            String literal = m.group(1);
++            if (literal.indexOf('%') == -1) {
++                // Just literal, append it as is
++                // It can't contain user-provided parts like %m, etc.
++                m.appendReplacement(sb, "'$1'");
++                continue;
++            }
++
++            // Replace with bind
++            m.appendReplacement(sb, "?");
++            // We will use prepared statements, so we don't need to escape quotes.
++            // And we assume the users had 'That''s a string with quotes' in their configs.
++            literal = literal.replaceAll("''", "'");
++            argPatterns.add(literal);
++            args.add(new PatternParser(literal).parse());
++        }
++        m.appendTail(sb);
++        parameterizedSql = sb.toString();
++        lastPattern = pattern;
++    }
++
++    public void setParameters(PreparedStatement ps, LoggingEvent logEvent) throws SQLException {
++        for (int i = 0; i < args.size(); i++) {
++            buffer.setLength(0);
++            PatternConverter c = args.get(i);
++            while (c != null) {
++                c.format(buffer, logEvent);
++                c = c.next;
++            }
++            ps.setString(i + 1, buffer.toString());
++        }
++        // This clears "toString cache"
++        buffer.setLength(0);
++        if (buffer.capacity() > 100000) {
++            // Avoid leaking too much memory if we discover long parameter
++            buffer = new StringBuffer();
++        }
++    }
++}
+diff --git a/src/test/input/jdbc_h2_bufferSize1.properties b/src/test/input/jdbc_h2_bufferSize1.properties
+new file mode 100644
+index 0000000..77e6083
+--- /dev/null
++++ b/src/test/input/jdbc_h2_bufferSize1.properties
+@@ -0,0 +1,25 @@
++# 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.
++
++log4j.threshold=ALL
++log4j.rootLogger=ALL,A
++log4j.appender.A=org.apache.log4j.jdbc.JDBCAppender
++log4j.appender.A.URL=jdbc:h2:mem:test_db
++log4j.appender.A.driver=org.h2.Driver
++log4j.appender.A.bufferSize=1
++log4j.appender.A.user=
++log4j.appender.A.password=
++log4j.appender.A.layout=org.apache.log4j.PatternLayout
++log4j.appender.A.sql=insert into logs(level,location,message,message2) values('%p','%c','%m', ' %c %p %m')
+diff --git a/src/test/input/jdbc_h2_bufferSize2.properties b/src/test/input/jdbc_h2_bufferSize2.properties
+new file mode 100644
+index 0000000..fba02a3
+--- /dev/null
++++ b/src/test/input/jdbc_h2_bufferSize2.properties
+@@ -0,0 +1,25 @@
++# 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.
++
++log4j.threshold=ALL
++log4j.rootLogger=ALL,A
++log4j.appender.A=org.apache.log4j.jdbc.JDBCAppender
++log4j.appender.A.URL=jdbc:h2:mem:test_db
++log4j.appender.A.driver=org.h2.Driver
++log4j.appender.A.bufferSize=2
++log4j.appender.A.user=
++log4j.appender.A.password=
++log4j.appender.A.layout=org.apache.log4j.PatternLayout
++log4j.appender.A.sql=insert into logs(level,location,message,message2) values('%p','%c','%m', ' %c %p %m')
+diff --git a/src/test/java/org/apache/log4j/jdbc/JdbcAppenderTest.java b/src/test/java/org/apache/log4j/jdbc/JdbcAppenderTest.java
+new file mode 100644
+index 0000000..f851063
+--- /dev/null
++++ b/src/test/java/org/apache/log4j/jdbc/JdbcAppenderTest.java
+@@ -0,0 +1,208 @@
++/*
++ * 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.log4j.jdbc;
++
++import org.apache.log4j.Appender;
++import org.apache.log4j.LogManager;
++import org.apache.log4j.Logger;
++import org.apache.log4j.PropertyConfigurator;
++import org.apache.log4j.TestContants;
++import org.apache.log4j.VectorErrorHandler;
++import org.apache.log4j.xml.XLevel;
++import org.junit.After;
++import org.junit.Assert;
++import org.junit.Before;
++import org.junit.Test;
++
++import java.sql.Connection;
++import java.sql.DriverManager;
++import java.sql.PreparedStatement;
++import java.sql.ResultSet;
++import java.sql.SQLException;
++import java.sql.Statement;
++import java.util.ArrayList;
++import java.util.Collections;
++import java.util.List;
++
++public class JdbcAppenderTest {
++    // Closing the last connection to "in-memory h2" removes the database
++    // So we keep the connection during the test
++    // The logger opens its own connection
++    Connection con;
++
++    @Before
++    public void setup() throws SQLException {
++        con = DriverManager.getConnection("jdbc:h2:mem:test_db");
++        Statement st = con.createStatement();
++        try {
++            st.execute("create table logs(level varchar(100),location varchar(100),message varchar(100),message2 varchar(100))");
++        } finally {
++            st.close();
++        }
++    }
++
++    @After
++    public void cleanup() throws SQLException {
++        LogManager.shutdown();
++        con.close();
++    }
++
++    @Test
++    public void verifyJdbcInsecure() throws SQLException {
++        String secureJdbcReplacement = "org.apache.log4j.jdbc.JDBCAppender.secure_jdbc_replacement";
++        System.setProperty(secureJdbcReplacement, "false");
++        try {
++            PropertyConfigurator.configure(TestContants.TEST_INPUT_PREFIX + "jdbc_h2_bufferSize1.properties");
++            Appender jdbcAppender = LogManager.getRootLogger().getAppender("A");
++            // Keep errors
++            VectorErrorHandler errorHandler = new VectorErrorHandler();
++            jdbcAppender.setErrorHandler(errorHandler);
++
++            Logger logger = Logger.getLogger(JdbcAppenderTest.class);
++
++            String oldThreadName = Thread.currentThread().getName();
++            try {
++                Thread.currentThread().setName("main");
++                logger.debug("message with '' quote");
++                Assert.assertEquals(
++                        "batchSize=1, so messages should be added immediately",
++                        "DEBUG; org.apache.log4j.jdbc.JdbcAppenderTest; message with ' quote;  org.apache.log4j.jdbc.JdbcAppenderTest DEBUG message with ' quote\n",
++                        joinSorted(getMessages()));
++
++                // It should fail
++                logger.fatal("message with ' quote");
++
++                Assert.assertEquals(
++                        "Inserting a message with ' should cause failure in insecure mode, so only one message should be in the DB",
++                        "DEBUG; org.apache.log4j.jdbc.JdbcAppenderTest; message with ' quote;  org.apache.log4j.jdbc.JdbcAppenderTest DEBUG message with ' quote\n",
++                        joinSorted(getMessages()));
++
++                StringBuilder exceptions = new StringBuilder();
++                StringBuilder errorCodes = new StringBuilder();
++                for (int i = 0; i < errorHandler.size(); i++) {
++                    Exception ex = errorHandler.getException(i);
++                    exceptions.append(ex.toString());
++                    errorCodes.append(
++                            ex instanceof SQLException
++                                    ? ("SQLException.getErrorCode() = " + ((SQLException) ex).getErrorCode())
++                                    : ("SQL Exception expected, got " + ex.getClass()));
++                    exceptions.append('\n');
++                    errorCodes.append('\n');
++                }
++                Assert.assertEquals(
++                        "Logging a message with ' should trigger SQLException 'Syntax error in SQL statement...' when using insecure JDBCAppender mode, actual exceptions are\n" + exceptions,
++                        "SQLException.getErrorCode() = 42001\n",
++                        errorCodes.toString()
++                );
++            } finally {
++                Thread.currentThread().setName(oldThreadName);
++            }
++        } finally {
++            System.getProperties().remove(secureJdbcReplacement);
++        }
++    }
++
++    @Test
++    public void verifyJdbcBufferSize1() throws SQLException {
++        PropertyConfigurator.configure(TestContants.TEST_INPUT_PREFIX + "jdbc_h2_bufferSize1.properties");
++
++        Logger logger = Logger.getLogger(JdbcAppenderTest.class);
++
++        String oldThreadName = Thread.currentThread().getName();
++        try {
++            Thread.currentThread().setName("main");
++            logger.debug("message with ' quote");
++            Assert.assertEquals(
++                    "batchSize=1, so messages should be added immediately",
++                    "DEBUG; org.apache.log4j.jdbc.JdbcAppenderTest; message with ' quote;  org.apache.log4j.jdbc.JdbcAppenderTest DEBUG message with ' quote\n",
++                    joinSorted(getMessages()));
++
++            logger.fatal("message with \" quote");
++
++            Assert.assertEquals(
++                    "batchSize=1, so two messages should be in DB after two logging calls",
++                    "DEBUG; org.apache.log4j.jdbc.JdbcAppenderTest; message with ' quote;  org.apache.log4j.jdbc.JdbcAppenderTest DEBUG message with ' quote\n" +
++                            "FATAL; org.apache.log4j.jdbc.JdbcAppenderTest; message with \" quote;  org.apache.log4j.jdbc.JdbcAppenderTest FATAL message with \" quote\n",
++                    joinSorted(getMessages()));
++        } finally {
++            Thread.currentThread().setName(oldThreadName);
++        }
++    }
++
++    @Test
++    public void verifyJdbcBufferSize2() throws SQLException {
++        PropertyConfigurator.configure(TestContants.TEST_INPUT_PREFIX + "jdbc_h2_bufferSize2.properties");
++
++        Logger logger = Logger.getLogger(JdbcAppenderTest.class);
++
++        String oldThreadName = Thread.currentThread().getName();
++        try {
++            Thread.currentThread().setName("main");
++            logger.log(XLevel.TRACE, "xtrace message");
++            logger.debug("message with ' quote");
++            logger.info("message with \" quote");
++            logger.warn("?");
++            // bufferSize=2, so this message won't yet be stored to the db
++            logger.error("m4");
++
++            Assert.assertEquals(
++                    "DEBUG; org.apache.log4j.jdbc.JdbcAppenderTest; message with ' quote;  org.apache.log4j.jdbc.JdbcAppenderTest DEBUG message with ' quote\n" +
++                            "INFO; org.apache.log4j.jdbc.JdbcAppenderTest; message with \" quote;  org.apache.log4j.jdbc.JdbcAppenderTest INFO message with \" quote\n" +
++                            "TRACE; org.apache.log4j.jdbc.JdbcAppenderTest; xtrace message;  org.apache.log4j.jdbc.JdbcAppenderTest TRACE xtrace message\n" +
++                            "WARN; org.apache.log4j.jdbc.JdbcAppenderTest; ?;  org.apache.log4j.jdbc.JdbcAppenderTest WARN ?\n",
++                    joinSorted(getMessages()));
++
++            logger.fatal("m5");
++
++            Assert.assertEquals(
++                    "Logging m5 message should trigger buffer flush for both m4 and m5",
++                    "DEBUG; org.apache.log4j.jdbc.JdbcAppenderTest; message with ' quote;  org.apache.log4j.jdbc.JdbcAppenderTest DEBUG message with ' quote\n" +
++                            "ERROR; org.apache.log4j.jdbc.JdbcAppenderTest; m4;  org.apache.log4j.jdbc.JdbcAppenderTest ERROR m4\n" +
++                            "FATAL; org.apache.log4j.jdbc.JdbcAppenderTest; m5;  org.apache.log4j.jdbc.JdbcAppenderTest FATAL m5\n" +
++                            "INFO; org.apache.log4j.jdbc.JdbcAppenderTest; message with \" quote;  org.apache.log4j.jdbc.JdbcAppenderTest INFO message with \" quote\n" +
++                            "TRACE; org.apache.log4j.jdbc.JdbcAppenderTest; xtrace message;  org.apache.log4j.jdbc.JdbcAppenderTest TRACE xtrace message\n" +
++                            "WARN; org.apache.log4j.jdbc.JdbcAppenderTest; ?;  org.apache.log4j.jdbc.JdbcAppenderTest WARN ?\n",
++                    joinSorted(getMessages()));
++        } finally {
++            Thread.currentThread().setName(oldThreadName);
++        }
++    }
++
++    private static String joinSorted(List<String> list) {
++        Collections.sort(list);
++        StringBuilder sb = new StringBuilder();
++        for (String s : list) {
++            sb.append(s).append('\n');
++        }
++        return sb.toString();
++    }
++
++    private List<String> getMessages() throws SQLException {
++        List<String> res = new ArrayList<String>();
++        PreparedStatement ps = con.prepareStatement("select level,location,message,message2 from logs");
++        ResultSet rs = ps.executeQuery();
++        try {
++            while (rs.next()) {
++                res.add(rs.getString(1) + "; " + rs.getString(2)
++                        + "; " + rs.getString(3) + "; " + rs.getString(4));
++            }
++        } finally {
++            rs.close();
++        }
++        return res;
++    }
++}
+diff --git a/src/test/java/org/apache/log4j/jdbc/JdbcPatternParserTest.java b/src/test/java/org/apache/log4j/jdbc/JdbcPatternParserTest.java
+new file mode 100644
+index 0000000..aafbd80
+--- /dev/null
++++ b/src/test/java/org/apache/log4j/jdbc/JdbcPatternParserTest.java
+@@ -0,0 +1,50 @@
++/*
++ * 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.log4j.jdbc;
++
++import org.junit.Assert;
++import org.junit.Test;
++
++public class JdbcPatternParserTest {
++    JdbcPatternParser parser = new JdbcPatternParser();
++
++    @Test
++    public void testParameterizedSql() {
++        assertParameterizedSql(
++                "JdbcPatternParser{sql=INSERT INTO A1 (TITLE3) VALUES ( ? ),args=[ %d  -  %c %-5p %c %x  -  %m%n ]}",
++                "INSERT INTO A1 (TITLE3) VALUES ( ' %d  -  %c %-5p %c %x  -  %m%n ' )"
++        );
++        assertParameterizedSql(
++                "JdbcPatternParser{sql=INSERT INTO A1 (TITLE3) VALUES ( ?, ?, ?, ?,  ?, ? ),args=[%d, %c, %-5p,  '%c, %x,   -  %m%n ]}",
++                "INSERT INTO A1 (TITLE3) VALUES ( '%d', '%c', '%-5p', ' ''%c',  '%x', '  -  %m%n ' )"
++        );
++
++        assertParameterizedSql(
++                "JdbcPatternParser{sql=INSERT INTO A1 (TITLE3) VALUES ( ' just string literal', 'another literal with quotes '' asdf', ?),args=[message: %m]}",
++                "INSERT INTO A1 (TITLE3) VALUES ( ' just string literal', 'another literal with quotes '' asdf', 'message: %m')"
++        );
++    }
++
++    private void assertParameterizedSql(String expected, String input) {
++        parser.setPattern(input);
++        Assert.assertEquals(
++                "parser.setPattern(...).toString() for " + input,
++                expected,
++                parser.toString()
++        );
++    }
++}


=====================================
debian/patches/CVE-2022-23307.patch
=====================================
@@ -0,0 +1,343 @@
+From: Markus Koschany <apo at debian.org>
+Date: Mon, 31 Jan 2022 11:37:03 +0100
+Subject: CVE-2022-23307
+
+Origin: https://github.com/qos-ch/reload4j/commit/64902fe18ce5a5dd40487051a2f6231d9fbbe9b0
+---
+ .../org/apache/log4j/chainsaw/LoggingReceiver.java |  8 +-
+ .../log4j/net/HardenedLoggingEventInputStream.java | 56 +++++++++++++
+ .../log4j/net/HardenedObjectInputStream.java       | 93 +++++++++++++++++++++
+ src/test/input/xml/socketAppenderForChainsaw.xml   | 24 ++++++
+ .../org/apache/log4j/net/SocketAppenderTest.java   | 96 ++++++++++++++++++++++
+ 5 files changed, 273 insertions(+), 4 deletions(-)
+ create mode 100644 src/main/java/org/apache/log4j/net/HardenedLoggingEventInputStream.java
+ create mode 100644 src/main/java/org/apache/log4j/net/HardenedObjectInputStream.java
+ create mode 100644 src/test/input/xml/socketAppenderForChainsaw.xml
+ create mode 100644 src/test/java/org/apache/log4j/net/SocketAppenderTest.java
+
+diff --git a/src/main/java/org/apache/log4j/chainsaw/LoggingReceiver.java b/src/main/java/org/apache/log4j/chainsaw/LoggingReceiver.java
+index ca087ad..74ecc06 100644
+--- a/src/main/java/org/apache/log4j/chainsaw/LoggingReceiver.java
++++ b/src/main/java/org/apache/log4j/chainsaw/LoggingReceiver.java
+@@ -18,11 +18,11 @@ package org.apache.log4j.chainsaw;
+ 
+ import java.io.EOFException;
+ import java.io.IOException;
+-import java.io.ObjectInputStream;
+ import java.net.ServerSocket;
+ import java.net.Socket;
+ import java.net.SocketException;
+ import org.apache.log4j.Logger;
++import org.apache.log4j.net.HardenedLoggingEventInputStream;
+ import org.apache.log4j.spi.LoggingEvent;
+ 
+ /**
+@@ -58,10 +58,10 @@ class LoggingReceiver extends Thread {
+         public void run() {
+             LOG.debug("Starting to get data");
+             try {
+-                final ObjectInputStream ois =
+-                    new ObjectInputStream(mClient.getInputStream());
++                final HardenedLoggingEventInputStream hleis =
++                    new HardenedLoggingEventInputStream(mClient.getInputStream());
+                 while (true) {
+-                    final LoggingEvent event = (LoggingEvent) ois.readObject();
++                    final LoggingEvent event = (LoggingEvent) hleis.readObject();
+                     mModel.addEvent(new EventDetails(event));
+                 }
+             } catch (EOFException e) {
+diff --git a/src/main/java/org/apache/log4j/net/HardenedLoggingEventInputStream.java b/src/main/java/org/apache/log4j/net/HardenedLoggingEventInputStream.java
+new file mode 100644
+index 0000000..f0f6a20
+--- /dev/null
++++ b/src/main/java/org/apache/log4j/net/HardenedLoggingEventInputStream.java
+@@ -0,0 +1,56 @@
++/*
++ * 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.log4j.net;
++
++import java.io.IOException;
++import java.io.InputStream;
++import java.util.ArrayList;
++import java.util.List;
++
++import org.apache.log4j.Level;
++import org.apache.log4j.Priority;
++import org.apache.log4j.spi.LocationInfo;
++import org.apache.log4j.spi.LoggingEvent;
++import org.apache.log4j.spi.ThrowableInformation;
++
++// === Copied from the logback project with permission ==
++public class HardenedLoggingEventInputStream extends HardenedObjectInputStream {
++
++    static final String ARRAY_PREFIX = "[L";
++
++    static public List<String> getWhilelist() {
++
++	List<String> whitelist = new ArrayList<String>();
++	whitelist.add(LoggingEvent.class.getName());
++	whitelist.add(Level.class.getName());
++	whitelist.add(Priority.class.getName());
++	whitelist.add(ThrowableInformation.class.getName());
++	whitelist.add(LocationInfo.class.getName());
++
++	return whitelist;
++    }
++
++    public HardenedLoggingEventInputStream(InputStream is) throws IOException {
++	super(is, getWhilelist());
++    }
++
++    public HardenedLoggingEventInputStream(InputStream is, List<String> additionalAuthorizedClasses)
++	    throws IOException {
++	this(is);
++	super.addToWhitelist(additionalAuthorizedClasses);
++    }
++}
+diff --git a/src/main/java/org/apache/log4j/net/HardenedObjectInputStream.java b/src/main/java/org/apache/log4j/net/HardenedObjectInputStream.java
+new file mode 100644
+index 0000000..c911572
+--- /dev/null
++++ b/src/main/java/org/apache/log4j/net/HardenedObjectInputStream.java
+@@ -0,0 +1,93 @@
++/*
++ * 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.log4j.net;
++
++import java.io.IOException;
++import java.io.InputStream;
++import java.io.InvalidClassException;
++import java.io.ObjectInputStream;
++import java.io.ObjectStreamClass;
++import java.util.ArrayList;
++import java.util.List;
++
++/**
++ * HardenedObjectInputStream restricts the set of classes that can be
++ * deserialized to a set of explicitly whitelisted classes. This prevents
++ * certain type of attacks from being successful.
++ * 
++ * <p>
++ * It is assumed that classes in the "java.lang" and "java.util" packages are
++ * always authorized.
++ * </p>
++ * 
++ * @author Ceki Gülcü
++ * @since 1.2.18
++ * 
++ *        === Copied from the logback project with permission ==
++ */
++public class HardenedObjectInputStream extends ObjectInputStream {
++
++    static final String ARRAY_CLASS_PREFIX = "[L";
++    final List<String> whitelistedClassNames;
++    final static String[] JAVA_PACKAGES = new String[] { "java.lang", "java.util", ARRAY_CLASS_PREFIX + "java.lang" };
++
++    public HardenedObjectInputStream(InputStream in, String[] whilelist) throws IOException {
++	super(in);
++
++	this.whitelistedClassNames = new ArrayList<String>();
++	if (whilelist != null) {
++	    for (int i = 0; i < whilelist.length; i++) {
++		this.whitelistedClassNames.add(whilelist[i]);
++	    }
++	}
++    }
++
++    public HardenedObjectInputStream(InputStream in, List<String> whitelist) throws IOException {
++	super(in);
++
++	this.whitelistedClassNames = new ArrayList<String>();
++	this.whitelistedClassNames.addAll(whitelist);
++    }
++
++    @Override
++    protected Class<?> resolveClass(ObjectStreamClass anObjectStreamClass) throws IOException, ClassNotFoundException {
++
++	String incomingClassName = anObjectStreamClass.getName();
++
++	if (!isWhitelisted(incomingClassName)) {
++	    throw new InvalidClassException("Unauthorized deserialization attempt", incomingClassName);
++	}
++
++	return super.resolveClass(anObjectStreamClass);
++    }
++
++    private boolean isWhitelisted(String incomingClassName) {
++	for (int i = 0; i < JAVA_PACKAGES.length; i++) {
++	    if (incomingClassName.startsWith(JAVA_PACKAGES[i]))
++		return true;
++	}
++	for (String whiteListed : whitelistedClassNames) {
++	    if (incomingClassName.equals(whiteListed))
++		return true;
++	}
++	return false;
++    }
++
++    protected void addToWhitelist(List<String> additionalAuthorizedClasses) {
++	whitelistedClassNames.addAll(additionalAuthorizedClasses);
++    }
++}
+\ No newline at end of file
+diff --git a/src/test/input/xml/socketAppenderForChainsaw.xml b/src/test/input/xml/socketAppenderForChainsaw.xml
+new file mode 100644
+index 0000000..b022ba5
+--- /dev/null
++++ b/src/test/input/xml/socketAppenderForChainsaw.xml
+@@ -0,0 +1,24 @@
++<?xml version="1.0" encoding="UTF-8" ?>
++<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
++
++<log4j:configuration debug="true" 
++xmlns:log4j='http://jakarta.apache.org/log4j/'>
++
++
++  <!-- primary appender -->
++  <appender name="REMOTE" class="org.apache.log4j.net.SocketAppender">
++    
++    <param name="RemoteHost" value="localhost"/>
++    <param name="Port" value="4445"/>
++    <param name="ReconnectionDelay" value="10"/>
++  </appender>
++
++  <root>
++    <priority value ="trace" />
++    <appender-ref ref="REMOTE" />
++  </root>
++
++        
++</log4j:configuration>
++
++ 
+diff --git a/src/test/java/org/apache/log4j/net/SocketAppenderTest.java b/src/test/java/org/apache/log4j/net/SocketAppenderTest.java
+new file mode 100644
+index 0000000..6c4a390
+--- /dev/null
++++ b/src/test/java/org/apache/log4j/net/SocketAppenderTest.java
+@@ -0,0 +1,96 @@
++/*
++ * 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.log4j.net;
++
++import static org.apache.log4j.TestContants.TEST_INPUT_PREFIX;
++import static org.junit.Assert.assertEquals;
++
++import org.apache.log4j.AppenderSkeleton;
++import org.apache.log4j.Logger;
++import org.apache.log4j.spi.LoggingEvent;
++import org.apache.log4j.xml.DOMConfigurator;
++import org.junit.After;
++import org.junit.Before;
++import org.junit.Test;
++
++public class SocketAppenderTest {
++
++    /* JUnit's setUp and tearDown */
++
++    @Before
++    public void setUp() {
++	DOMConfigurator.configure(TEST_INPUT_PREFIX + "xml/SocketAppenderTestConfig.xml");
++	// DOMConfigurator.configure(TEST_INPUT_PREFIX +
++	// "xml/socketAppenderForChainsaw.xml");
++
++	logger = Logger.getLogger(SocketAppenderTest.class);
++	secondary = (LastOnlyAppender) Logger.getLogger("org.apache.log4j.net.SocketAppenderTestDummy")
++		.getAppender("lastOnly");
++    }
++
++    @After
++    public void tearDown() {
++    }
++
++    /* Tests */
++
++    @Test
++    public void testFallbackErrorHandlerWhenStarting() {
++	String msg = "testFallbackErrorHandlerWhenStarting";
++	logger.debug(msg);
++
++	// above debug log will fail and shoul be redirected to secondary appender
++	assertEquals("SocketAppender with FallbackErrorHandler", msg, secondary.getLastMessage());
++    }
++
++    /* Fields */
++
++    private static Logger logger;
++    private static LastOnlyAppender secondary;
++
++    /* Inner classes */
++
++    /**
++     * Inner-class For debugging purposes only Saves last LoggerEvent
++     */
++    static public class LastOnlyAppender extends AppenderSkeleton {
++	protected void append(LoggingEvent event) {
++	    this.lastEvent = event;
++	}
++
++	public boolean requiresLayout() {
++	    return false;
++	}
++
++	public void close() {
++	    this.closed = true;
++	}
++
++	/**
++	 * @return last appended LoggingEvent's message
++	 */
++	public String getLastMessage() {
++	    if (this.lastEvent != null)
++		return this.lastEvent.getMessage().toString();
++	    else
++		return "";
++	}
++
++	private LoggingEvent lastEvent;
++    };
++
++}
+\ No newline at end of file


=====================================
debian/patches/series
=====================================
@@ -1,6 +1,9 @@
 build_fix.patch
-
 remove-activation-framework-dependency.patch
 add-missing-classes.patch
 CVE-2019-17571.patch
 disable-examples.patch
+CVE-2022-23305.patch
+CVE-2021-4104.patch
+CVE-2022-23302.patch
+CVE-2022-23307.patch



View it on GitLab: https://salsa.debian.org/java-team/apache-log4j1.2/-/compare/cf1271e4e0546dbd64005c70397052548a4fa536...430143f948a219be67cba69ce8a36fb87180f425

-- 
View it on GitLab: https://salsa.debian.org/java-team/apache-log4j1.2/-/compare/cf1271e4e0546dbd64005c70397052548a4fa536...430143f948a219be67cba69ce8a36fb87180f425
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20220131/930f25a7/attachment.htm>


More information about the pkg-java-commits mailing list