Projects
openEuler:20.03:LTS:SP3
log4j
Sign Up
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 4
View file
_service:tar_scm_kernel_repo:log4j.spec
Changed
@@ -1,11 +1,15 @@ Name: log4j Version: 2.13.2 -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-44228-1.patch +Patch3: CVE-2021-44228-2.patch +Patch4: CVE-2021-44228-3.patch +Patch5: CVE-2021-44228-4.patch BuildRequires: fdupes maven-local mvn(com.fasterxml.jackson.core:jackson-core) BuildRequires: mvn(com.fasterxml.jackson.core:jackson-databind) mvn(com.lmax:disruptor) BuildRequires: mvn(com.sun.mail:javax.mail) mvn(org.apache.commons:commons-compress) @@ -168,6 +172,9 @@ %doc NOTICE.txt %changelog +* Sat Dec 11 2021 yaoxin <yaoxin30@huawei.com> - 2.13.2-2 +- Fix CVE-2021-44228 + * Wed Oct 21 2020 wangyue <wanyue92@huawei.com> - 2.13.2-1 - Upgrade to 2.13.2 to fix CVE-2020-9488
View file
_service:tar_scm_kernel_repo:CVE-2021-44228-1.patch
Added
@@ -0,0 +1,551 @@ +From 755e2c9d57f0517a73d16bfcaed93cc91969bdee Mon Sep 17 00:00:00 2001 +From: Ralph Goers <rgoers@apache.org> +Date: Mon, 29 Nov 2021 22:28:07 -0700 +Subject: [PATCH] Restrict LDAP access via JNDI + +--- + log4j-core/pom.xml | 5 + + .../log4j/core/appender/mom/JmsAppender.java | 31 ++++- + .../logging/log4j/core/lookup/JndiLookup.java | 5 + + .../logging/log4j/core/net/JndiManager.java | 106 ++++++++++++++- + .../logging/log4j/core/util/NetUtils.java | 44 +++++++ + .../log4j/core/lookup/JndiExploit.java | 36 +++++ + .../log4j/core/lookup/JndiLdapLookupTest.java | 124 ++++++++++++++++++ + .../src/test/resources/java-import.ldif | 4 + + pom.xml | 6 + + 9 files changed, 353 insertions(+), 8 deletions(-) + create mode 100644 log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiExploit.java + create mode 100644 log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLdapLookupTest.java + create mode 100644 log4j-core/src/test/resources/java-import.ldif + +diff --git a/log4j-core/pom.xml b/log4j-core/pom.xml +index 5d24d6f..3afa014 100644 +--- a/log4j-core/pom.xml ++++ b/log4j-core/pom.xml +@@ -332,6 +332,11 @@ + <artifactId>HdrHistogram</artifactId> + <scope>test</scope> + </dependency> ++ <dependency> ++ <groupId>org.zapodot</groupId> ++ <artifactId>embedded-ldap-junit</artifactId> ++ <scope>test</scope> ++ </dependency> + </dependencies> + <build> + <plugins> +diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsAppender.java +index ddac666..f2190ca 100644 +--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsAppender.java ++++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsAppender.java +@@ -88,6 +88,12 @@ public class JmsAppender extends AbstractAppender { + @PluginBuilderAttribute + private boolean immediateFail; + ++ @PluginBuilderAttribute ++ private String allowedLdapClasses; ++ ++ @PluginBuilderAttribute ++ private String allowedLdapHosts; ++ + // Programmatic access only for now. + private JmsManager jmsManager; + +@@ -100,8 +106,18 @@ public class JmsAppender extends AbstractAppender { + JmsManager actualJmsManager = jmsManager; + JmsManagerConfiguration configuration = null; + if (actualJmsManager == null) { ++ Properties additionalProperties = null; ++ if (allowedLdapClasses != null || allowedLdapHosts != null) { ++ additionalProperties = new Properties(); ++ if (allowedLdapHosts != null) { ++ additionalProperties.put(JndiManager.ALLOWED_HOSTS, allowedLdapHosts); ++ } ++ if (allowedLdapClasses != null) { ++ additionalProperties.put(JndiManager.ALLOWED_CLASSES, allowedLdapClasses); ++ } ++ } + final Properties jndiProperties = JndiManager.createProperties(factoryName, providerUrl, urlPkgPrefixes, +- securityPrincipalName, securityCredentials, null); ++ securityPrincipalName, securityCredentials, additionalProperties); + configuration = new JmsManagerConfiguration(jndiProperties, factoryBindingName, destinationBindingName, + userName, password, false, reconnectIntervalMillis); + actualJmsManager = AbstractManager.getManager(getName(), JmsManager.FACTORY, configuration); +@@ -202,6 +218,16 @@ public class JmsAppender extends AbstractAppender { + return this; + } + ++ public Builder setAllowedLdapClasses(final String allowedLdapClasses) { ++ this.allowedLdapClasses = allowedLdapClasses; ++ return this; ++ } ++ ++ public Builder setAllowedLdapHosts(final String allowedLdapHosts) { ++ this.allowedLdapHosts = allowedLdapHosts; ++ return this; ++ } ++ + /** + * Does not include the password. + */ +@@ -212,7 +238,8 @@ public class JmsAppender extends AbstractAppender { + + ", securityCredentials=" + securityCredentials + ", factoryBindingName=" + factoryBindingName + + ", destinationBindingName=" + destinationBindingName + ", username=" + userName + ", layout=" + + getLayout() + ", filter=" + getFilter() + ", ignoreExceptions=" + isIgnoreExceptions() +- + ", jmsManager=" + jmsManager + "]"; ++ + ", jmsManager=" + jmsManager + ", allowedLdapClasses=" + allowedLdapClasses ++ + ", allowedLdapHosts=" + allowedLdapHosts + "]"; + } + + } +diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java +index 30e65ad..e57d0be 100644 +--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java ++++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java +@@ -16,6 +16,11 @@ + */ + package org.apache.logging.log4j.core.lookup; + ++import java.net.MalformedURLException; ++import java.net.URI; ++import java.net.URISyntaxException; ++import java.util.ArrayList; ++import java.util.List; + import java.util.Objects; + + import javax.naming.NamingException; +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 2670857..8a0e68d 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 +@@ -17,31 +17,76 @@ + + package org.apache.logging.log4j.core.net; + ++import java.io.Serializable; ++import java.net.URI; ++import java.net.URISyntaxException; ++import java.util.ArrayList; ++import java.util.Arrays; ++import java.util.List; + import java.util.Properties; + import java.util.concurrent.TimeUnit; + + import javax.naming.Context; +-import javax.naming.InitialContext; ++import javax.naming.NameClassPair; ++import javax.naming.NamingEnumeration; + import javax.naming.NamingException; ++import javax.naming.Referenceable; ++import javax.naming.directory.Attribute; ++import javax.naming.directory.Attributes; ++import javax.naming.directory.DirContext; ++import javax.naming.directory.InitialDirContext; + + import org.apache.logging.log4j.core.appender.AbstractManager; + import org.apache.logging.log4j.core.appender.ManagerFactory; + import org.apache.logging.log4j.core.util.JndiCloser; ++import org.apache.logging.log4j.core.util.NetUtils; ++import org.apache.logging.log4j.util.PropertiesUtil; + + /** +- * Manages a JNDI {@link javax.naming.Context}. ++ * Manages a JNDI {@link javax.naming.directory.DirContext}. + * + * @since 2.1 + */ + public class JndiManager extends AbstractManager { + ++ public static final String ALLOWED_HOSTS = "allowedLdapHosts"; ++ public static final String ALLOWED_CLASSES = "allowedLdapClasses"; ++ + private static final JndiManagerFactory FACTORY = new JndiManagerFactory(); ++ private static final String PREFIX = "log4j2."; ++ private static final List<String> permanentAllowedHosts = new ArrayList<>(); ++ private static final List<String> permanentAllowedClasses = new ArrayList<>(); ++ private static final String LDAP = "ldap"; ++ private static final String SERIALIZED_DATA = "javaserializeddata"; ++ private static final String CLASS_NAME = "javaclassname"; ++ private static final String REFERENCE_ADDRESS = "javareferenceaddress"; ++ private static final String OBJECT_FACTORY = "javafactory"; ++ private final List<String> allowedHosts; ++ private final List<String> allowedClasses; ++ ++ static { ++ permanentAllowedHosts.addAll(NetUtils.getLocalIps()); ++ permanentAllowedClasses.add(Boolean.class.getName()); ++ permanentAllowedClasses.add(Byte.class.getName()); ++ permanentAllowedClasses.add(Character.class.getName()); ++ permanentAllowedClasses.add(Double.class.getName()); ++ permanentAllowedClasses.add(Float.class.getName()); ++ permanentAllowedClasses.add(Integer.class.getName()); ++ permanentAllowedClasses.add(Long.class.getName()); ++ permanentAllowedClasses.add(Number.class.getName()); ++ permanentAllowedClasses.add(Short.class.getName()); ++ permanentAllowedClasses.add(String.class.getName()); ++ } + +- private final Context context; + +- private JndiManager(final String name, final Context context) { ++ private final DirContext context; ++ ++ private JndiManager(final String name, final DirContext context, final List<String> allowedHosts, ++ final List<String> allowedClasses) { + super(null, name); + this.context = context; ++ this.allowedHosts = allowedHosts; ++ this.allowedClasses = allowedClasses; + }
View file
_service:tar_scm_kernel_repo:CVE-2021-44228-2.patch
Added
@@ -0,0 +1,232 @@ +From fe3d988db456640c96412e6c2a27ea2d40e51615 Mon Sep 17 00:00:00 2001 +From: Ralph Goers <rgoers@apache.org> +Date: Tue, 30 Nov 2021 17:20:24 -0700 +Subject: [PATCH] Disable most JNDI protocols + +--- + .../log4j/core/appender/mom/JmsAppender.java | 13 ++++- + .../logging/log4j/core/lookup/JndiLookup.java | 5 -- + .../logging/log4j/core/net/JndiManager.java | 47 +++++++++---------- + .../log4j/core/lookup/JndiLdapLookupTest.java | 22 ++++++++- + 4 files changed, 56 insertions(+), 31 deletions(-) + +diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsAppender.java +index f2190ca91c..35f5b10569 100644 +--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsAppender.java ++++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsAppender.java +@@ -94,6 +94,9 @@ + @PluginBuilderAttribute + private String allowedLdapHosts; + ++ @PluginBuilderAttribute ++ private String allowedJndiProtocols; ++ + // Programmatic access only for now. + private JmsManager jmsManager; + +@@ -115,6 +118,9 @@ public JmsAppender build() { + if (allowedLdapClasses != null) { + additionalProperties.put(JndiManager.ALLOWED_CLASSES, allowedLdapClasses); + } ++ if (allowedJndiProtocols != null) { ++ additionalProperties.put(JndiManager.ALLOWED_PROTOCOLS, allowedJndiProtocols); ++ } + } + final Properties jndiProperties = JndiManager.createProperties(factoryName, providerUrl, urlPkgPrefixes, + securityPrincipalName, securityCredentials, additionalProperties); +@@ -228,6 +234,11 @@ public Builder setAllowedLdapHosts(final String allowedLdapHosts) { + return this; + } + ++ public Builder setAllowedJndiProtocols(final String allowedJndiProtocols) { ++ this.allowedJndiProtocols = allowedJndiProtocols; ++ return this; ++ } ++ + /** + * Does not include the password. + */ +@@ -239,7 +250,7 @@ public String toString() { + + ", destinationBindingName=" + destinationBindingName + ", username=" + userName + ", layout=" + + getLayout() + ", filter=" + getFilter() + ", ignoreExceptions=" + isIgnoreExceptions() + + ", jmsManager=" + jmsManager + ", allowedLdapClasses=" + allowedLdapClasses +- + ", allowedLdapHosts=" + allowedLdapHosts + "]"; ++ + ", allowedLdapHosts=" + allowedLdapHosts + ", allowedJndiProtocols=" + allowedJndiProtocols + "]"; + } + + } +diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java +index e57d0bebba..30e65ad24f 100644 +--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java ++++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java +@@ -16,11 +16,6 @@ + */ + package org.apache.logging.log4j.core.lookup; + +-import java.net.MalformedURLException; +-import java.net.URI; +-import java.net.URISyntaxException; +-import java.util.ArrayList; +-import java.util.List; + import java.util.Objects; + + import javax.naming.NamingException; +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 8a0e68dc66..613a0551da 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 +@@ -17,20 +17,17 @@ + + package org.apache.logging.log4j.core.net; + +-import java.io.Serializable; + import java.net.URI; + import java.net.URISyntaxException; + import java.util.ArrayList; + import java.util.Arrays; + import java.util.List; ++import java.util.Locale; + import java.util.Properties; + import java.util.concurrent.TimeUnit; + + import javax.naming.Context; +-import javax.naming.NameClassPair; +-import javax.naming.NamingEnumeration; + import javax.naming.NamingException; +-import javax.naming.Referenceable; + import javax.naming.directory.Attribute; + import javax.naming.directory.Attributes; + import javax.naming.directory.DirContext; +@@ -51,42 +48,36 @@ + + public static final String ALLOWED_HOSTS = "allowedLdapHosts"; + public static final String ALLOWED_CLASSES = "allowedLdapClasses"; ++ public static final String ALLOWED_PROTOCOLS = "allowedJndiProtocols"; + + private static final JndiManagerFactory FACTORY = new JndiManagerFactory(); + private static final String PREFIX = "log4j2."; +- private static final List<String> permanentAllowedHosts = new ArrayList<>(); +- private static final List<String> permanentAllowedClasses = new ArrayList<>(); + private static final String LDAP = "ldap"; ++ private static final String LDAPS = "ldaps"; ++ private static final String JAVA = "java"; ++ private static final List<String> permanentAllowedHosts = NetUtils.getLocalIps(); ++ private static final List<String> permanentAllowedClasses = Arrays.asList(Boolean.class.getName(), ++ Byte.class.getName(), Character.class.getName(), Double.class.getName(), Float.class.getName(), ++ Integer.class.getName(), Long.class.getName(), Number.class.getName(), Short.class.getName(), ++ String.class.getName()); ++ private static final List<String> permanentAllowedProtocols = Arrays.asList(JAVA, LDAP, LDAPS); + private static final String SERIALIZED_DATA = "javaserializeddata"; + private static final String CLASS_NAME = "javaclassname"; + private static final String REFERENCE_ADDRESS = "javareferenceaddress"; + private static final String OBJECT_FACTORY = "javafactory"; + private final List<String> allowedHosts; + private final List<String> allowedClasses; +- +- static { +- permanentAllowedHosts.addAll(NetUtils.getLocalIps()); +- permanentAllowedClasses.add(Boolean.class.getName()); +- permanentAllowedClasses.add(Byte.class.getName()); +- permanentAllowedClasses.add(Character.class.getName()); +- permanentAllowedClasses.add(Double.class.getName()); +- permanentAllowedClasses.add(Float.class.getName()); +- permanentAllowedClasses.add(Integer.class.getName()); +- permanentAllowedClasses.add(Long.class.getName()); +- permanentAllowedClasses.add(Number.class.getName()); +- permanentAllowedClasses.add(Short.class.getName()); +- permanentAllowedClasses.add(String.class.getName()); +- } +- ++ private final List<String> allowedProtocols; + + private final DirContext context; + + private JndiManager(final String name, final DirContext context, final List<String> allowedHosts, +- final List<String> allowedClasses) { ++ final List<String> allowedClasses, final List<String> allowedProtocols) { + super(null, name); + this.context = context; + this.allowedHosts = allowedHosts; + this.allowedClasses = allowedClasses; ++ this.allowedProtocols = allowedProtocols; + } + + /** +@@ -216,7 +207,11 @@ protected boolean releaseSub(final long timeout, final TimeUnit timeUnit) { + public synchronized <T> T lookup(final String name) throws NamingException { + try { + URI uri = new URI(name); +- if (LDAP.equalsIgnoreCase(uri.getScheme())) { ++ if (!allowedProtocols.contains(uri.getScheme().toLowerCase(Locale.ROOT))) { ++ LOGGER.warn("Log4j JNDI does not allow protocol {}", uri.getScheme()); ++ return null; ++ } ++ if (LDAP.equalsIgnoreCase(uri.getScheme()) || LDAPS.equalsIgnoreCase(uri.getScheme())) { + if (!allowedHosts.contains(uri.getHost())) { + LOGGER.warn("Attempt to access ldap server not in allowed list"); + return null; +@@ -253,12 +248,16 @@ protected boolean releaseSub(final long timeout, final TimeUnit timeUnit) { + public JndiManager createManager(final String name, final Properties data) { + String hosts = data != null ? data.getProperty(ALLOWED_HOSTS) : null; + String classes = data != null ? data.getProperty(ALLOWED_CLASSES) : null; ++ String protocols = data != null ? data.getProperty(ALLOWED_PROTOCOLS) : null; + List<String> allowedHosts = new ArrayList<>(); + List<String> allowedClasses = new ArrayList<>(); ++ List<String> allowedProtocols = new ArrayList<>(); + addAll(hosts, allowedHosts, permanentAllowedHosts, ALLOWED_HOSTS, data); + addAll(classes, allowedClasses, permanentAllowedClasses, ALLOWED_CLASSES, data); ++ addAll(protocols, allowedProtocols, permanentAllowedProtocols, ALLOWED_PROTOCOLS, data); + try { +- return new JndiManager(name, new InitialDirContext(data), allowedHosts, allowedClasses); ++ return new JndiManager(name, new InitialDirContext(data), allowedHosts, allowedClasses, ++ allowedProtocols); + } catch (final NamingException e) { + LOGGER.error("Error creating JNDI InitialContext.", e); + return null; +diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLdapLookupTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLdapLookupTest.java +index 73129f5a91..a26d927da4 100644 +--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLdapLookupTest.java ++++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLdapLookupTest.java +@@ -43,7 +43,8 @@ + private static final String TEST_STRING = "TestString"; + private static final String TEST_MESSAGE = "TestMessage"; + private static final String LEVEL = "TestLevel"; +- public static final String DOMAIN_DSN = "dc=apache,dc=org"; ++ private static final String DOMAIN_DSN = "dc=apache,dc=org"; ++ private static final String DOMAIN = "apache.org"; + + @Rule + public EmbeddedLdapRule embeddedLdapRule = EmbeddedLdapRuleBuilder.newInstance().usingDomainDsn(DOMAIN_DSN)
View file
_service:tar_scm_kernel_repo:CVE-2021-44228-3.patch
Added
@@ -0,0 +1,112 @@ +From 5f81dd218aab36bf1c6a7410c88c29594bb1a0e7 Mon Sep 17 00:00:00 2001 +From: Ralph Goers <rgoers@apache.org> +Date: Tue, 30 Nov 2021 22:38:22 -0700 +Subject: [PATCH] Rename test. Various minor fixes + +--- + .../logging/log4j/core/net/JndiManager.java | 31 +++++++++++++------ + ...est.java => JndiRestrictedLookupTest.java} | 4 +-- + ...-import.ldif => JndiRestrictedLookup.ldif} | 0 + 3 files changed, 24 insertions(+), 11 deletions(-) + rename log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/{JndiLdapLookupTest.java => JndiRestrictedLookupTest.java} (98%) + rename log4j-core/src/test/resources/{java-import.ldif => JndiRestrictedLookup.ldif} (100%) + +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 613a0551da..b392b938b4 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 +@@ -21,12 +21,15 @@ + import java.net.URISyntaxException; + import java.util.ArrayList; + import java.util.Arrays; ++import java.util.HashMap; + import java.util.List; + import java.util.Locale; ++import java.util.Map; + import java.util.Properties; + import java.util.concurrent.TimeUnit; + + import javax.naming.Context; ++import javax.naming.NamingEnumeration; + import javax.naming.NamingException; + import javax.naming.directory.Attribute; + import javax.naming.directory.Attributes; +@@ -58,13 +61,12 @@ + private static final List<String> permanentAllowedHosts = NetUtils.getLocalIps(); + private static final List<String> permanentAllowedClasses = Arrays.asList(Boolean.class.getName(), + Byte.class.getName(), Character.class.getName(), Double.class.getName(), Float.class.getName(), +- Integer.class.getName(), Long.class.getName(), Number.class.getName(), Short.class.getName(), +- String.class.getName()); ++ Integer.class.getName(), Long.class.getName(), Short.class.getName(), String.class.getName()); + private static final List<String> permanentAllowedProtocols = Arrays.asList(JAVA, LDAP, LDAPS); +- private static final String SERIALIZED_DATA = "javaserializeddata"; +- private static final String CLASS_NAME = "javaclassname"; +- private static final String REFERENCE_ADDRESS = "javareferenceaddress"; +- private static final String OBJECT_FACTORY = "javafactory"; ++ private static final String SERIALIZED_DATA = "javaSerializedData"; ++ private static final String CLASS_NAME = "javaClassName"; ++ private static final String REFERENCE_ADDRESS = "javaReferenceAddress"; ++ private static final String OBJECT_FACTORY = "javaFactory"; + private final List<String> allowedHosts; + private final List<String> allowedClasses; + private final List<String> allowedProtocols; +@@ -218,8 +220,18 @@ protected boolean releaseSub(final long timeout, final TimeUnit timeUnit) { + } + Attributes attributes = this.context.getAttributes(name); + if (attributes != null) { +- Attribute classNameAttr = attributes.get(CLASS_NAME); +- if (attributes.get(SERIALIZED_DATA) != null) { ++ // In testing the "key" for attributes seems to be lowercase while the attribute id is ++ // camelcase, but that may just be true for the test LDAP used here. This copies the Attributes ++ // to a Map ignoring the "key" and using the Attribute's id as the key in the Map so it matches ++ // the Java schema. ++ Map<String, Attribute> attributeMap = new HashMap<>(); ++ NamingEnumeration<? extends Attribute> enumeration = attributes.getAll(); ++ while (enumeration.hasMore()) { ++ Attribute attribute = enumeration.next(); ++ attributeMap.put(attribute.getID(), attribute); ++ } ++ Attribute classNameAttr = attributeMap.get(CLASS_NAME); ++ if (attributeMap.get(SERIALIZED_DATA) != null) { + if (classNameAttr != null) { + String className = classNameAttr.get().toString(); + if (!allowedClasses.contains(className)) { +@@ -230,7 +242,8 @@ protected boolean releaseSub(final long timeout, final TimeUnit timeUnit) { + LOGGER.warn("No class name provided for {}", name); + return null; + } +- } else if (attributes.get(REFERENCE_ADDRESS) != null || attributes.get(OBJECT_FACTORY) != null){ ++ } else if (attributeMap.get(REFERENCE_ADDRESS) != null ++ || attributeMap.get(OBJECT_FACTORY) != null) { + LOGGER.warn("Referenceable class is not allowed for {}", name); + return null; + } +diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLdapLookupTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiRestrictedLookupTest.java +similarity index 98% +rename from log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLdapLookupTest.java +rename to log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiRestrictedLookupTest.java +index a26d927da4..032c9c4d85 100644 +--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLdapLookupTest.java ++++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiRestrictedLookupTest.java +@@ -36,7 +36,7 @@ + /** + * JndiLookupTest + */ +-public class JndiLdapLookupTest { ++public class JndiRestrictedLookupTest { + + private static final String LDAP_URL = "ldap://127.0.0.1:"; + private static final String RESOURCE = "JndiExploit"; +@@ -48,7 +48,7 @@ + + @Rule + public EmbeddedLdapRule embeddedLdapRule = EmbeddedLdapRuleBuilder.newInstance().usingDomainDsn(DOMAIN_DSN) +- .importingLdifs("java-import.ldif").build(); ++ .importingLdifs("JndiRestrictedLookup.ldif").build(); + + @BeforeClass + public static void beforeClass() { +diff --git a/log4j-core/src/test/resources/java-import.ldif b/log4j-core/src/test/resources/JndiRestrictedLookup.ldif +similarity index 100% +rename from log4j-core/src/test/resources/java-import.ldif +rename to log4j-core/src/test/resources/JndiRestrictedLookup.ldif
View file
_service:tar_scm_kernel_repo:CVE-2021-44228-4.patch
Added
@@ -0,0 +1,237 @@ +From 7fe72d62fcb9246be792b946e405e1d40d402780 Mon Sep 17 00:00:00 2001 +From: Ralph Goers <rgoers@apache.org> +Date: Sat, 4 Dec 2021 20:59:39 -0700 +Subject: [PATCH] LOG4J2-3201 - Limit the protocols JNDI can use by default. + Limit the servers and classes that can be accessed via LDAP. + +--- + .../logging/log4j/core/net/JndiManager.java | 62 ++++++++++--------- + .../logging/log4j/core/util/NetUtils.java | 4 ++ + src/changes/changes.xml | 3 + + src/site/xdoc/manual/appenders.xml | 27 ++++++++ + src/site/xdoc/manual/configuration.xml.vm | 26 ++++++++ + src/site/xdoc/manual/extending.xml | 5 +- + src/site/xdoc/manual/lookups.xml | 7 +++ + 7 files changed, 103 insertions(+), 31 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 b392b93..2d7604f 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 +@@ -209,43 +209,45 @@ public class JndiManager extends AbstractManager { + public synchronized <T> T lookup(final String name) throws NamingException { + try { + URI uri = new URI(name); +- if (!allowedProtocols.contains(uri.getScheme().toLowerCase(Locale.ROOT))) { +- LOGGER.warn("Log4j JNDI does not allow protocol {}", uri.getScheme()); +- return null; +- } +- if (LDAP.equalsIgnoreCase(uri.getScheme()) || LDAPS.equalsIgnoreCase(uri.getScheme())) { +- if (!allowedHosts.contains(uri.getHost())) { +- LOGGER.warn("Attempt to access ldap server not in allowed list"); ++ if (uri.getScheme() != null) { ++ if (!allowedProtocols.contains(uri.getScheme().toLowerCase(Locale.ROOT))) { ++ LOGGER.warn("Log4j JNDI does not allow protocol {}", uri.getScheme()); + return null; + } +- Attributes attributes = this.context.getAttributes(name); +- if (attributes != null) { +- // In testing the "key" for attributes seems to be lowercase while the attribute id is +- // camelcase, but that may just be true for the test LDAP used here. This copies the Attributes +- // to a Map ignoring the "key" and using the Attribute's id as the key in the Map so it matches +- // the Java schema. +- Map<String, Attribute> attributeMap = new HashMap<>(); +- NamingEnumeration<? extends Attribute> enumeration = attributes.getAll(); +- while (enumeration.hasMore()) { +- Attribute attribute = enumeration.next(); +- attributeMap.put(attribute.getID(), attribute); ++ if (LDAP.equalsIgnoreCase(uri.getScheme()) || LDAPS.equalsIgnoreCase(uri.getScheme())) { ++ if (!allowedHosts.contains(uri.getHost())) { ++ LOGGER.warn("Attempt to access ldap server not in allowed list"); ++ return null; + } +- Attribute classNameAttr = attributeMap.get(CLASS_NAME); +- if (attributeMap.get(SERIALIZED_DATA) != null) { +- if (classNameAttr != null) { +- String className = classNameAttr.get().toString(); +- if (!allowedClasses.contains(className)) { +- LOGGER.warn("Deserialization of {} is not allowed", className); ++ Attributes attributes = this.context.getAttributes(name); ++ if (attributes != null) { ++ // In testing the "key" for attributes seems to be lowercase while the attribute id is ++ // camelcase, but that may just be true for the test LDAP used here. This copies the Attributes ++ // to a Map ignoring the "key" and using the Attribute's id as the key in the Map so it matches ++ // the Java schema. ++ Map<String, Attribute> attributeMap = new HashMap<>(); ++ NamingEnumeration<? extends Attribute> enumeration = attributes.getAll(); ++ while (enumeration.hasMore()) { ++ Attribute attribute = enumeration.next(); ++ attributeMap.put(attribute.getID(), attribute); ++ } ++ Attribute classNameAttr = attributeMap.get(CLASS_NAME); ++ if (attributeMap.get(SERIALIZED_DATA) != null) { ++ if (classNameAttr != null) { ++ String className = classNameAttr.get().toString(); ++ if (!allowedClasses.contains(className)) { ++ LOGGER.warn("Deserialization of {} is not allowed", className); ++ return null; ++ } ++ } else { ++ LOGGER.warn("No class name provided for {}", name); + return null; + } +- } else { +- LOGGER.warn("No class name provided for {}", name); ++ } else if (attributeMap.get(REFERENCE_ADDRESS) != null ++ || attributeMap.get(OBJECT_FACTORY) != null) { ++ LOGGER.warn("Referenceable class is not allowed for {}", name); + return null; + } +- } else if (attributeMap.get(REFERENCE_ADDRESS) != null +- || attributeMap.get(OBJECT_FACTORY) != null) { +- LOGGER.warn("Referenceable class is not allowed for {}", name); +- return null; + } + } + } +diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/NetUtils.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/NetUtils.java +index b9a01ae..6adac59 100644 +--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/NetUtils.java ++++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/NetUtils.java +@@ -83,6 +83,10 @@ public final class NetUtils { + } + } + ++ /** ++ * Returns all the local host names and ip addresses. ++ * @return The local host names and ip addresses. ++ */ + public static List<String> getLocalIps() { + List<String> localIps = new ArrayList<>(); + localIps.add("localhost"); +diff --git a/src/changes/changes.xml b/src/changes/changes.xml +index 9c44684..f2d9c57 100644 +--- a/src/changes/changes.xml ++++ b/src/changes/changes.xml +@@ -30,6 +30,9 @@ + - "remove" - Removed + --> + <release version="2.13.2" date="2020-04-23" description="GA Release 2.13.2"> ++ <action issue="LOG4J2-3201" dev="rgoers" type="fix"> ++ Limit the protocols JNDI can use by default. Limit the servers and classes that can be accessed via LDAP. ++ </action> + <action issue="LOG4J2-2824" dev="rgoers" type="fix" due-to="CrazyBills"> + Implement requiresLocation in GelfLayout to reflect whether location information is used in the message Pattern. + </action> +diff --git a/src/site/xdoc/manual/appenders.xml b/src/site/xdoc/manual/appenders.xml +index ab40094..267f54f 100644 +--- a/src/site/xdoc/manual/appenders.xml ++++ b/src/site/xdoc/manual/appenders.xml +@@ -1542,6 +1542,33 @@ public class ConnectionFactory { + <th>Default</th> + <th>Description</th> + </tr> ++ <tr> ++ <td>allowdLdapClasses</td> ++ <td>String</td> ++ <td>null</td> ++ <td> ++ A comma separated list of fully qualified class names that may be accessed by LDAP. The classes ++ must implement Serializable. Only applies when the JMS Appender By default only Java primative classes are allowed. ++ </td> ++ </tr> ++ <tr> ++ <td>allowdLdapHosts</td> ++ <td>String</td> ++ <td>null</td> ++ <td> ++ A comma separated list of host names or ip addresses that may be accessed by LDAP. By default only ++ the local host names and ip addresses are allowed. ++ </td> ++ </tr> ++ <tr> ++ <td>allowdJndiProtocols</td> ++ <td>String</td> ++ <td>null</td> ++ <td> ++ A comma separated list of protocol names that JNDI will allow. By default only java, ldap, and ldaps ++ are the only allowed protocols. ++ </td> ++ </tr> + <tr> + <td>factoryBindingName</td> + <td>String</td> +diff --git a/src/site/xdoc/manual/configuration.xml.vm b/src/site/xdoc/manual/configuration.xml.vm +index a3da3b8..402a96c 100644 +--- a/src/site/xdoc/manual/configuration.xml.vm ++++ b/src/site/xdoc/manual/configuration.xml.vm +@@ -1960,6 +1960,32 @@ public class AwesomeTest { + before falling back to the default class loader. + </td> + </tr> ++ <tr> ++ <td><a name="allowedLdapClasses"/>log4j2.allowedLdapClasses</td> ++ <td>LOG4J_ALLOWED_LDAP_CLASSES</td> ++ <td> </td> ++ <td> ++ System property that specifies fully qualified class names that may be accessed by LDAP. The classes ++ must implement Serializable. By default only Java primative classes are allowed. ++ </td> ++ </tr> ++ <tr> ++ <td><a name="allowedLdapHosts"/>log4j2.allowedLdapHosts</td> ++ <td>LOG4J_ALLOWED_LDAP_HOSTS</td> ++ <td> </td> ++ <td> ++ System property that adds host names or ip addresses that may be access by LDAP. By default it only allows ++ the local host names and ip addresses. ++ </td> ++ </tr> ++ <tr> ++ <td><a name="allowedJndiProtocols"/>log4j2.allowedJndiProtocols</td> ++ <td>LOG4J_ALLOWED_JNDI_PROTOCOLS</td> ++ <td> </td> ++ <td> ++ System property that adds protocol names that JNDI will allow. By default it only allows java, ldap, and ldaps. ++ </td> ++ </tr> + <tr> + <td><a name="uuidSequence"/>log4j2.uuidSequence
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.