Skip to content

Commit

Permalink
CNDB-11076: bump SLF4J version to 2.0.9; bump logback version to 1.4.…
Browse files Browse the repository at this point in the history
…14 to get rid of security holes (#1515)
  • Loading branch information
jakubzytka authored Jan 23, 2025
1 parent 845d600 commit 9f2541a
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 66 deletions.
10 changes: 5 additions & 5 deletions build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -598,11 +598,11 @@
<dependency groupId="org.antlr" artifactId="antlr-runtime" version="3.5.2">
<exclusion groupId="org.antlr" artifactId="stringtemplate"/>
</dependency>
<dependency groupId="org.slf4j" artifactId="slf4j-api" version="1.7.25"/>
<dependency groupId="org.slf4j" artifactId="log4j-over-slf4j" version="1.7.25"/>
<dependency groupId="org.slf4j" artifactId="jcl-over-slf4j" version="1.7.25" />
<dependency groupId="ch.qos.logback" artifactId="logback-core" version="1.2.9"/>
<dependency groupId="ch.qos.logback" artifactId="logback-classic" version="1.2.9"/>
<dependency groupId="org.slf4j" artifactId="slf4j-api" version="2.0.9"/>
<dependency groupId="org.slf4j" artifactId="log4j-over-slf4j" version="2.0.9"/>
<dependency groupId="org.slf4j" artifactId="jcl-over-slf4j" version="2.0.9" />
<dependency groupId="ch.qos.logback" artifactId="logback-core" version="1.4.14"/>
<dependency groupId="ch.qos.logback" artifactId="logback-classic" version="1.4.14"/>
<dependency groupId="com.fasterxml.jackson.core" artifactId="jackson-core" version="2.13.2"/>
<dependency groupId="com.fasterxml.jackson.core" artifactId="jackson-databind" version="2.13.2.2"/>
<dependency groupId="com.fasterxml.jackson.core" artifactId="jackson-annotations" version="2.13.2"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,13 @@

package org.apache.cassandra.utils.logging;

import java.lang.management.ManagementFactory;
import java.security.AccessControlException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.management.JMX;
import javax.management.ObjectName;

import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
Expand All @@ -37,14 +34,14 @@
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.jmx.JMXConfiguratorMBean;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.TurboFilterList;
import ch.qos.logback.classic.turbo.ReconfigureOnChangeFilter;
import ch.qos.logback.classic.turbo.TurboFilter;
import ch.qos.logback.classic.util.ContextInitializer;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.hook.DelayingShutdownHook;
import ch.qos.logback.core.hook.DefaultShutdownHook;
import ch.qos.logback.core.spi.AppenderAttachable;
import org.apache.cassandra.security.ThreadAwareSecurityManager;

Expand Down Expand Up @@ -92,7 +89,7 @@ public void onStartup()
@Override
public void onShutdown()
{
DelayingShutdownHook logbackHook = new DelayingShutdownHook();
DefaultShutdownHook logbackHook = new DefaultShutdownHook();
logbackHook.setContext((LoggerContext) LoggerFactory.getILoggerFactory());
logbackHook.run();
}
Expand All @@ -105,10 +102,11 @@ public void setLoggingLevel(String classQualifier, String rawLevel) throws Excep
// if both classQualifier and rawLevel are empty, reload from configuration
if (StringUtils.isBlank(classQualifier) && StringUtils.isBlank(rawLevel))
{
JMXConfiguratorMBean jmxConfiguratorMBean = JMX.newMBeanProxy(ManagementFactory.getPlatformMBeanServer(),
new ObjectName("ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator"),
JMXConfiguratorMBean.class);
jmxConfiguratorMBean.reloadDefaultConfiguration();
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
lc.reset();

ContextInitializer ci = new ContextInitializer(lc);
ci.autoConfig();
return;
}
// classQualifier is set, but blank level given
Expand Down
2 changes: 1 addition & 1 deletion test/conf/logback-burntest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<define name="instance_id" class="org.apache.cassandra.distributed.impl.InstanceIDDefiner" />

<!-- Shutdown hook ensures that async appender flushes -->
<shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook"/>
<shutdownHook class="ch.qos.logback.core.hook.DefaultShutdownHook"/>

<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">

Expand Down
4 changes: 2 additions & 2 deletions test/conf/logback-dtest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<define name="instance_id" class="org.apache.cassandra.distributed.impl.InstanceIDDefiner" />

<!-- Shutdown hook ensures that async appender flushes -->
<shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook"/>
<shutdownHook class="ch.qos.logback.core.hook.DefaultShutdownHook"/>

<appender name="INSTANCEFILE" class="ch.qos.logback.core.FileAppender">
<file>./build/test/logs/${cassandra.testtag}/${suitename}/${cluster_id}/${instance_id}/system.log</file>
Expand All @@ -34,7 +34,7 @@

<appender name="INSTANCESTDERR" target="System.err" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-5level %date{HH:mm:ss,SSS} %msg%n</pattern>
<pattern>%-5level %date{"HH:mm:ss,SSS"} %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
Expand Down
2 changes: 1 addition & 1 deletion test/conf/logback-test-jenkins.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<configuration debug="false" scan="true" scanPeriod="60 seconds">
<!-- Shutdown hook ensures that async appender flushes -->
<shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook"/>
<shutdownHook class="ch.qos.logback.core.hook.DefaultShutdownHook"/>

<!-- Status listener is used to wrap stdout/stderr and tee to log file -->
<statusListener class="org.apache.cassandra.LogbackStatusListener"/>
Expand Down
2 changes: 1 addition & 1 deletion test/conf/logback-test.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<configuration debug="false" scan="true" scanPeriod="60 seconds">
<!-- Shutdown hook ensures that async appender flushes -->
<shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook"/>
<shutdownHook class="ch.qos.logback.core.hook.DefaultShutdownHook"/>

<!-- Status listener is used to wrap stdout/stderr and tee to log file -->
<statusListener class="org.apache.cassandra.LogbackStatusListener"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,19 @@
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.time.DateUtils;

import org.junit.Assert;
import org.junit.Test;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.ReconfigureOnChangeTask;
import ch.qos.logback.classic.spi.TurboFilterList;
import ch.qos.logback.classic.turbo.ReconfigureOnChangeFilter;
import ch.qos.logback.classic.turbo.TurboFilter;
import org.apache.cassandra.db.marshal.UTF8Type;
import org.apache.cassandra.schema.SchemaConstants;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.cql3.QueryProcessor;
import org.apache.cassandra.cql3.UntypedResultSet;
Expand All @@ -53,13 +49,13 @@
import org.apache.cassandra.db.marshal.TypeParser;
import org.apache.cassandra.exceptions.FunctionExecutionException;
import org.apache.cassandra.exceptions.InvalidRequestException;
import org.apache.cassandra.schema.SchemaConstants;
import org.apache.cassandra.service.ClientState;
import org.apache.cassandra.transport.Event.SchemaChange.Change;
import org.apache.cassandra.transport.Event.SchemaChange.Target;
import org.apache.cassandra.transport.ProtocolVersion;
import org.apache.cassandra.transport.messages.ResultMessage;

import static ch.qos.logback.core.CoreConstants.RECONFIGURE_ON_CHANGE_TASK;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
Expand Down Expand Up @@ -1814,9 +1810,16 @@ public void testEmptyListAndNullInitcond() throws Throwable
public void testLogbackReload() throws Throwable
{
// see https://issues.apache.org/jira/browse/CASSANDRA-11033
Logger l = LoggerFactory.getLogger(AggregationTest.class);
ch.qos.logback.classic.Logger logbackLogger = (ch.qos.logback.classic.Logger) l;
LoggerContext ctx = logbackLogger.getLoggerContext();

ReconfigureOnChangeTask rocTask = new ReconfigureOnChangeTask();
rocTask.setContext(ctx);

// make logback's scan interval 1ms - boilerplate, but necessary for this test
configureLogbackScanPeriod(1L);
ScheduledExecutorService scheduledExecutorService = ctx.getScheduledExecutorService();
ScheduledFuture<?> scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(rocTask, 1, 1,
TimeUnit.MILLISECONDS);
try
{

Expand Down Expand Up @@ -1865,41 +1868,8 @@ public void testLogbackReload() throws Throwable
}
finally
{
configureLogbackScanPeriod(60000L);
}
}

private static void configureLogbackScanPeriod(long millis)
{
Logger l = LoggerFactory.getLogger(AggregationTest.class);
ch.qos.logback.classic.Logger logbackLogger = (ch.qos.logback.classic.Logger) l;
LoggerContext ctx = logbackLogger.getLoggerContext();
TurboFilterList turboFilterList = ctx.getTurboFilterList();
boolean done = false;
for (TurboFilter turboFilter : turboFilterList)
{
if (turboFilter instanceof ReconfigureOnChangeFilter)
{
ReconfigureOnChangeFilter reconfigureFilter = (ReconfigureOnChangeFilter) turboFilter;
reconfigureFilter.setContext(ctx);
reconfigureFilter.setRefreshPeriod(millis);
reconfigureFilter.stop();
reconfigureFilter.start(); // start() sets the next check timestammp
done = true;
break;
}
scheduledFuture.cancel(true);
}

ReconfigureOnChangeTask roct = (ReconfigureOnChangeTask) ctx.getObject(RECONFIGURE_ON_CHANGE_TASK);
if (roct != null)
{
// New functionality in logback - they replaced ReconfigureOnChangeFilter (which runs in the logging code)
// with an async ReconfigureOnChangeTask - i.e. in a thread that does not become sandboxed.
// Let the test run anyway, just we cannot reconfigure it (and it is pointless to reconfigure).
return;
}

assertTrue("ReconfigureOnChangeFilter not in logback's turbo-filter list - do that by adding scan=\"true\" to logback-test.xml's configuration element", done);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/
package org.apache.cassandra.utils;

import org.apache.log4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.cassandra.db.ClusteringComparator;
import org.apache.cassandra.db.DecoratedKey;
Expand Down Expand Up @@ -133,7 +133,7 @@ protected Unfiltered computeNext()
// -- tombstones with DeletionTime.LIVE
if (next.isRangeTombstoneMarker())
{
Logger.getLogger(getClass()).info("tombstone: " + next.toString(metadata()));
LoggerFactory.getLogger(getClass()).info("tombstone: {}", next.toString(metadata()));
RangeTombstoneMarker marker = (RangeTombstoneMarker) next;

if (marker.isOpen(reversed) && marker.openDeletionTime(reversed).isLive() ||
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.cassandra.utils.logging;

import org.junit.Test;
import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;

import static org.junit.Assert.assertSame;

public class LogbackLoggingSupportTest
{
@Test
public void setLogLevelWithoutOptionsReloadsConfiguration() throws Exception
{
// given
LogbackLoggingSupport loggingSupport = new LogbackLoggingSupport();
loggingSupport.onStartup();

Logger rootLogger = (Logger) LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
Level defaultLevel = rootLogger.getLevel();

rootLogger.setLevel(Level.OFF);
assertSame("the log level should have been switched to OFF", Level.OFF, rootLogger.getLevel());

// when
// empty class and level reset to the default configuration
loggingSupport.setLoggingLevel("", "");

// then
assertSame("reset test log level should be reset", defaultLevel, rootLogger.getLevel());
}
}

0 comments on commit 9f2541a

Please sign in to comment.