From 9b69d4ab395dfbdaa29518a36188cdd1b315048c Mon Sep 17 00:00:00 2001 From: wk333 <13474090681@163.com> Date: Wed, 29 Dec 2021 14:48:03 +0800 Subject: [PATCH] Fix CVE-2021-44832 --- CVE-2021-44832-pre.patch | 49 ++++++ CVE-2021-44832.patch | 338 +++++++++++++++++++++++++++++++++++++++ log4j.spec | 7 +- 3 files changed, 393 insertions(+), 1 deletion(-) create mode 100644 CVE-2021-44832-pre.patch create mode 100644 CVE-2021-44832.patch diff --git a/CVE-2021-44832-pre.patch b/CVE-2021-44832-pre.patch new file mode 100644 index 0000000..d5ed5c6 --- /dev/null +++ b/CVE-2021-44832-pre.patch @@ -0,0 +1,49 @@ +From 0a38c766b74260485b4427cfbe7b22952ab14a29 Mon Sep 17 00:00:00 2001 +From: Carter Kozak +Date: Wed, 22 Dec 2021 15:20:16 -0500 +Subject: [PATCH] JNDI enablement properties are loaded at most once + +Rather than checking properties after each invocation, jndi +properties are all read into static final boolean fields when +the JndiManager class is initialized, this way properties cannot +be mutated and refreshed at runtime, and checks are cheaper. +This format matches other log4j configuration points as set +in `Constants.java`. +--- + .../org/apache/logging/log4j/core/net/JndiManager.java | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/JndiManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/JndiManager.java +index d9d0c0b662..d73d4137b6 100644 +--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/JndiManager.java ++++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/JndiManager.java +@@ -42,6 +42,10 @@ + private static final String PREFIX = "log4j2.enableJndi"; + private static final String JAVA_SCHEME = "java"; + ++ private static final boolean JNDI_CONTEXT_SELECTOR_ENABLED = isJndiEnabled("ContextSelector"); ++ private static final boolean JNDI_JMS_ENABLED = isJndiEnabled("Jms"); ++ private static final boolean JNDI_LOOKUP_ENABLED = isJndiEnabled("Lookup"); ++ + private final InitialContext context; + + private static boolean isJndiEnabled(final String subKey) { +@@ -53,15 +57,15 @@ public static boolean isJndiEnabled() { + } + + public static boolean isJndiContextSelectorEnabled() { +- return isJndiEnabled("ContextSelector"); ++ return JNDI_CONTEXT_SELECTOR_ENABLED; + } + + public static boolean isJndiJmsEnabled() { +- return isJndiEnabled("Jms"); ++ return JNDI_JMS_ENABLED; + } + + public static boolean isJndiLookupEnabled() { +- return isJndiEnabled("Lookup"); ++ return JNDI_LOOKUP_ENABLED; + } + + private JndiManager(final String name, final InitialContext context) { diff --git a/CVE-2021-44832.patch b/CVE-2021-44832.patch new file mode 100644 index 0000000..fbb3b76 --- /dev/null +++ b/CVE-2021-44832.patch @@ -0,0 +1,338 @@ +From 05db5f9527254632b59aed2a1d78a32c5ab74f16 Mon Sep 17 00:00:00 2001 +From: Gary Gregory +Date: Mon, 27 Dec 2021 12:42:26 -0500 +Subject: [PATCH] Refactor to reuse existing code. + +--- + .../db/jdbc/DataSourceConnectionSource.java | 20 +++++----- + .../logging/log4j/core/net/JndiManager.java | 9 ++++- + .../AbstractJdbcAppenderDataSourceTest.java | 13 ++++--- + .../db/jdbc/AbstractJdbcDataSourceTest.java | 39 +++++++++++++++++++ + .../jdbc/DataSourceConnectionSourceTest.java | 2 +- + .../JdbcAppenderMapMessageDataSourceTest.java | 2 +- + .../core/appender/mom/JmsAppenderTest.java | 3 +- + .../log4j/core/net/JndiManagerTest.java | 9 ++++- + src/site/xdoc/manual/appenders.xml | 10 +++-- + src/site/xdoc/manual/configuration.xml.vm | 12 +++++- + 10 files changed, 93 insertions(+), 26 deletions(-) + create mode 100644 log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/AbstractJdbcDataSourceTest.java + +diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/DataSourceConnectionSource.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/DataSourceConnectionSource.java +index a791df9897..6a55a84d3c 100644 +--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/DataSourceConnectionSource.java ++++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/DataSourceConnectionSource.java +@@ -18,8 +18,8 @@ + + import java.sql.Connection; + import java.sql.SQLException; ++import java.util.Objects; + +-import javax.naming.InitialContext; + import javax.naming.NamingException; + import javax.sql.DataSource; + +@@ -28,6 +28,7 @@ + import org.apache.logging.log4j.core.config.plugins.Plugin; + import org.apache.logging.log4j.core.config.plugins.PluginAttribute; + import org.apache.logging.log4j.core.config.plugins.PluginFactory; ++import org.apache.logging.log4j.core.net.JndiManager; + import org.apache.logging.log4j.status.StatusLogger; + import org.apache.logging.log4j.util.Strings; + +@@ -42,7 +43,7 @@ + private final String description; + + private DataSourceConnectionSource(final String dataSourceName, final DataSource dataSource) { +- this.dataSource = dataSource; ++ this.dataSource = Objects.requireNonNull(dataSource, "dataSource"); + this.description = "dataSource{ name=" + dataSourceName + ", value=" + dataSource + " }"; + } + +@@ -59,25 +60,26 @@ public String toString() { + /** + * Factory method for creating a connection source within the plugin manager. + * +- * @param jndiName The full JNDI path where the data source is bound. Should start with java:/comp/env or +- * environment-equivalent. ++ * @param jndiName The full JNDI path where the data source is bound. Must start with java:/comp/env or environment-equivalent. + * @return the created connection source. + */ + @PluginFactory + public static DataSourceConnectionSource createConnectionSource(@PluginAttribute("jndiName") final String jndiName) { ++ if (!JndiManager.isJndiJdbcEnabled()) { ++ LOGGER.error("JNDI must be enabled by setting log4j2.enableJndiJdbc=true"); ++ return null; ++ } + if (Strings.isEmpty(jndiName)) { + LOGGER.error("No JNDI name provided."); + return null; + } +- + try { +- final InitialContext context = new InitialContext(); +- final DataSource dataSource = (DataSource) context.lookup(jndiName); ++ @SuppressWarnings("resource") ++ final DataSource dataSource = JndiManager.getDefaultManager(DataSourceConnectionSource.class.getCanonicalName()).lookup(jndiName); + if (dataSource == null) { +- LOGGER.error("No data source found with JNDI name [" + jndiName + "]."); ++ LOGGER.error("No DataSource found with JNDI name [" + jndiName + "]."); + return null; + } +- + return new DataSourceConnectionSource(jndiName, dataSource); + } catch (final NamingException e) { + LOGGER.error(e.getMessage(), e); +diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/JndiManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/JndiManager.java +index d73d4137b6..5e807b28c9 100644 +--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/JndiManager.java ++++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/JndiManager.java +@@ -43,6 +43,7 @@ + private static final String JAVA_SCHEME = "java"; + + private static final boolean JNDI_CONTEXT_SELECTOR_ENABLED = isJndiEnabled("ContextSelector"); ++ private static final boolean JNDI_JDBC_ENABLED = isJndiEnabled("Jdbc"); + private static final boolean JNDI_JMS_ENABLED = isJndiEnabled("Jms"); + private static final boolean JNDI_LOOKUP_ENABLED = isJndiEnabled("Lookup"); + +@@ -53,13 +54,17 @@ private static boolean isJndiEnabled(final String subKey) { + } + + public static boolean isJndiEnabled() { +- return isJndiContextSelectorEnabled() || isJndiJmsEnabled() || isJndiLookupEnabled(); ++ return isJndiContextSelectorEnabled() || isJndiJdbcEnabled() || isJndiJmsEnabled() || isJndiLookupEnabled(); + } + + public static boolean isJndiContextSelectorEnabled() { + return JNDI_CONTEXT_SELECTOR_ENABLED; + } + ++ public static boolean isJndiJdbcEnabled() { ++ return JNDI_JDBC_ENABLED; ++ } ++ + public static boolean isJndiJmsEnabled() { + return JNDI_JMS_ENABLED; + } +@@ -208,7 +213,7 @@ protected boolean releaseSub(final long timeout, final TimeUnit timeUnit) { + } + LOGGER.warn("Unsupported JNDI URI - {}", name); + } catch (URISyntaxException ex) { +- LOGGER.warn("Invalid JNDI URI - {}", name); ++ LOGGER.warn("Invalid JNDI URI - {}", name); + } + return null; + } +diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/AbstractJdbcAppenderDataSourceTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/AbstractJdbcAppenderDataSourceTest.java +index c4a73121b3..adf9e90155 100644 +--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/AbstractJdbcAppenderDataSourceTest.java ++++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/AbstractJdbcAppenderDataSourceTest.java +@@ -16,12 +16,19 @@ + */ + package org.apache.logging.log4j.core.appender.db.jdbc; + ++import static org.junit.Assert.assertEquals; ++import static org.junit.Assert.assertFalse; ++import static org.junit.Assert.assertTrue; ++import static org.mockito.BDDMockito.given; ++import static org.mockito.Mockito.mock; ++ + import java.io.ByteArrayOutputStream; + import java.io.PrintWriter; + import java.sql.Connection; + import java.sql.ResultSet; + import java.sql.SQLException; + import java.sql.Statement; ++ + import javax.sql.DataSource; + + import org.apache.logging.log4j.LogManager; +@@ -35,14 +42,10 @@ + import org.junit.Test; + import org.junit.rules.RuleChain; + +-import static org.junit.Assert.*; +-import static org.mockito.BDDMockito.given; +-import static org.mockito.Mockito.mock; +- + /** + * Abstract unit test for JdbcAppender using a {@link DataSource} configuration. + */ +-public abstract class AbstractJdbcAppenderDataSourceTest { ++public abstract class AbstractJdbcAppenderDataSourceTest extends AbstractJdbcDataSourceTest { + + @Rule + public final RuleChain rules; +diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/AbstractJdbcDataSourceTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/AbstractJdbcDataSourceTest.java +new file mode 100644 +index 0000000000..78bebee1a1 +--- /dev/null ++++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/AbstractJdbcDataSourceTest.java +@@ -0,0 +1,39 @@ ++/* ++ * 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.logging.log4j.core.appender.db.jdbc; ++ ++import javax.sql.DataSource; ++ ++import org.junit.AfterClass; ++import org.junit.BeforeClass; ++ ++/** ++ * Abstract unit test for JDBC using a {@link DataSource} configuration. ++ */ ++public abstract class AbstractJdbcDataSourceTest { ++ ++ @AfterClass ++ public static void afterClass() throws Exception { ++ System.clearProperty("log4j2.enableJndiJdbc"); ++ } ++ ++ @BeforeClass ++ public static void beforeClass() throws Exception { ++ System.setProperty("log4j2.enableJndiJdbc", "true"); ++ } ++ ++} +diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/DataSourceConnectionSourceTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/DataSourceConnectionSourceTest.java +index a49404a83f..ea9183a23d 100644 +--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/DataSourceConnectionSourceTest.java ++++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/DataSourceConnectionSourceTest.java +@@ -37,7 +37,7 @@ + import org.junit.runners.Parameterized; + + @RunWith(Parameterized.class) +-public class DataSourceConnectionSourceTest { ++public class DataSourceConnectionSourceTest extends AbstractJdbcDataSourceTest { + + @Parameterized.Parameters(name = "{0}") + public static Object[][] data() { +diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppenderMapMessageDataSourceTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppenderMapMessageDataSourceTest.java +index bee9786da7..77dcf31a41 100644 +--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppenderMapMessageDataSourceTest.java ++++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppenderMapMessageDataSourceTest.java +@@ -46,7 +46,7 @@ + /** + * Unit tests {@link MapMessage}s for JdbcAppender using a {@link DataSource} configuration. + */ +-public class JdbcAppenderMapMessageDataSourceTest { ++public class JdbcAppenderMapMessageDataSourceTest extends AbstractJdbcDataSourceTest { + + @Rule + public final RuleChain rules; +diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/mom/JmsAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/mom/JmsAppenderTest.java +index 4c5b1a9eb7..253cb06a12 100644 +--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/mom/JmsAppenderTest.java ++++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/mom/JmsAppenderTest.java +@@ -48,6 +48,7 @@ + import org.apache.logging.log4j.message.Message; + import org.apache.logging.log4j.message.SimpleMessage; + import org.apache.logging.log4j.message.StringMapMessage; ++import org.junit.AfterClass; + import org.junit.Before; + import org.junit.BeforeClass; + import org.junit.Rule; +@@ -84,7 +85,7 @@ + @Rule + public RuleChain rules = RuleChain.outerRule(jndiRule).around(ctx); + +- @BeforeClass ++ @AfterClass + public static void afterClass() throws Exception { + System.clearProperty("log4j2.enableJndiJms"); + } +diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/net/JndiManagerTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/JndiManagerTest.java +index e421734b4a..0b3501cf15 100644 +--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/net/JndiManagerTest.java ++++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/JndiManagerTest.java +@@ -29,14 +29,19 @@ + */ + public class JndiManagerTest { + ++ @Test ++ public void testIsJndiContextSelectorEnabled() { ++ assertFalse(JndiManager.isJndiContextSelectorEnabled()); ++ } ++ + @Test + public void testIsJndiEnabled() { + assertFalse(JndiManager.isJndiEnabled()); + } + + @Test +- public void testIsJndiContextSelectorEnabled() { +- assertFalse(JndiManager.isJndiContextSelectorEnabled()); ++ public void testIsJndiJdbcEnabled() { ++ assertFalse(JndiManager.isJndiJdbcEnabled()); + } + + @Test +diff --git a/src/site/xdoc/manual/appenders.xml b/src/site/xdoc/manual/appenders.xml +index c0f8c6dbd5..42fb1b8c71 100644 +--- a/src/site/xdoc/manual/appenders.xml ++++ b/src/site/xdoc/manual/appenders.xml +@@ -995,9 +995,13 @@ CREATE TABLE logs ( + + + +-

The JDBCAppender writes log events to a relational database table using standard JDBC. It can be configured +- to obtain JDBC connections using a JNDI DataSource or a custom factory method. Whichever +- approach you take, it must be backed by a connection pool. Otherwise, logging ++

The JDBC Appender writes log events to a relational database table using standard JDBC. It can be configured ++ to obtain JDBC connections using a JNDI DataSource or a custom factory method.

++

The JDBC Appender configured with a DataSource requires JNDI support so as of release 2.17.1 ++ this appender will not function unless log4j2.enableJndiJdbc=true is configured as a system property ++ or environment variable. See the enableJndiJdbc system property.

++

++ Whichever approach you take, it must be backed by a connection pool. Otherwise, logging + performance will suffer greatly. If batch statements are supported by the configured JDBC driver and a + bufferSize is configured to be a positive number, then log events will be batched. Note that as + of Log4j 2.8, there are two ways to configure log event to column mappings: the original ColumnConfig +diff --git a/src/site/xdoc/manual/configuration.xml.vm b/src/site/xdoc/manual/configuration.xml.vm +index 7ddd97c8bd..247eade524 100644 +--- a/src/site/xdoc/manual/configuration.xml.vm ++++ b/src/site/xdoc/manual/configuration.xml.vm +@@ -2156,12 +2156,20 @@ public class AwesomeTest { + When true, the Log4j context selector that uses the JNDI java protocol is enabled. When false, the default, they are disabled. + + ++ ++ log4j2.enableJndiJdbc ++ LOG4J_ENABLE_JNDI_JDBC ++ false ++ ++ When true, a Log4j JDBC Appender configured with a DataSource which uses JNDI's java protocol is enabled. When false, the default, they are disabled. ++ ++ + + log4j2.enableJndiJms + LOG4J_ENABLE_JNDI_JMS + false + +- When true, the Log4j JMS Appender that uses JNDI's java protocol is enabled. When false, the default, they are disabled. ++ When true, a Log4j JMS Appender that uses JNDI's java protocol is enabled. When false, the default, they are disabled. + + + +@@ -2169,7 +2177,7 @@ public class AwesomeTest { + LOG4J_ENABLE_JNDI_LOOKUP + false + +- When true, the Log4j lookup that uses JNDI's java protocol is enabled. When false, the default, they are disabled. ++ When true, a Log4j lookup that uses JNDI's java protocol is enabled. When false, the default, they are disabled. + + + diff --git a/log4j.spec b/log4j.spec index 6b8a601..7cdcf4a 100644 --- a/log4j.spec +++ b/log4j.spec @@ -1,11 +1,13 @@ Name: log4j Version: 2.17.0 -Release: 1 +Release: 2 Summary: Java logging package License: Apache-2.0 URL: http://logging.apache.org/%{name} Source0: http://archive.apache.org/dist/logging/%{name}/%{version}/apache-%{name}-%{version}-src.tar.gz Patch1: logging-log4j-Remove-unsupported-EventDataConverter.patch +Patch2: CVE-2021-44832-pre.patch +Patch3: CVE-2021-44832.patch BuildRequires: fdupes maven-local mvn(com.fasterxml.jackson.core:jackson-core) BuildRequires: mvn(com.fasterxml.jackson.core:jackson-annotations) BuildRequires: mvn(jakarta.servlet:jakarta.servlet-api) @@ -182,6 +184,9 @@ rm -r log4j-1.2-api/src/main/java/org/apache/log4j/or/jms %doc NOTICE.txt %changelog +* Wed Dec 29 2021 wangkai - 2.17.0-2 +- Fix CVE-2021-44832 + * Fri Dec 24 2021 wangkai - 2.17.0-1 - Upgrade to 2.17.0 for fix CVE-2021-45105