[logback] 01/03: Add CVE-2017-5929-part2.patch
Markus Koschany
apo at moszumanska.debian.org
Tue Apr 4 13:56:33 UTC 2017
This is an automated email from the git hooks/post-receive script.
apo pushed a commit to branch master
in repository logback.
commit af91c89c6481fa90a69efe47037c18b4cb445f8e
Author: Markus Koschany <apo at debian.org>
Date: Tue Apr 4 14:44:31 2017 +0200
Add CVE-2017-5929-part2.patch
---
debian/patches/CVE-2017-5929-part2.patch | 390 +++++++++++++++++++++++++++++++
debian/patches/series | 1 +
2 files changed, 391 insertions(+)
diff --git a/debian/patches/CVE-2017-5929-part2.patch b/debian/patches/CVE-2017-5929-part2.patch
new file mode 100644
index 0000000..f14e1fa
--- /dev/null
+++ b/debian/patches/CVE-2017-5929-part2.patch
@@ -0,0 +1,390 @@
+From: Markus Koschany <apo at debian.org>
+Date: Tue, 4 Apr 2017 14:22:43 +0200
+Subject: CVE-2017-5929-part2
+
+This is part2 to fix CVE-2017-5929
+
+Origin: https://github.com/qos-ch/logback/commit/979b042cb1f0b4c1e5869ccc8912e68c39f769f9
+Origin: https://github.com/qos-ch/logback/commit/7fbea6127fa98fc48368ca5e8540eefe0e60cec5
+Origin: https://github.com/qos-ch/logback/commit/3b4f605454534b304770eeee3cb343521fcd6968
+---
+ .../access/net/HardenedAccessEventInputStream.java | 15 ++++++
+ .../java/ch/qos/logback/access/net/SocketNode.java | 11 ++---
+ .../ch/qos/logback/classic/net/SocketAppender.java | 2 -
+ .../ch/qos/logback/classic/net/SocketNode.java | 14 +++---
+ .../server/HardenedLoggingEventInputStream.java | 56 ++++++++++++++++++++++
+ .../server/LogbackClassicSerializationHelper.java | 28 -----------
+ .../net/server/RemoteAppenderStreamClient.java | 10 ++--
+ .../core/net/HardenedObjectInputStream.java | 47 +++++++++++++-----
+ 8 files changed, 123 insertions(+), 60 deletions(-)
+ create mode 100644 logback-access/src/main/java/ch/qos/logback/access/net/HardenedAccessEventInputStream.java
+ create mode 100644 logback-classic/src/main/java/ch/qos/logback/classic/net/server/HardenedLoggingEventInputStream.java
+ delete mode 100644 logback-classic/src/main/java/ch/qos/logback/classic/net/server/LogbackClassicSerializationHelper.java
+
+diff --git a/logback-access/src/main/java/ch/qos/logback/access/net/HardenedAccessEventInputStream.java b/logback-access/src/main/java/ch/qos/logback/access/net/HardenedAccessEventInputStream.java
+new file mode 100644
+index 0000000..c0ba6b0
+--- /dev/null
++++ b/logback-access/src/main/java/ch/qos/logback/access/net/HardenedAccessEventInputStream.java
+@@ -0,0 +1,15 @@
++package ch.qos.logback.access.net;
++
++import java.io.IOException;
++import java.io.InputStream;
++
++import ch.qos.logback.access.spi.AccessEvent;
++import ch.qos.logback.core.net.HardenedObjectInputStream;
++
++public class HardenedAccessEventInputStream extends HardenedObjectInputStream {
++
++ public HardenedAccessEventInputStream(InputStream in) throws IOException {
++ super(in, new String[] {AccessEvent.class.getName(), String[].class.getName()});
++ }
++
++}
+diff --git a/logback-access/src/main/java/ch/qos/logback/access/net/SocketNode.java b/logback-access/src/main/java/ch/qos/logback/access/net/SocketNode.java
+index e164774..aeb7b14 100644
+--- a/logback-access/src/main/java/ch/qos/logback/access/net/SocketNode.java
++++ b/logback-access/src/main/java/ch/qos/logback/access/net/SocketNode.java
+@@ -15,7 +15,6 @@ package ch.qos.logback.access.net;
+
+ import java.io.BufferedInputStream;
+ import java.io.IOException;
+-import java.io.ObjectInputStream;
+ import java.net.Socket;
+
+ import ch.qos.logback.access.spi.AccessContext;
+@@ -42,15 +41,15 @@ public class SocketNode implements Runnable {
+
+ Socket socket;
+ AccessContext context;
+- ObjectInputStream ois;
++ HardenedAccessEventInputStream hardenedOIS;
+
+ public SocketNode(Socket socket, AccessContext context) {
+ this.socket = socket;
+ this.context = context;
+ try {
+- ois = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
++ hardenedOIS = new HardenedAccessEventInputStream(new BufferedInputStream(socket.getInputStream()));
+ } catch (Exception e) {
+- System.out.println("Could not open ObjectInputStream to " + socket + e);
++ System.out.println("Could not open HardenedObjectInputStream to " + socket + e);
+ }
+ }
+
+@@ -61,7 +60,7 @@ public class SocketNode implements Runnable {
+ try {
+ while (true) {
+ // read an event from the wire
+- event = (IAccessEvent) ois.readObject();
++ event = (IAccessEvent) hardenedOIS.readObject();
+ // check that the event should be logged
+ if (context.getFilterChainDecision(event) == FilterReply.DENY) {
+ break;
+@@ -81,7 +80,7 @@ public class SocketNode implements Runnable {
+ }
+
+ try {
+- ois.close();
++ hardenedOIS.close();
+ } catch (Exception e) {
+ System.out.println("Could not close connection." + e);
+ }
+diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketAppender.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketAppender.java
+index 82518c7..0590cae 100644
+--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketAppender.java
++++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketAppender.java
+@@ -14,8 +14,6 @@
+ // Contributors: Dan MacDonald <dan at redknee.com>
+ package ch.qos.logback.classic.net;
+
+-import java.net.InetAddress;
+-
+ import ch.qos.logback.classic.spi.ILoggingEvent;
+ import ch.qos.logback.core.net.AbstractSocketAppender;
+ import ch.qos.logback.core.spi.PreSerializationTransformer;
+diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketNode.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketNode.java
+index 4c01cbe..8faf6a6 100644
+--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketNode.java
++++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketNode.java
+@@ -15,13 +15,13 @@ package ch.qos.logback.classic.net;
+
+ import java.io.BufferedInputStream;
+ import java.io.IOException;
+-import java.io.ObjectInputStream;
+ import java.net.Socket;
+ import java.net.SocketAddress;
+
+ import ch.qos.logback.classic.Logger;
+
+ import ch.qos.logback.classic.LoggerContext;
++import ch.qos.logback.classic.net.server.HardenedLoggingEventInputStream;
+ import ch.qos.logback.classic.spi.ILoggingEvent;
+
+ // Contributors: Moses Hohman <mmhohman at rainbow.uchicago.edu>
+@@ -44,7 +44,7 @@ public class SocketNode implements Runnable {
+
+ Socket socket;
+ LoggerContext context;
+- ObjectInputStream ois;
++ HardenedLoggingEventInputStream hardenedLoggingEventInputStream;
+ SocketAddress remoteSocketAddress;
+
+ Logger logger;
+@@ -68,7 +68,7 @@ public class SocketNode implements Runnable {
+ public void run() {
+
+ try {
+- ois = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
++ hardenedLoggingEventInputStream = new HardenedLoggingEventInputStream(new BufferedInputStream(socket.getInputStream()));
+ } catch (Exception e) {
+ logger.error("Could not open ObjectInputStream to " + socket, e);
+ closed = true;
+@@ -80,7 +80,7 @@ public class SocketNode implements Runnable {
+ try {
+ while (!closed) {
+ // read an event from the wire
+- event = (ILoggingEvent) ois.readObject();
++ event = (ILoggingEvent) hardenedLoggingEventInputStream.readObject();
+ // get a logger from the hierarchy. The name of the logger is taken to
+ // be the name contained in the event.
+ remoteLogger = context.getLogger(event.getLoggerName());
+@@ -110,13 +110,13 @@ public class SocketNode implements Runnable {
+ return;
+ }
+ closed = true;
+- if (ois != null) {
++ if (hardenedLoggingEventInputStream != null) {
+ try {
+- ois.close();
++ hardenedLoggingEventInputStream.close();
+ } catch (IOException e) {
+ logger.warn("Could not close connection.", e);
+ } finally {
+- ois = null;
++ hardenedLoggingEventInputStream = null;
+ }
+ }
+ }
+diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/server/HardenedLoggingEventInputStream.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/HardenedLoggingEventInputStream.java
+new file mode 100644
+index 0000000..522a30f
+--- /dev/null
++++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/HardenedLoggingEventInputStream.java
+@@ -0,0 +1,56 @@
++package ch.qos.logback.classic.net.server;
++
++import java.io.IOException;
++import java.io.InputStream;
++import java.util.ArrayList;
++import java.util.List;
++
++import org.slf4j.helpers.BasicMarker;
++
++import ch.qos.logback.classic.Level;
++import ch.qos.logback.classic.Logger;
++import ch.qos.logback.classic.spi.ClassPackagingData;
++import ch.qos.logback.classic.spi.IThrowableProxy;
++import ch.qos.logback.classic.spi.LoggerContextVO;
++import ch.qos.logback.classic.spi.LoggerRemoteView;
++import ch.qos.logback.classic.spi.LoggingEventVO;
++import ch.qos.logback.classic.spi.StackTraceElementProxy;
++import ch.qos.logback.classic.spi.ThrowableProxy;
++import ch.qos.logback.classic.spi.ThrowableProxyVO;
++import ch.qos.logback.core.net.HardenedObjectInputStream;
++
++public class HardenedLoggingEventInputStream extends HardenedObjectInputStream {
++
++ static final String ARRAY_PREFIX = "[L";
++
++ static public List<String> getWhilelist() {
++ List<String> whitelist = new ArrayList<String>();
++ whitelist.add(LoggingEventVO.class.getName());
++ whitelist.add(LoggerContextVO.class.getName());
++ whitelist.add(LoggerRemoteView.class.getName());
++ whitelist.add(ThrowableProxyVO.class.getName());
++ whitelist.add(BasicMarker.class.getName());
++ whitelist.add(Level.class.getName());
++ whitelist.add(Logger.class.getName());
++ whitelist.add(StackTraceElement.class.getName());
++ whitelist.add(StackTraceElement[].class.getName());
++ whitelist.add(ThrowableProxy.class.getName());
++ whitelist.add(ThrowableProxy[].class.getName());
++ whitelist.add(IThrowableProxy.class.getName());
++ whitelist.add(IThrowableProxy[].class.getName());
++ whitelist.add(StackTraceElementProxy.class.getName());
++ whitelist.add(StackTraceElementProxy[].class.getName());
++ whitelist.add(ClassPackagingData.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/logback-classic/src/main/java/ch/qos/logback/classic/net/server/LogbackClassicSerializationHelper.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/LogbackClassicSerializationHelper.java
+deleted file mode 100644
+index 00a974f..0000000
+--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/server/LogbackClassicSerializationHelper.java
++++ /dev/null
+@@ -1,28 +0,0 @@
+-package ch.qos.logback.classic.net.server;
+-
+-import java.util.ArrayList;
+-import java.util.List;
+-
+-import org.slf4j.helpers.BasicMarker;
+-
+-import ch.qos.logback.classic.Logger;
+-import ch.qos.logback.classic.spi.LoggerContextVO;
+-import ch.qos.logback.classic.spi.LoggingEventVO;
+-import ch.qos.logback.classic.spi.ThrowableProxyVO;
+-
+-public class LogbackClassicSerializationHelper {
+-
+-
+-
+- static public List<String> getWhilelist() {
+- List<String> whitelist = new ArrayList<String>();
+- whitelist.add(LoggingEventVO.class.getName());
+- whitelist.add(LoggerContextVO.class.getName());
+- whitelist.add(ThrowableProxyVO.class.getName());
+- whitelist.add(StackTraceElement.class.getName());
+- whitelist.add(BasicMarker.class.getName());
+- whitelist.add(BasicMarker.class.getName());
+- whitelist.add(Logger.class.getName());
+- return whitelist;
+- }
+-}
+diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderStreamClient.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderStreamClient.java
+index 5be7e24..71e1b0b 100644
+--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderStreamClient.java
++++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderStreamClient.java
+@@ -16,12 +16,12 @@ package ch.qos.logback.classic.net.server;
+ import java.io.EOFException;
+ import java.io.IOException;
+ import java.io.InputStream;
+-import java.io.ObjectInputStream;
+ import java.net.Socket;
+
+ import ch.qos.logback.classic.Logger;
+ import ch.qos.logback.classic.LoggerContext;
+ import ch.qos.logback.classic.spi.ILoggingEvent;
++import ch.qos.logback.core.net.HardenedObjectInputStream;
+ import ch.qos.logback.core.util.CloseUtil;
+
+ /**
+@@ -87,7 +87,7 @@ class RemoteAppenderStreamClient implements RemoteAppenderClient {
+ */
+ public void run() {
+ logger.info(this + ": connected");
+- ObjectInputStream ois = null;
++ HardenedObjectInputStream ois = null;
+ try {
+ ois = createObjectInputStream();
+ while (true) {
+@@ -120,11 +120,11 @@ class RemoteAppenderStreamClient implements RemoteAppenderClient {
+ }
+ }
+
+- private ObjectInputStream createObjectInputStream() throws IOException {
++ private HardenedObjectInputStream createObjectInputStream() throws IOException {
+ if (inputStream != null) {
+- return new ObjectInputStream(inputStream);
++ return new HardenedLoggingEventInputStream(inputStream);
+ }
+- return new ObjectInputStream(socket.getInputStream());
++ return new HardenedLoggingEventInputStream(socket.getInputStream());
+ }
+
+ /**
+diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/HardenedObjectInputStream.java b/logback-core/src/main/java/ch/qos/logback/core/net/HardenedObjectInputStream.java
+index 439e2bd..d1b7301 100644
+--- a/logback-core/src/main/java/ch/qos/logback/core/net/HardenedObjectInputStream.java
++++ b/logback-core/src/main/java/ch/qos/logback/core/net/HardenedObjectInputStream.java
+@@ -6,43 +6,66 @@ import java.io.InvalidClassException;
+ import java.io.ObjectInputStream;
+ import java.io.ObjectStreamClass;
+ import java.util.ArrayList;
+-import java.util.Collections;
+ 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.0
+ */
+ public class HardenedObjectInputStream extends ObjectInputStream {
+
+- List<String> whitelistedClassNames;
+- String[] javaPackages = new String[] {"java.lang", "java.util"};
+-
+- public HardenedObjectInputStream(InputStream in, List<String> whilelist) throws IOException {
++ final List<String> whitelistedClassNames;
++ final static String[] JAVA_PACKAGES = new String[] { "java.lang", "java.util" };
++
++ public HardenedObjectInputStream(InputStream in, String[] whilelist) throws IOException {
+ super(in);
+- this.whitelistedClassNames = Collections.synchronizedList(new ArrayList<String>(whilelist));
++
++ 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)) {
++
++ if (!isWhitelisted(incomingClassName)) {
+ throw new InvalidClassException("Unauthorized deserialization attempt", anObjectStreamClass.getName());
+ }
+-
++
+ return super.resolveClass(anObjectStreamClass);
+ }
+
+ private boolean isWhitelisted(String incomingClassName) {
+- for(int i = 0; i < javaPackages.length; i++) {
+- if(incomingClassName.startsWith(javaPackages[i]))
++ for (int i = 0; i < JAVA_PACKAGES.length; i++) {
++ if (incomingClassName.startsWith(JAVA_PACKAGES[i]))
+ return true;
+ }
+- for(String className: whitelistedClassNames) {
+- if(incomingClassName.equals(className))
++ for (String whiteListed : whitelistedClassNames) {
++ if (incomingClassName.equals(whiteListed))
+ return true;
+ }
+ return false;
+ }
++
++ protected void addToWhitelist(List<String> additionalAuthorizedClasses) {
++ whitelistedClassNames.addAll(additionalAuthorizedClasses);
++ }
+ }
diff --git a/debian/patches/series b/debian/patches/series
index 79138a8..09720d1 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,3 +1,4 @@
01-compile-groovy.patch
02-remove-google-ads.patch
CVE-2017-5929.patch
+CVE-2017-5929-part2.patch
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/logback.git
More information about the pkg-java-commits
mailing list