--- Begin Message ---
- To: Debian Bug Tracking System <submit@bugs.debian.org>
- Subject: jessie-pu: package logback/1:1.1.2-1
- From: Markus Koschany <apo@debian.org>
- Date: Fri, 07 Apr 2017 15:57:07 +0200
- Message-id: <149157342747.21318.3436210064361555264.reportbug@conan>
Package: release.debian.org
Severity: normal
Tags: jessie
User: release.debian.org@packages.debian.org
Usertags: pu
Dear release team,
I have prepared a security update for logback. [1]
The security team marked this issue as no-dsa hence I would like
to include it in the next point-release for Jessie.
Thanks
Markus
[1] https://bugs.debian.org/857343
diff -Nru logback-1.1.2/debian/changelog logback-1.1.2/debian/changelog
--- logback-1.1.2/debian/changelog 2014-04-29 06:26:58.000000000 +0200
+++ logback-1.1.2/debian/changelog 2017-04-07 15:48:29.000000000 +0200
@@ -1,3 +1,13 @@
+logback (1:1.1.2-1+deb8u1) jessie; urgency=high
+
+ * Team upload.
+ * Fix CVE-2017-5929:
+ It was discovered that logback, a flexible logging library for Java, would
+ deserialize data from untrusted sockets. This issue has been resolved by
+ adding a whitelist to use only trusted classes. (Closes: #857343)
+
+ -- Markus Koschany <apo@debian.org> Fri, 07 Apr 2017 15:48:29 +0200
+
logback (1:1.1.2-1) unstable; urgency=medium
* Team upload.
diff -Nru logback-1.1.2/debian/patches/CVE-2017-5929.patch logback-1.1.2/debian/patches/CVE-2017-5929.patch
--- logback-1.1.2/debian/patches/CVE-2017-5929.patch 1970-01-01 01:00:00.000000000 +0100
+++ logback-1.1.2/debian/patches/CVE-2017-5929.patch 2017-04-07 15:48:29.000000000 +0200
@@ -0,0 +1,364 @@
+From: Markus Koschany <apo@debian.org>
+Date: Fri, 7 Apr 2017 14:35:27 +0200
+Subject: CVE-2017-5929
+
+Bug-Debian: https://bugs.debian.org/857343
+Origin: https://github.com/qos-ch/logback/commit/f46044b805bca91efe5fd6afe52257cd02f775f8
+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 | 12 ++--
+ .../logback/classic/net/SimpleSocketServer.java | 1 -
+ .../ch/qos/logback/classic/net/SocketAppender.java | 2 -
+ .../ch/qos/logback/classic/net/SocketNode.java | 15 +++--
+ .../server/HardenedLoggingEventInputStream.java | 56 +++++++++++++++++
+ .../net/server/RemoteAppenderStreamClient.java | 10 +--
+ .../core/net/HardenedObjectInputStream.java | 71 ++++++++++++++++++++++
+ 8 files changed, 159 insertions(+), 23 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
+ create mode 100644 logback-core/src/main/java/ch/qos/logback/core/net/HardenedObjectInputStream.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 32c6654..7db96a3 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,16 +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 +59,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 +79,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/SimpleSocketServer.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/SimpleSocketServer.java
+index e450fff..a0fd7d8 100644
+--- a/logback-classic/src/main/java/ch/qos/logback/classic/net/SimpleSocketServer.java
++++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/SimpleSocketServer.java
+@@ -14,7 +14,6 @@
+ package ch.qos.logback.classic.net;
+
+ import java.io.IOException;
+-import java.lang.reflect.Constructor;
+ import java.net.ServerSocket;
+ import java.net.Socket;
+ import java.util.ArrayList;
+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 1bc74a4..9f2ebef 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@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 98023e8..dcd967c 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@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,8 +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;
+@@ -81,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());
+@@ -111,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/RemoteAppenderStreamClient.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/server/RemoteAppenderStreamClient.java
+index a4b34a9..3901dad 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;
+
+ /**
+@@ -86,7 +86,7 @@ class RemoteAppenderStreamClient implements RemoteAppenderClient {
+ */
+ public void run() {
+ logger.info(this + ": connected");
+- ObjectInputStream ois = null;
++ HardenedObjectInputStream ois = null;
+ try {
+ ois = createObjectInputStream();
+ while (true) {
+@@ -124,11 +124,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
+new file mode 100644
+index 0000000..d1b7301
+--- /dev/null
++++ b/logback-core/src/main/java/ch/qos/logback/core/net/HardenedObjectInputStream.java
+@@ -0,0 +1,71 @@
++package ch.qos.logback.core.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.0
++ */
++public class HardenedObjectInputStream extends ObjectInputStream {
++
++ 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 = 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", anObjectStreamClass.getName());
++ }
++
++ 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);
++ }
++}
diff -Nru logback-1.1.2/debian/patches/series logback-1.1.2/debian/patches/series
--- logback-1.1.2/debian/patches/series 1970-01-01 01:00:00.000000000 +0100
+++ logback-1.1.2/debian/patches/series 2017-04-07 15:48:29.000000000 +0200
@@ -0,0 +1 @@
+CVE-2017-5929.patch
--- End Message ---