!9 [sync] PR-3: Fix cves
Merge pull request !9 from openeuler-sync-bot/sync-pr3-openEuler-20.03-LTS-SP1-to-openEuler-22.03-LTS-Next
This commit is contained in:
commit
9b096944c6
166
CVE-2021-4104.patch
Normal file
166
CVE-2021-4104.patch
Normal file
@ -0,0 +1,166 @@
|
||||
From: Markus Koschany <apo@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
|
||||
48
CVE-2022-23302.patch
Normal file
48
CVE-2022-23302.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From: Markus Koschany <apo@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()
|
||||
631
CVE-2022-23305.patch
Normal file
631
CVE-2022-23305.patch
Normal file
@ -0,0 +1,631 @@
|
||||
From: Markus Koschany <apo@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()
|
||||
+ );
|
||||
+ }
|
||||
+}
|
||||
343
CVE-2022-23307.patch
Normal file
343
CVE-2022-23307.patch
Normal file
@ -0,0 +1,343 @@
|
||||
From: Markus Koschany <apo@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
|
||||
13
log4j12.spec
13
log4j12.spec
@ -1,6 +1,6 @@
|
||||
Name: log4j12
|
||||
Version: 1.2.17
|
||||
Release: 24
|
||||
Release: 25
|
||||
Summary: A logging library for Java
|
||||
License: ASL 2.0
|
||||
URL: http://logging.apache.org/log4j/1.2/
|
||||
@ -12,6 +12,10 @@ Patch0000: 0001-logfactor5-changed-userdir.patch
|
||||
Patch0001: 0009-Fix-tests.patch
|
||||
Patch0002: 0010-Fix-javadoc-link.patch
|
||||
Patch0003: 0001-Backport-fix-for-CVE-2017-5645.patch
|
||||
Patch0004: CVE-2021-4104.patch
|
||||
Patch0005: CVE-2022-23302.patch
|
||||
Patch0006: CVE-2022-23305.patch
|
||||
Patch0007: CVE-2022-23307.patch
|
||||
|
||||
BuildRequires: maven-local mvn(ant-contrib:ant-contrib) mvn(javax.mail:mail)
|
||||
BuildRequires: mvn(junit:junit) mvn(org.apache.ant:ant-junit)
|
||||
@ -19,7 +23,7 @@ BuildRequires: mvn(org.apache.felix:maven-bundle-plugin)
|
||||
BuildRequires: mvn(org.apache.geronimo.specs:geronimo-jms_1.1_spec)
|
||||
BuildRequires: mvn(org.apache.maven.plugins:maven-antrun-plugin)
|
||||
BuildRequires: mvn(org.apache.maven.plugins:maven-assembly-plugin)
|
||||
BuildRequires: mvn(oro:oro) mvn(org.apache.ant:ant-nodeps)
|
||||
BuildRequires: mvn(oro:oro) mvn(org.apache.ant:ant-nodeps) maven
|
||||
|
||||
Obsoletes: log4j <= 0:1.2.17-14
|
||||
|
||||
@ -80,7 +84,7 @@ sed -i '/TelnetAppenderTest/d' tests/src/java/org/apache/log4j/CoreTestSuite.jav
|
||||
%mvn_file log4j:log4j log4j %{name}
|
||||
|
||||
%build
|
||||
%mvn_build
|
||||
%mvn_build -b
|
||||
|
||||
%install
|
||||
%mvn_install -X
|
||||
@ -119,5 +123,8 @@ fi
|
||||
%files help -f .mfiles-javadoc
|
||||
|
||||
%changelog
|
||||
* Tue Feb 08 2022 wangkai <wangkai385@huawei.com> - 1.2.17-25
|
||||
- Fix cves
|
||||
|
||||
* Fri Dec 13 2019 openEuler Buildteam <buildteam@openeuler.org> - 1.2.17-24
|
||||
- Package init
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user