From 7f6e601c614ade88f8bba55248573598ef19ef747e914e83b3e68a43d781a40d Mon Sep 17 00:00:00 2001 From: Gus Kenion Date: Thu, 9 Jan 2025 07:30:47 +0000 Subject: [PATCH] CVE-2024-12798 (bsc#1234742), CVE-2024-12801 (bsc#1234743) OBS-URL: https://build.opensuse.org/package/show/Java:packages/logback?expand=0&rev=20 --- .gitattributes | 23 + .gitignore | 1 + _service | 17 + logback-1.2.11.tar.xz | 3 + logback-1.2.3-getCallerClass.patch | 59 ++ logback-1.2.8-jetty.patch | 71 ++ logback-CVE-2024-12801-CVE-2024-12798.patch | 681 ++++++++++++++++++++ logback.changes | 133 ++++ logback.spec | 153 +++++ 9 files changed, 1141 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 _service create mode 100644 logback-1.2.11.tar.xz create mode 100644 logback-1.2.3-getCallerClass.patch create mode 100644 logback-1.2.8-jetty.patch create mode 100644 logback-CVE-2024-12801-CVE-2024-12798.patch create mode 100644 logback.changes create mode 100644 logback.spec diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b03811 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57affb6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.osc diff --git a/_service b/_service new file mode 100644 index 0000000..e7872b5 --- /dev/null +++ b/_service @@ -0,0 +1,17 @@ + + + git + https://github.com/qos-ch/logback.git + v_1.2.11 + v_* + @PARENT_TAG@ + v_(.*) + logback + logback-access/lib + + + *.tar + xz + + + diff --git a/logback-1.2.11.tar.xz b/logback-1.2.11.tar.xz new file mode 100644 index 0000000..ffbbe98 --- /dev/null +++ b/logback-1.2.11.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f19bb3aa39c84a58f5c083220b3b9a7982693242ac99234cf304943bde037572 +size 2970784 diff --git a/logback-1.2.3-getCallerClass.patch b/logback-1.2.3-getCallerClass.patch new file mode 100644 index 0000000..4960505 --- /dev/null +++ b/logback-1.2.3-getCallerClass.patch @@ -0,0 +1,59 @@ +--- logback-1.2.3/logback-classic/src/main/java/ch/qos/logback/classic/spi/PackagingDataCalculator.java 2019-11-29 12:40:38.797022563 +0100 ++++ logback-1.2.3/logback-classic/src/main/java/ch/qos/logback/classic/spi/PackagingDataCalculator.java 2019-11-29 13:11:30.783272712 +0100 +@@ -17,7 +17,8 @@ + import java.security.CodeSource; + import java.util.HashMap; + +-import sun.reflect.Reflection; ++import java.lang.reflect.Method; ++import java.lang.reflect.InvocationTargetException; + + // import java.security.AccessControlException; import java.security.AccessController;import java.security.PrivilegedAction; + /** +@@ -32,27 +33,6 @@ + + HashMap cache = new HashMap(); + +- private static boolean GET_CALLER_CLASS_METHOD_AVAILABLE = false; // private static boolean +- // HAS_GET_CLASS_LOADER_PERMISSION = false; +- +- static { +- // if either the Reflection class or the getCallerClass method +- // are unavailable, then we won't invoke Reflection.getCallerClass() +- // This approach ensures that this class will *run* on JDK's lacking +- // sun.reflect.Reflection class. However, this class will *not compile* +- // on JDKs lacking sun.reflect.Reflection. +- try { +- Reflection.getCallerClass(2); +- GET_CALLER_CLASS_METHOD_AVAILABLE = true; +- } catch (NoClassDefFoundError e) { +- } catch (NoSuchMethodError e) { +- } catch (UnsupportedOperationException e) { +- } catch (Throwable e) { +- System.err.println("Unexpected exception"); +- e.printStackTrace(); +- } +- } +- + public void calculate(IThrowableProxy tp) { + while (tp != null) { + populateFrames(tp.getStackTraceElementProxyArray()); +@@ -81,8 +61,16 @@ + int missfireCount = 0; + for (int i = 0; i < commonFrames; i++) { + Class callerClass = null; +- if (GET_CALLER_CLASS_METHOD_AVAILABLE) { +- callerClass = Reflection.getCallerClass(localFirstCommon + i - missfireCount + 1); ++ try { ++ Class reflect = Class.forName("sun.reflect.Reflection"); ++ Method getCallerClass = reflect.getMethod("getCallerClass",Integer.TYPE); ++ callerClass = (Class)(getCallerClass.invoke(null, localFirstCommon + i - missfireCount + 1)); ++ } catch (ClassNotFoundException e) { ++ } catch (NoSuchMethodException e) { ++ } catch (IllegalAccessException e) { ++ } catch (InvocationTargetException e) { ++ System.err.println("Unexpected exception"); ++ e.printStackTrace(); + } + StackTraceElementProxy step = stepArray[stepFirstCommon + i]; + String stepClassname = step.ste.getClassName(); diff --git a/logback-1.2.8-jetty.patch b/logback-1.2.8-jetty.patch new file mode 100644 index 0000000..c11a41f --- /dev/null +++ b/logback-1.2.8-jetty.patch @@ -0,0 +1,71 @@ +--- logback-1.2.8/logback-access/pom.xml 2021-12-14 12:55:51.000000000 +0100 ++++ logback-1.2.8/logback-access/pom.xml 2021-12-16 15:35:11.255651389 +0100 +@@ -47,6 +47,12 @@ + true + + ++ org.eclipse.jetty ++ jetty-util ++ compile ++ true ++ ++ + org.codehaus.janino + janino + compile +--- logback-1.2.8/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java 2021-12-14 12:55:51.000000000 +0100 ++++ logback-1.2.8/logback-access/src/main/java/ch/qos/logback/access/jetty/RequestLogImpl.java 2021-12-16 15:35:11.255651389 +0100 +@@ -209,11 +209,6 @@ + started = false; + } + +- @Override +- public boolean isRunning() { +- return started; +- } +- + public void setFileName(String fileName) { + this.fileName = fileName; + } +@@ -227,26 +222,6 @@ + return started; + } + +- @Override +- public boolean isStarting() { +- return false; +- } +- +- @Override +- public boolean isStopping() { +- return false; +- } +- +- @Override +- public boolean isStopped() { +- return !started; +- } +- +- @Override +- public boolean isFailed() { +- return false; +- } +- + public boolean isQuiet() { + return quiet; + } +@@ -310,13 +285,7 @@ + return fai.getFilterChainDecision(event); + } + +- @Override +- public void addLifeCycleListener(Listener listener) { +- // we'll implement this when asked +- } +- +- @Override +- public void removeLifeCycleListener(Listener listener) { ++ public void log(Request request, int status, long written) { + // we'll implement this when asked + } + diff --git a/logback-CVE-2024-12801-CVE-2024-12798.patch b/logback-CVE-2024-12801-CVE-2024-12798.patch new file mode 100644 index 0000000..cb3c4d7 --- /dev/null +++ b/logback-CVE-2024-12801-CVE-2024-12798.patch @@ -0,0 +1,681 @@ +This security patch addresses the following vulnerabilities: +CVE-2024-12801 (bsc#1234743) + Server-Side Request Forgery (SSRF) in SaxEventRecorder +CVE-2024-12798 (bsc#1234742) + ACE vulnerability in JaninoEventEvaluator + +It is based on the following upstream patches: +https://github.com/qos-ch/logback/commit/2cb6d520df7592ef1c3a198f1b5df3c10c93e183.patch +https://github.com/qos-ch/logback/commit/5f05041cba4c4ac0a62748c5c527a2da48999f2d.patch +https://github.com/qos-ch/logback/commit/6ddf91890a4c23e855132c89086ad7e069d81755.patch + +The change addresses the above issues by: + - removing SaxEventRecorder and JaninoEventEvaluator + - ignoring external DTD files in DOCTYPE to further reduce vulnerability to SSRF attacks +--- a/logback-access/src/main/java/ch/qos/logback/access/boolex/JaninoEventEvaluator.java ++++ /dev/null +@@ -1,84 +0,0 @@ +-/** +- * Logback: the reliable, generic, fast and flexible logging framework. +- * Copyright (C) 1999-2015, QOS.ch. All rights reserved. +- * +- * This program and the accompanying materials are dual-licensed under +- * either the terms of the Eclipse Public License v1.0 as published by +- * the Eclipse Foundation +- * +- * or (per the licensee's choosing) +- * +- * under the terms of the GNU Lesser General Public License version 2.1 +- * as published by the Free Software Foundation. +- */ +-package ch.qos.logback.access.boolex; +- +-import java.util.ArrayList; +-import java.util.List; +- +-import ch.qos.logback.access.spi.IAccessEvent; +-import ch.qos.logback.core.CoreConstants; +-import ch.qos.logback.core.boolex.JaninoEventEvaluatorBase; +-import ch.qos.logback.core.boolex.Matcher; +- +-public class JaninoEventEvaluator extends JaninoEventEvaluatorBase { +- +- public final static List DEFAULT_PARAM_NAME_LIST = new ArrayList(); +- public final static List DEFAULT_PARAM_TYPE_LIST = new ArrayList(); +- +- static { +- DEFAULT_PARAM_NAME_LIST.add("event"); +- DEFAULT_PARAM_TYPE_LIST.add(IAccessEvent.class); +- } +- +- @Override +- protected String getDecoratedExpression() { +- String expression = getExpression(); +- if (!expression.contains("return")) { +- expression = "return " + expression + ";"; +- addInfo("Adding [return] prefix and a semicolon suffix. Expression becomes [" + expression + "]"); +- addInfo("See also " + CoreConstants.CODES_URL + "#block"); +- } +- return expression; +- } +- +- @Override +- protected String[] getParameterNames() { +- List fullNameList = new ArrayList(); +- fullNameList.addAll(DEFAULT_PARAM_NAME_LIST); +- +- for (int i = 0; i < matcherList.size(); i++) { +- Matcher m = (Matcher) matcherList.get(i); +- fullNameList.add(m.getName()); +- } +- +- return (String[]) fullNameList.toArray(CoreConstants.EMPTY_STRING_ARRAY); +- } +- +- @Override +- protected Class[] getParameterTypes() { +- List fullTypeList = new ArrayList(); +- fullTypeList.addAll(DEFAULT_PARAM_TYPE_LIST); +- for (int i = 0; i < matcherList.size(); i++) { +- fullTypeList.add(Matcher.class); +- } +- return (Class[]) fullTypeList.toArray(CoreConstants.EMPTY_CLASS_ARRAY); +- } +- +- @Override +- protected Object[] getParameterValues(IAccessEvent accessEvent) { +- final int matcherListSize = matcherList.size(); +- +- int i = 0; +- Object[] values = new Object[DEFAULT_PARAM_NAME_LIST.size() + matcherListSize]; +- +- values[i++] = accessEvent; +- +- for (int j = 0; j < matcherListSize; j++) { +- values[i++] = matcherList.get(j); +- } +- +- return values; +- } +- +-} +--- a/logback-classic/src/main/java/ch/qos/logback/classic/boolex/JaninoEventEvaluator.java ++++ /dev/null +@@ -1,152 +0,0 @@ +-/** +- * Logback: the reliable, generic, fast and flexible logging framework. +- * Copyright (C) 1999-2015, QOS.ch. All rights reserved. +- * +- * This program and the accompanying materials are dual-licensed under +- * either the terms of the Eclipse Public License v1.0 as published by +- * the Eclipse Foundation +- * +- * or (per the licensee's choosing) +- * +- * under the terms of the GNU Lesser General Public License version 2.1 +- * as published by the Free Software Foundation. +- */ +-package ch.qos.logback.classic.boolex; +- +-import java.util.ArrayList; +-import java.util.List; +-import java.util.Map; +- +-import org.slf4j.Marker; +- +-import ch.qos.logback.classic.Level; +-import ch.qos.logback.classic.spi.ILoggingEvent; +-import ch.qos.logback.classic.spi.IThrowableProxy; +-import ch.qos.logback.classic.spi.LoggerContextVO; +-import ch.qos.logback.classic.spi.ThrowableProxy; +-import ch.qos.logback.core.CoreConstants; +-import ch.qos.logback.core.boolex.JaninoEventEvaluatorBase; +-import ch.qos.logback.core.boolex.Matcher; +- +-public class JaninoEventEvaluator extends JaninoEventEvaluatorBase { +- +- public final static String IMPORT_LEVEL = "import ch.qos.logback.classic.Level;\r\n"; +- +- public final static List DEFAULT_PARAM_NAME_LIST = new ArrayList(); +- public final static List DEFAULT_PARAM_TYPE_LIST = new ArrayList(); +- +- static { +- DEFAULT_PARAM_NAME_LIST.add("DEBUG"); +- DEFAULT_PARAM_NAME_LIST.add("INFO"); +- DEFAULT_PARAM_NAME_LIST.add("WARN"); +- DEFAULT_PARAM_NAME_LIST.add("ERROR"); +- +- DEFAULT_PARAM_NAME_LIST.add("event"); +- DEFAULT_PARAM_NAME_LIST.add("message"); +- +- DEFAULT_PARAM_NAME_LIST.add("formattedMessage"); +- DEFAULT_PARAM_NAME_LIST.add("logger"); +- DEFAULT_PARAM_NAME_LIST.add("loggerContext"); +- DEFAULT_PARAM_NAME_LIST.add("level"); +- DEFAULT_PARAM_NAME_LIST.add("timeStamp"); +- DEFAULT_PARAM_NAME_LIST.add("marker"); +- DEFAULT_PARAM_NAME_LIST.add("mdc"); +- DEFAULT_PARAM_NAME_LIST.add("throwableProxy"); +- DEFAULT_PARAM_NAME_LIST.add("throwable"); +- +- DEFAULT_PARAM_TYPE_LIST.add(int.class); +- DEFAULT_PARAM_TYPE_LIST.add(int.class); +- DEFAULT_PARAM_TYPE_LIST.add(int.class); +- DEFAULT_PARAM_TYPE_LIST.add(int.class); +- +- DEFAULT_PARAM_TYPE_LIST.add(ILoggingEvent.class); +- DEFAULT_PARAM_TYPE_LIST.add(String.class); +- DEFAULT_PARAM_TYPE_LIST.add(String.class); +- DEFAULT_PARAM_TYPE_LIST.add(String.class); +- DEFAULT_PARAM_TYPE_LIST.add(LoggerContextVO.class); +- DEFAULT_PARAM_TYPE_LIST.add(int.class); +- DEFAULT_PARAM_TYPE_LIST.add(long.class); +- DEFAULT_PARAM_TYPE_LIST.add(Marker.class); +- DEFAULT_PARAM_TYPE_LIST.add(Map.class); +- DEFAULT_PARAM_TYPE_LIST.add(IThrowableProxy.class); +- DEFAULT_PARAM_TYPE_LIST.add(Throwable.class); +- } +- +- protected String getDecoratedExpression() { +- String expression = getExpression(); +- if (!expression.contains("return")) { +- expression = "return " + expression + ";"; +- addInfo("Adding [return] prefix and a semicolon suffix. Expression becomes [" + expression + "]"); +- addInfo("See also " + CoreConstants.CODES_URL + "#block"); +- +- } +- return IMPORT_LEVEL + expression; +- } +- +- protected String[] getParameterNames() { +- List fullNameList = new ArrayList(); +- fullNameList.addAll(DEFAULT_PARAM_NAME_LIST); +- +- for (int i = 0; i < matcherList.size(); i++) { +- Matcher m = (Matcher) matcherList.get(i); +- fullNameList.add(m.getName()); +- } +- +- return (String[]) fullNameList.toArray(CoreConstants.EMPTY_STRING_ARRAY); +- } +- +- protected Class[] getParameterTypes() { +- List fullTypeList = new ArrayList(); +- fullTypeList.addAll(DEFAULT_PARAM_TYPE_LIST); +- for (int i = 0; i < matcherList.size(); i++) { +- fullTypeList.add(Matcher.class); +- } +- return (Class[]) fullTypeList.toArray(CoreConstants.EMPTY_CLASS_ARRAY); +- } +- +- protected Object[] getParameterValues(ILoggingEvent loggingEvent) { +- final int matcherListSize = matcherList.size(); +- +- int i = 0; +- Object[] values = new Object[DEFAULT_PARAM_NAME_LIST.size() + matcherListSize]; +- +- values[i++] = Level.DEBUG_INTEGER; +- values[i++] = Level.INFO_INTEGER; +- values[i++] = Level.WARN_INTEGER; +- values[i++] = Level.ERROR_INTEGER; +- +- values[i++] = loggingEvent; +- values[i++] = loggingEvent.getMessage(); +- values[i++] = loggingEvent.getFormattedMessage(); +- values[i++] = loggingEvent.getLoggerName(); +- values[i++] = loggingEvent.getLoggerContextVO(); +- values[i++] = loggingEvent.getLevel().toInteger(); +- values[i++] = loggingEvent.getTimeStamp(); +- // In order to avoid NullPointerException, we could push a dummy marker if +- // the event's marker is null. However, this would surprise user who +- // expect to see a null marker instead of a dummy one. +- values[i++] = loggingEvent.getMarker(); +- values[i++] = loggingEvent.getMDCPropertyMap(); +- +- IThrowableProxy iThrowableProxy = loggingEvent.getThrowableProxy(); +- +- if (iThrowableProxy != null) { +- values[i++] = iThrowableProxy; +- if (iThrowableProxy instanceof ThrowableProxy) { +- values[i++] = ((ThrowableProxy) iThrowableProxy).getThrowable(); +- } else { +- values[i++] = null; +- } +- } else { +- values[i++] = null; +- values[i++] = null; +- } +- +- for (int j = 0; j < matcherListSize; j++) { +- values[i++] = (Matcher) matcherList.get(j); +- } +- +- return values; +- } +- +-} +--- a/logback-classic/src/main/java/ch/qos/logback/classic/util/DefaultNestedComponentRules.java ++++ b/logback-classic/src/main/java/ch/qos/logback/classic/util/DefaultNestedComponentRules.java +@@ -14,7 +14,6 @@ + package ch.qos.logback.classic.util; + + import ch.qos.logback.classic.PatternLayout; +-import ch.qos.logback.classic.boolex.JaninoEventEvaluator; + import ch.qos.logback.classic.encoder.PatternLayoutEncoder; + import ch.qos.logback.core.AppenderBase; + import ch.qos.logback.core.UnsynchronizedAppenderBase; +@@ -38,8 +37,6 @@ public class DefaultNestedComponentRules + registry.add(AppenderBase.class, "encoder", PatternLayoutEncoder.class); + registry.add(UnsynchronizedAppenderBase.class, "encoder", PatternLayoutEncoder.class); + +- registry.add(EvaluatorFilter.class, "evaluator", JaninoEventEvaluator.class); +- + SSLNestedComponentRegistryRules.addDefaultNestedComponentRegistryRules(registry); + } + +--- /dev/null ++++ b/logback-core-blackbox/src/test/blackboxInput/joran/conditional/ifWithExec.xml +@@ -0,0 +1,28 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +--- a/logback-core/src/main/java/ch/qos/logback/core/boolex/JaninoEventEvaluatorBase.java ++++ /dev/null +@@ -1,95 +0,0 @@ +-/** +- * Logback: the reliable, generic, fast and flexible logging framework. +- * Copyright (C) 1999-2015, QOS.ch. All rights reserved. +- * +- * This program and the accompanying materials are dual-licensed under +- * either the terms of the Eclipse Public License v1.0 as published by +- * the Eclipse Foundation +- * +- * or (per the licensee's choosing) +- * +- * under the terms of the GNU Lesser General Public License version 2.1 +- * as published by the Free Software Foundation. +- */ +-package ch.qos.logback.core.boolex; +- +-import java.util.ArrayList; +-import java.util.List; +- +-import org.codehaus.janino.ScriptEvaluator; +- +-/** +- * Abstract class which sets the groundwork for janino based evaluations. +- * +- * @author Ceki Gülcü +- * +- * @param +- */ +-abstract public class JaninoEventEvaluatorBase extends EventEvaluatorBase { +- +- static Class EXPRESSION_TYPE = boolean.class; +- static Class[] THROWN_EXCEPTIONS = new Class[1]; +- +- static public final int ERROR_THRESHOLD = 4; +- static { +- THROWN_EXCEPTIONS[0] = EvaluationException.class; +- } +- +- private String expression; +- +- ScriptEvaluator scriptEvaluator; +- private int errorCount = 0; +- +- abstract protected String getDecoratedExpression(); +- +- abstract protected String[] getParameterNames(); +- +- abstract protected Class[] getParameterTypes(); +- +- abstract protected Object[] getParameterValues(E event); +- +- protected List matcherList = new ArrayList(); +- +- @Override +- public void start() { +- try { +- assert context != null; +- scriptEvaluator = new ScriptEvaluator(getDecoratedExpression(), EXPRESSION_TYPE, getParameterNames(), getParameterTypes(), THROWN_EXCEPTIONS); +- super.start(); +- } catch (Exception e) { +- addError("Could not start evaluator with expression [" + expression + "]", e); +- } +- } +- +- public boolean evaluate(E event) throws EvaluationException { +- if (!isStarted()) { +- throw new IllegalStateException("Evaluator [" + name + "] was called in stopped state"); +- } +- try { +- Boolean result = (Boolean) scriptEvaluator.evaluate(getParameterValues(event)); +- return result.booleanValue(); +- } catch (Exception ex) { +- errorCount++; +- if (errorCount >= ERROR_THRESHOLD) { +- stop(); +- } +- throw new EvaluationException("Evaluator [" + name + "] caused an exception", ex); +- } +- } +- +- public String getExpression() { +- return expression; +- } +- +- public void setExpression(String expression) { +- this.expression = expression; +- } +- +- public void addMatcher(Matcher matcher) { +- matcherList.add(matcher); +- } +- +- public List getMatcherList() { +- return matcherList; +- } +-} +--- a/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEventRecorder.java ++++ b/logback-core/src/main/java/ch/qos/logback/core/joran/event/SaxEventRecorder.java +@@ -15,6 +15,7 @@ package ch.qos.logback.core.joran.event; + + import static ch.qos.logback.core.CoreConstants.XML_PARSING; + ++import java.io.ByteArrayInputStream; + import java.io.IOException; + import java.io.InputStream; + import java.util.ArrayList; +@@ -45,6 +46,26 @@ public class SaxEventRecorder extends De + cai = new ContextAwareImpl(context, this); + } + ++ /** ++ * An implementation which disallows external DTDs ++ * ++ * @param publicId The public identifier, or null if none is ++ * available. ++ * @param systemId The system identifier provided in the XML ++ * document. ++ * @return ++ * @throws SAXException ++ * @throws IOException ++ * @since 1.5.13 ++ */ ++ @Override ++ public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { ++ addWarn("Document Type Declaration (DOCTYPE) with external file reference is"); ++ addWarn("disallowed to prevent Server-Side Request Forgery (SSRF) attacks."); ++ addWarn("returning contents of SYSTEM " +systemId+ " as a white space"); ++ return new InputSource(new ByteArrayInputStream(" ".getBytes())); ++ } ++ + public List saxEventList = new ArrayList(); + Locator locator; + ElementPath globalElementPath = new ElementPath(); +@@ -102,7 +123,6 @@ public class SaxEventRecorder extends De + } + + public void startElement(String namespaceURI, String localName, String qName, Attributes atts) { +- + String tagName = getTagName(localName, qName); + globalElementPath.push(tagName); + ElementPath current = globalElementPath.duplicate(); +--- a/logback-core/src/main/java/ch/qos/logback/core/joran/event/stax/StaxEventRecorder.java ++++ /dev/null +@@ -1,116 +0,0 @@ +-/** +- * Logback: the reliable, generic, fast and flexible logging framework. +- * Copyright (C) 1999-2015, QOS.ch. All rights reserved. +- * +- * This program and the accompanying materials are dual-licensed under +- * either the terms of the Eclipse Public License v1.0 as published by +- * the Eclipse Foundation +- * +- * or (per the licensee's choosing) +- * +- * under the terms of the GNU Lesser General Public License version 2.1 +- * as published by the Free Software Foundation. +- */ +-package ch.qos.logback.core.joran.event.stax; +- +-import ch.qos.logback.core.Context; +-import ch.qos.logback.core.joran.spi.ElementPath; +-import ch.qos.logback.core.joran.spi.JoranException; +-import ch.qos.logback.core.spi.ContextAwareBase; +- +-import javax.xml.stream.XMLEventReader; +-import javax.xml.stream.XMLInputFactory; +-import javax.xml.stream.XMLStreamException; +-import javax.xml.stream.events.Characters; +-import javax.xml.stream.events.EndElement; +-import javax.xml.stream.events.StartElement; +-import javax.xml.stream.events.XMLEvent; +-import java.io.InputStream; +-import java.util.ArrayList; +-import java.util.List; +- +-public class StaxEventRecorder extends ContextAwareBase { +- +- List eventList = new ArrayList(); +- ElementPath globalElementPath = new ElementPath(); +- +- public StaxEventRecorder(Context context) { +- setContext(context); +- } +- +- public void recordEvents(InputStream inputStream) throws JoranException { +- try { +- XMLEventReader xmlEventReader = XMLInputFactory.newInstance().createXMLEventReader(inputStream); +- read(xmlEventReader); +- } catch (XMLStreamException e) { +- throw new JoranException("Problem parsing XML document. See previously reported errors.", e); +- } +- } +- +- public List getEventList() { +- return eventList; +- } +- +- private void read(XMLEventReader xmlEventReader) throws XMLStreamException { +- while (xmlEventReader.hasNext()) { +- XMLEvent xmlEvent = xmlEventReader.nextEvent(); +- switch (xmlEvent.getEventType()) { +- case XMLEvent.START_ELEMENT: +- addStartElement(xmlEvent); +- break; +- case XMLEvent.CHARACTERS: +- addCharacters(xmlEvent); +- break; +- case XMLEvent.END_ELEMENT: +- addEndEvent(xmlEvent); +- break; +- default: +- break; +- } +- } +- } +- +- private void addStartElement(XMLEvent xmlEvent) { +- StartElement se = xmlEvent.asStartElement(); +- String tagName = se.getName().getLocalPart(); +- globalElementPath.push(tagName); +- ElementPath current = globalElementPath.duplicate(); +- StartEvent startEvent = new StartEvent(current, tagName, se.getAttributes(), se.getLocation()); +- eventList.add(startEvent); +- } +- +- private void addCharacters(XMLEvent xmlEvent) { +- Characters characters = xmlEvent.asCharacters(); +- StaxEvent lastEvent = getLastEvent(); +- +- if (lastEvent instanceof BodyEvent) { +- BodyEvent be = (BodyEvent) lastEvent; +- be.append(characters.getData()); +- } else { +- // ignore space only text if the previous event is not a BodyEvent +- if (!characters.isWhiteSpace()) { +- BodyEvent bodyEvent = new BodyEvent(characters.getData(), xmlEvent.getLocation()); +- eventList.add(bodyEvent); +- } +- } +- } +- +- private void addEndEvent(XMLEvent xmlEvent) { +- EndElement ee = xmlEvent.asEndElement(); +- String tagName = ee.getName().getLocalPart(); +- EndEvent endEvent = new EndEvent(tagName, ee.getLocation()); +- eventList.add(endEvent); +- globalElementPath.pop(); +- } +- +- StaxEvent getLastEvent() { +- if (eventList.isEmpty()) { +- return null; +- } +- int size = eventList.size(); +- if (size == 0) +- return null; +- return eventList.get(size - 1); +- } +- +-} +--- a/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLParametersConfiguration.java ++++ b/logback-core/src/main/java/ch/qos/logback/core/net/ssl/SSLParametersConfiguration.java +@@ -19,8 +19,6 @@ import java.util.List; + + import javax.net.ssl.SSLEngine; + +-import org.codehaus.janino.Java; +- + import ch.qos.logback.core.spi.ContextAwareBase; + import ch.qos.logback.core.util.OptionHelper; + import ch.qos.logback.core.util.StringCollectionUtil; +--- /dev/null ++++ b/logback-core/src/test/input/joran/event-ssrf.xml +@@ -0,0 +1,27 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ XXX& ++ ++ +\ No newline at end of file +--- a/logback-classic/src/main/java/ch/qos/logback/classic/joran/action/EvaluatorAction.java ++++ /dev/null +@@ -1,23 +0,0 @@ +-/** +- * Logback: the reliable, generic, fast and flexible logging framework. +- * Copyright (C) 1999-2015, QOS.ch. All rights reserved. +- * +- * This program and the accompanying materials are dual-licensed under +- * either the terms of the Eclipse Public License v1.0 as published by +- * the Eclipse Foundation +- * +- * or (per the licensee's choosing) +- * +- * under the terms of the GNU Lesser General Public License version 2.1 +- * as published by the Free Software Foundation. +- */ +-package ch.qos.logback.classic.joran.action; +- +-import ch.qos.logback.classic.boolex.JaninoEventEvaluator; +-import ch.qos.logback.core.joran.action.AbstractEventEvaluatorAction; +- +-public class EvaluatorAction extends AbstractEventEvaluatorAction { +- protected String defaultClassName() { +- return JaninoEventEvaluator.class.getName(); +- } +-} +--- a/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java ++++ b/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java +@@ -46,7 +46,6 @@ public class JoranConfigurator extends J + rs.addRule(new ElementSelector("configuration/contextName"), new ContextNameAction()); + rs.addRule(new ElementSelector("configuration/contextListener"), new LoggerContextListenerAction()); + rs.addRule(new ElementSelector("configuration/insertFromJNDI"), new InsertFromJNDIAction()); +- rs.addRule(new ElementSelector("configuration/evaluator"), new EvaluatorAction()); + + rs.addRule(new ElementSelector("configuration/appender/sift"), new SiftAction()); + rs.addRule(new ElementSelector("configuration/appender/sift/*"), new NOPAction()); +--- a/logback-access/src/main/java/ch/qos/logback/access/joran/JoranConfigurator.java ++++ b/logback-access/src/main/java/ch/qos/logback/access/joran/JoranConfigurator.java +@@ -15,7 +15,6 @@ package ch.qos.logback.access.joran; + + import ch.qos.logback.access.PatternLayout; + import ch.qos.logback.access.PatternLayoutEncoder; +-import ch.qos.logback.access.boolex.JaninoEventEvaluator; + import ch.qos.logback.access.joran.action.ConfigurationAction; + import ch.qos.logback.access.joran.action.EvaluatorAction; + import ch.qos.logback.access.sift.SiftAction; +@@ -67,7 +66,6 @@ public class JoranConfigurator extends J + @Override + protected void addDefaultNestedComponentRegistryRules(DefaultNestedComponentRegistry registry) { + registry.add(AppenderBase.class, "layout", PatternLayout.class); +- registry.add(EvaluatorFilter.class, "evaluator", JaninoEventEvaluator.class); + + registry.add(AppenderBase.class, "encoder", PatternLayoutEncoder.class); + registry.add(UnsynchronizedAppenderBase.class, "encoder", PatternLayoutEncoder.class); +--- a/logback-access/src/main/java/ch/qos/logback/access/joran/action/EvaluatorAction.java ++++ b/logback-access/src/main/java/ch/qos/logback/access/joran/action/EvaluatorAction.java +@@ -13,13 +13,12 @@ + */ + package ch.qos.logback.access.joran.action; + +-import ch.qos.logback.access.boolex.JaninoEventEvaluator; + import ch.qos.logback.core.joran.action.AbstractEventEvaluatorAction; + + public class EvaluatorAction extends AbstractEventEvaluatorAction { + + @Override + protected String defaultClassName() { +- return JaninoEventEvaluator.class.getName(); ++ return AbstractEventEvaluatorAction.class.getName(); + } + } diff --git a/logback.changes b/logback.changes new file mode 100644 index 0000000..7e6173c --- /dev/null +++ b/logback.changes @@ -0,0 +1,133 @@ +------------------------------------------------------------------- +Wed Jan 8 13:10:15 UTC 2025 - Gus Kenion + +- CVE-2024-12798 (bsc#1234742) Arbitrary code execution via + JaninoEventEvaluator + * Resolution: remove JaninoEventEvaluator +- CVE-2024-12801 (bsc#1234743) Server-Side Request Forgery (SSRF) + in SaxEventRecorder + * Resolution: prevent Server-Side Request Forgery (SSRF) attacks + by ignoring external DTD files in DOCTYPE + * Remove SaxEventRecorder + +------------------------------------------------------------------- +Wed Feb 21 10:48:45 UTC 2024 - Gus Kenion + +- Use %patch -P N instead of deprecated %patchN. + +------------------------------------------------------------------- +Sat Sep 9 14:35:55 UTC 2023 - Fridrich Strba + +- Reproducible builds: use SOURCE_DATE_EPOCH for timestamp + +------------------------------------------------------------------- +Thu Apr 28 04:54:39 UTC 2022 - Fridrich Strba + +- Upgrade to upstream version 1.2.11 + * Backported fix for LOGBACK-1027. + * Fixed incorrect String cast in JNDIUtil. This corrects + LOGBACK-1604. + * In SMTPAppenderBase empty username parameter is now treated the + same way as null. This fixes LOGBACK-1594. + * ContextInitializer no longer complains about missing + logback.groovy configuration file. This fixes LOGBACK-1601. + * In response to CVE-2021-42550 (aka LOGBACK-1591) the following + steps were made: + 1) Hardened logback's JNDI lookup mechanism to only honor + requests in the java: namespace. All other types of requests + are ignored. + 2) SMTPAppender was hardened. + 3) Temporarily removed DB support for security reasons. + 4) Removed Groovy configuration support. As logging is so + pervasive and configuration with Groovy is probably too + powerful, this feature is unlikely to be reinstated for + security reasons. + The aforementioned vulnerability requires write access to + logback's configuration file as a prerequisite. A successul + RCE attack with CVE-2021-42550 requires all of the following + conditions to be met: + + write access to logback.xml + + use of versions < 1.2.9 + + reloading of poisoned configuration data, which implies + application restart or scan="true" set prior to attack +- Set project.build.sourceEncoding property to ISO-8859-1 to + avoid the new maven-resources-plugin chocking on trying to filter + in UTF-8 encoding JKS (binary) resources + +------------------------------------------------------------------- +Tue Feb 22 18:16:52 UTC 2022 - Fridrich Strba + +- Do not build against the log4j12 packages + +------------------------------------------------------------------- +Fri Dec 17 12:11:00 UTC 2021 - Fridrich Strba + +- Do not execute goals generateTestStubs and compileTests of + gmavenplus-plugin, since we are not compiling or runnig tests + during the rpm build. This also allows us to use a wider range + of gmavenplus-plugin versions, since those executions changed + names in 1.6. + +------------------------------------------------------------------- +Thu Dec 16 16:21:39 UTC 2021 - Fridrich Strba + +- Upgrade to version 1.2.8 (bsc#1193795) + * Changes of version 1.2.8 + + In response to LOGBACK-1591, all JNDI lookup code in logback + has been disabled until further notice. This impacts + ContextJNDISelector and element in + configuration files. + + Also in response to LOGBACK-1591, all database (JDBC) related + code in the project has been removed with no replacement. + + Note that the vulnerability mentioned in LOGBACK-1591 requires + write access to logback's configuration file as a + prerequisite. The log4Shell/CVE-2021-44228 and LOGBACK-1591 + are of different severity levels. A successful RCE requires + all of the following conditions to be met: + - write access to logback.xml + - use of versions < 1.2.8 + - reloading of poisoned configuration data, which implies + application restart or scan="true" set prior to attack + + As an additional extra precaution, in addition to upgrading to + logback version 1.2.8, the users are advised to set their + logback configuration files as read-only. + * Changes of version 1.2.7 + + Added hostnameVerification to property SSLSocketAppender. + This fixes LOGBACK-1574. + * Changes of version 1.2.6 + + To prevent XML eXternal Entity injection (XXE) attacks, Joran + no longer reads external entities passed in XML files. This + fixes LOGBACK-1465. + * Changes of version 1.2.5 + + Instead of an Appender, the LayoutWrappingEncoder now accepts + a variable of type ContextAware as a parent. This fixes + LOGBACK-1326. + * Changes of version 1.2.4 + + Added support for minimum length in %i filename pattern. This + fixes LOGBACK-1248. + + For size bound log file archiving, allow + TimeBasedArchiveRemove to remove files with indexes containing + upto 5 digits. This fixes LOGBACK-1175. + + Added %prefix composite converter which automatically prefixes + child converter output with the name of the converter. This + feature is quite handy in environments where log files need to + be parsed and monitored. +- Changed patch: + * logback-1.1.11-jetty.patch -> logback-1.2.8-jetty.patch + + Rediff to changed context + +------------------------------------------------------------------- +Fri Nov 29 12:15:18 UTC 2019 - Fridrich Strba + +- Do not force building with java < 9 +- Specify maven.compiler.release=8 to access the + java.util.function.Supplier API, introduced in java 8 +- Added patch: + * logback-1.2.3-getCallerClass.patch + + Access the sun.reflect.Reflection.getCallerClass by + reflection, in order to be able to build with jdk >= 9 + +------------------------------------------------------------------- +Sun Nov 17 19:45:03 UTC 2019 - Fridrich Strba + +- Initial packaging of logback 1.2.3 diff --git a/logback.spec b/logback.spec new file mode 100644 index 0000000..fc6c6b3 --- /dev/null +++ b/logback.spec @@ -0,0 +1,153 @@ +# +# spec file for package logback +# +# Copyright (c) 2025 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + + +Name: logback +Version: 1.2.11 +Release: 0 +Summary: A Java logging library +License: EPL-1.0 OR LGPL-2.1-or-later +URL: https://logback.qos.ch/ +Source0: %{name}-%{version}.tar.xz +# Remove deprecated methods +Patch0: %{name}-1.2.8-jetty.patch +Patch1: logback-1.2.3-getCallerClass.patch +Patch2: logback-CVE-2024-12801-CVE-2024-12798.patch +BuildRequires: fdupes +BuildRequires: maven-local +BuildRequires: mvn(javax.mail:mail) +BuildRequires: mvn(javax.servlet:javax.servlet-api) +BuildRequires: mvn(junit:junit) +BuildRequires: mvn(log4j:log4j) +BuildRequires: mvn(org.apache.ant:ant-junit) +BuildRequires: mvn(org.apache.felix:maven-bundle-plugin) +BuildRequires: mvn(org.apache.maven.plugins:maven-antrun-plugin) +BuildRequires: mvn(org.apache.tomcat:tomcat-catalina) +BuildRequires: mvn(org.apache.tomcat:tomcat-coyote) +BuildRequires: mvn(org.codehaus.janino:janino) +BuildRequires: mvn(org.eclipse.jetty:jetty-server) +BuildRequires: mvn(org.eclipse.jetty:jetty-util) +BuildRequires: mvn(org.fusesource.jansi:jansi) +BuildRequires: mvn(org.slf4j:slf4j-api) +BuildRequires: mvn(org.slf4j:slf4j-ext) +BuildArch: noarch + +%description +Logback is intended as a successor to the popular log4j project. At present +time, logback is divided into three modules, logback-core, logback-classic +and logback-access. + +The logback-core module lays the groundwork for the other two modules. The +logback-classic module can be assimilated to a significantly improved +version of log4j. Moreover, logback-classic natively implements the SLF4J +API so that you can readily switch back and forth between logback and other +logging frameworks such as log4j or java.util.logging (JUL). + +The logback-access module integrates with Servlet containers, such as +Tomcat and Jetty, to provide HTTP-access log functionality. Note that you +could easily build your own module on top of logback-core. + +%package javadoc +Summary: Javadoc for %{name} + +%description javadoc +API documentation for the Logback library + +%package access +Summary: Logback-access module for Servlet integration + +%description access +The logback-access module integrates with Servlet containers, such as Tomcat +and Jetty, to provide HTTP-access log functionality. Note that you could +easily build your own module on top of logback-core. + +%package examples +Summary: Logback Examples Module + +%description examples +logback-examples module. + +%prep +%setup -q +chmod -x README.md LICENSE.txt +find . -type f -exec chmod -x {} \; +chmod +x %{name}-examples/src/main/resources/setClasspath.sh + +%patch -P 0 -p1 +%patch -P 1 -p1 +%patch -P 2 -p1 + +%pom_remove_plugin :maven-source-plugin +%pom_remove_plugin :findbugs-maven-plugin +%pom_remove_plugin -r :maven-dependency-plugin +%pom_remove_plugin -r :cobertura-maven-plugin + +rm -r %{name}-*/src/test/java/* +# remove test deps +# ch.qos.logback:logback-core:test-jar +%pom_xpath_remove -r "pom:dependency[pom:type = 'test-jar']" +%pom_xpath_remove -r "pom:dependency[pom:scope = 'test']" + +# bundle-test-jar +%pom_xpath_remove -r "pom:plugin[pom:artifactId = 'maven-jar-plugin']/pom:executions" + +# com.oracle:ojdbc14:10.2.0.1 com.microsoft.sqlserver:sqljdbc4:2.0 +%pom_xpath_remove "pom:project/pom:profiles/pom:profile[pom:id = 'host-orion']" %{name}-access + +%pom_xpath_remove "pom:project/pom:profiles/pom:profile[pom:id = 'javadocjar']" + +# disable for now +%pom_disable_module logback-site + +%pom_xpath_remove "pom:build/pom:extensions" + +%{mvn_package} ":%{name}-access" access +%{mvn_package} ":%{name}-examples" examples + +%build + +%{mvn_build} -f -- \ + -Dproject.build.outputTimestamp=$(date -u -d @${SOURCE_DATE_EPOCH:-$(date +%%s)} +%%Y-%%m-%%dT%%H:%%M:%%SZ) \ +%if %{?pkg_vcmp:%pkg_vcmp java-devel >= 9}%{!?pkg_vcmp:0} + -Dmaven.compiler.release=8 \ +%endif + -Dsource=8 -Dproject.build.sourceEncoding=ISO-8859-1 + +%install +%mvn_install +%fdupes -s %{buildroot}%{_javadocdir} + +install -d -m 755 %{buildroot}%{_datadir}/%{name}/examples +cp -r %{name}-examples/src %{buildroot}%{_datadir}/%{name}/examples +ln -sf %{_mavenpomdir}/%{name}/%{name}-examples.pom %{buildroot}%{_datadir}/%{name}/examples/pom.xml +%fdupes -s %{buildroot}%{_datadir}/%{name} + +%files -f .mfiles +%doc README.md +%license LICENSE.txt + +%files javadoc -f .mfiles-javadoc +%license LICENSE.txt + +%files access -f .mfiles-access +%license LICENSE.txt + +%files examples -f .mfiles-examples +%license LICENSE.txt +%{_datadir}/%{name} + +%changelog