Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
bbeee8a
Add the very first `log4j-fuzz-test`
vy Jul 12, 2024
e32ca7f
Move away from tests to `fuzzerTestOneInput()` approach
vy Jul 17, 2024
231e2f7
Replace Jackson with the reference JSON implementation
vy Jul 18, 2024
a28314e
Improve function naming
vy Jul 29, 2024
4d5f53d
Delete JSON fuzzing dictionary, it will be provided while running the…
vy Jul 29, 2024
dd5eeb1
Switch to using the downloaded `jazzer_standalone.jar`
vy Jul 29, 2024
8471a78
Fix `generate-uber-jar` execution
vy Jul 29, 2024
7fc3eb2
Split tests into dedicated modules
vy Jul 29, 2024
2843690
Consolidate parameterized and non-parameterized tests
vy Jul 29, 2024
7bb87ad
Fix Spotless failures
vy Jul 29, 2024
efd670b
Merge remote-tracking branch 'origin/2.x' into fuzzing
vy Jul 29, 2024
3993ec0
Add SLF4J-to-Log4j Bridge fuzzers
vy Jul 29, 2024
0de4707
Add `oss-fuzz-build.sh`
vy Jul 31, 2024
a307946
Merge remote-tracking branch 'origin/2.x' into fuzzing
vy Aug 1, 2024
b45934a
Port `develocity.xml` from `2.x`
vy Aug 1, 2024
f557569
Fix broken `log4j-osgi-test/pom.xml`
vy Aug 1, 2024
1f1c2e4
Fix build scripts
vy Aug 1, 2024
6bb3d83
Explain how to use dictionary and corpus
vy Aug 2, 2024
fb037d0
Switch Maven Wrapper from `bin` to `only-script` distribution
vy Aug 8, 2024
c86d2f5
Merge remote-tracking branch 'origin/2.x' into fuzzing
vy Aug 8, 2024
5ef11a0
Fix fuzzer detection
vy Aug 8, 2024
755ccb4
Fix script folder detection
vy Aug 8, 2024
034fe35
Fix classpath detection
vy Aug 8, 2024
22c5016
Reflect OSS-Fuzz project path change
vy Aug 12, 2024
a2ebafe
Merge remote-tracking branch 'origin/2.x' into fuzzing
vy Aug 12, 2024
ea32623
Make wget/git quiet
vy Aug 13, 2024
96033d9
Merge remote-tracking branch 'origin/2.x' into fuzzing
vy Aug 13, 2024
7726392
Merge remote-tracking branch 'origin/2.x' into fuzzing
vy Aug 27, 2024
0c6cd0b
Increase verbosity for troubleshooting (google/oss-fuzz#12349)
vy Aug 27, 2024
cc7ee49
Add classpath verification
vy Aug 27, 2024
e90bd3c
Improve diagnostics
vy Aug 29, 2024
9a31233
Simplify `FUZZING.adoc` instructions
vy Aug 29, 2024
48afb8f
More troubleshooting aid
vy Aug 31, 2024
094580e
Merge remote-tracking branch 'origin/2.x' into fuzzing
vy Aug 31, 2024
f62a4f3
Package the Java runtime
vy Sep 2, 2024
80beda6
Merge remote-tracking branch 'origin/2.x' into fuzzing
vy Sep 2, 2024
a9afe78
Follow symlinks while copying the Java runtime
vy Sep 2, 2024
a7bf040
Report the commit ID
vy Sep 2, 2024
e9edabf
Avoid surrogate character handling in `JsonWriter`
vy Sep 4, 2024
2319db3
Extend JTL codec fuzzing
vy Sep 4, 2024
359342f
Discard JRE crashes
vy Sep 4, 2024
8d59895
Improve documentation
vy Sep 4, 2024
c1df0dc
Fix script in docs
vy Sep 4, 2024
0300b3a
Fix typo
vy Sep 4, 2024
ccaf9f8
Enable `pipefail` needed for correctly capturing the pipe failures
vy Sep 5, 2024
bd325aa
Merge remote-tracking branch 'origin/2.x' into fuzzing
vy Sep 5, 2024
f27affb
Enable `set -x` to troubleshoot build failure
vy Sep 5, 2024
42c0823
Fix premature grep exit
vy Sep 5, 2024
558d363
Last minor changes for the build script
vy Sep 5, 2024
dc84cd2
Decrease JSON length to avoid false positives
vy Sep 5, 2024
44308e6
More troubleshooting aid
vy Sep 9, 2024
5e0e4ba
Merge remote-tracking branch 'origin/2.x' into fuzzing
vy Sep 9, 2024
a3e380d
Fix unbound variable failure
vy Sep 10, 2024
d2af2d7
Fix bash typo
vy Sep 11, 2024
b383895
Try to fix the build script
vy Sep 12, 2024
209bafd
Merge remote-tracking branch 'origin/2.x' into fuzzing
vy Sep 13, 2024
9007360
Dump system memory information on failure
vy Sep 13, 2024
e870738
Add changelog entry
vy Sep 13, 2024
88bca7c
Improve FQCN detection in `Log4jLoggerFacade`
vy Sep 17, 2024
64a30c9
Add the `ApacheNoticeResourceTransformer` shade plugin transformer
vy Sep 17, 2024
7c45e23
Suppress `maven-shade-plugin` complaints
vy Sep 17, 2024
613406f
Improve `log4j-perf-test/README.adoc`
vy Sep 17, 2024
7fb6e12
Improve FQCN detection in `Slf4jLoggerFacade`
vy Sep 17, 2024
5dee111
Merge remote-tracking branch 'origin/2.x' into fuzzing
vy Sep 17, 2024
d8622d9
Apply review feedback
vy Sep 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
# specific language governing permissions and limitations
# under the License.
distributionSha256Sum=8351955a9acf2f83c136c4eee0f6db894ab6265fdbe0a94b32a380307dbaa3e1
distributionType=script
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.8/apache-maven-3.9.8-bin.zip
wrapperSha256Sum=3d8f20ce6103913be8b52aef6d994e0c54705fb527324ceb9b835b338739c7a8
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar
wrapperVersion=3.3.2
106 changes: 106 additions & 0 deletions FUZZING.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
////
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.
////

Log4j contains fuzz tests implemented using https://github.com/CodeIntelligenceTesting/jazzer[Jazzer]footnote:[
We are aware that https://github.com/google/oss-fuzz/discussions/12195[Jazzer is discontinued].
Yet it is still the only mature fuzzing framework in Java and https://google.github.io/oss-fuzz/getting-started/new-project-guide/jvm-lang/#jazzer[the recommended library by OSS-Fuzz].].
These tests are located in `-fuzz-test` prefixed modules; `log4j-core-fuzz-test`, `log4j-layout-template-json-fuzz-test`, etc.

[#oss-fuzz]
== Google OSS-Fuzz

https://github.com/google/oss-fuzz[OSS-Fuzz] is a Google service that continuously runs fuzz tests of critical F/OSS projects on a beefy cluster and reports its findings (bugs, vulnerabilities, etc.) privately to project maintainers.
Log4j provides OSS-Fuzz integration with following helpers:

- https://github.com/google/oss-fuzz/tree/master/projects/log4j2/Dockerfile[Dockerfile] to create a container image for running tests
- link:oss-fuzz-build.sh[`oss-fuzz-build.sh`] to generate fuzz test runner scripts along with all necessary dependencies

[#faq]
== F.A.Q.

Below we will try to answer some frequently asked questions.

[#running]
=== How can I run fuzz tests locally?

. Clone the OSS-Fuzz repository:
+
[source,bash]
----
git clone --depth 1 https://github.com/google/oss-fuzz google-oss-fuzz && cd $_
----

. Build the container image:
+
[source,bash]
----
python infra/helper.py build_image log4j2
----

. Run the container image to build the Log4j project and generate runner scripts along with dependencies:
+
[source,bash]
----
python infra/helper.py build_fuzzers \
--sanitizer address --engine libfuzzer --architecture x86_64 \
log4j2
----

. List generated runner scripts:
+
[source,bash]
----
ls -al build/out/log4j2
----

. Check one of the generated runner scripts:
+
[source,bash]
----
python infra/helper.py check_build \
--sanitizer address --engine libfuzzer --architecture x86_64 \
log4j2 log4j-core-fuzz-test-PatternLayoutFuzzer
----

. Execute one of the generated runner scripts:
+
[source,bash]
----
python infra/helper.py run_fuzzer \
--sanitizer address --engine libfuzzer --architecture x86_64 \
log4j2 log4j-core-fuzz-test-PatternLayoutFuzzer
----

[#view]
=== How can I view fuzzing failures detected by OSS-Fuzz?

The system running fuzzers registered to OSS-Fuzz is called *ClusterFuzz*, which provides https://oss-fuzz.com/[a web interface] for maintainers to monitor the fuzzing results.
Tests outputs and <<#reproduce,reproduction>> inputs for failed tests are stored in https://console.cloud.google.com/storage/browser/log4j2-logs.clusterfuzz-external.appspot.com[a Google Cloud Storage bucket].
Access to both the web interface and the bucket is restricted, and only allowed to https://github.com/google/oss-fuzz/blob/master/projects/log4j2/project.yaml[those configured for the project].

[#reproduce]
=== How can I reproduce fuzzing failures detected by OSS-Fuzz?

Download the associated `.testcase` file from https://console.cloud.google.com/storage/browser/log4j2-logs.clusterfuzz-external.appspot.com[the Google Cloud Storage bucket], and run the following command:

[source,bash]
----
python infra/helper.py reproduce \
log4j2 <FUZZ-TARGET-NAME> <TESTCASE-FILE-PATH>
----

Refer to https://google.github.io/oss-fuzz/advanced-topics/reproducing/[the related OSS-Fuzz documentation] for details.
51 changes: 51 additions & 0 deletions log4j-core-fuzz-test/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j</artifactId>
<version>${revision}</version>
<relativePath>../log4j-parent</relativePath>
</parent>

<artifactId>log4j-core-fuzz-test</artifactId>

<name>Apache Log4j Core fuzz tests</name>

<properties>
<bnd.baseline.skip>true</bnd.baseline.skip>
<log4j.docgen.skip>true</log4j.docgen.skip>
<maven.deploy.skip>true</maven.deploy.skip>
<maven.install.skip>true</maven.install.skip>
<maven.test.skip>true</maven.test.skip>
<sign.skip>true</sign.skip>
</properties>

<dependencies>

<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-fuzz-test</artifactId>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* 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.logging.log4j.core.fuzz;

import static org.apache.logging.log4j.fuzz.FuzzingUtil.createLoggerContext;
import static org.apache.logging.log4j.fuzz.FuzzingUtil.fuzzLogger;

import com.code_intelligence.jazzer.api.FuzzedDataProvider;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.fuzz.EncodingAppender;
import org.apache.logging.log4j.fuzz.FuzzingUtil.Log4jLoggerFacade;
import org.apache.logging.log4j.fuzz.FuzzingUtil.LoggerFacade;
import org.apache.logging.log4j.spi.ExtendedLogger;

public final class PatternLayoutFuzzer {

public static void fuzzerTestOneInput(final FuzzedDataProvider dataProvider) {
final String loggerContextName = PatternLayoutFuzzer.class.getSimpleName() + "LoggerContext";
try (final LoggerContext loggerContext =
createLoggerContext(loggerContextName, EncodingAppender.PLUGIN_NAME, configBuilder -> configBuilder
.newLayout("PatternLayout")
// Enforce using a single message-based converter, i.e., `MessagePatternConverter`
.addAttribute("pattern", "%m"))) {
final ExtendedLogger logger = loggerContext.getLogger(PatternLayoutFuzzer.class);
final LoggerFacade loggerFacade = new Log4jLoggerFacade(logger);
fuzzLogger(loggerFacade, dataProvider);
}
}
}
10 changes: 8 additions & 2 deletions log4j-core-its/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,32 @@
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j</artifactId>
<version>${revision}</version>
<relativePath>../log4j-parent</relativePath>
</parent>

<artifactId>log4j-core-its</artifactId>
<packaging>jar</packaging>

<name>Apache Log4j Core Integration Tests</name>
<description>Integration Tests for the Apache Log4j Implementation</description>

<properties>

<bnd.baseline.skip>true</bnd.baseline.skip>
<log4j.docgen.skip>true</log4j.docgen.skip>
<maven.deploy.skip>true</maven.deploy.skip>
<maven.install.skip>true</maven.install.skip>
<sign.skip>true</sign.skip>
<spotbugs.skip>true</spotbugs.skip>

<!-- Dependency versions -->
<slf4j2.version>2.0.16</slf4j2.version>

</properties>

<dependencyManagement>
Expand Down
1 change: 1 addition & 0 deletions log4j-fuzz-test/.log4j-plugin-processing-activator
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This file is here to activate the `plugin-processing` Maven profile.
77 changes: 77 additions & 0 deletions log4j-fuzz-test/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j</artifactId>
<version>${revision}</version>
<relativePath>../log4j-parent</relativePath>
</parent>

<artifactId>log4j-fuzz-test</artifactId>

<name>Apache Log4j fuzz tests</name>

<properties>

<log4j.docgen.skip>true</log4j.docgen.skip>
<bnd.baseline.skip>true</bnd.baseline.skip>
<maven.deploy.skip>true</maven.deploy.skip>
<maven.test.skip>true</maven.test.skip>
<sign.skip>true</sign.skip>

<!-- dependency versions -->
<json.version>20240303</json.version>

</properties>

<dependencies>

<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</dependency>

<dependency>
<groupId>org.jspecify</groupId>
<artifactId>jspecify</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
</dependency>

<dependency>
<groupId>com.code-intelligence</groupId>
<artifactId>jazzer</artifactId>
</dependency>

<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>${json.version}</version>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* 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.logging.log4j.fuzz;

import static org.assertj.core.api.Assertions.assertThat;

import java.io.Serializable;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Core;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;

/**
* Appender encoding incoming log events using the provided layout.
* It is intended for appender-agnostic fuzzing.
*/
@Plugin(name = EncodingAppender.PLUGIN_NAME, category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE)
public final class EncodingAppender extends AbstractAppender {

public static final String PLUGIN_NAME = "EncodingAppender";

private EncodingAppender(final String name, final Layout<? extends Serializable> layout) {
super(name, null, layout, true, null);
// Guard `PLUGIN_NAME` against copy-paste mistakes
assertThat(PLUGIN_NAME).isEqualTo(getClass().getSimpleName());
}

@PluginFactory
public static EncodingAppender createAppender(
final @PluginAttribute("name") String name, final @PluginElement("layout") Layout<?> layout) {
return new EncodingAppender(name, layout);
}

@Override
public void append(final LogEvent event) {
try {
getLayout().toByteArray(event);
} catch (final Exception ignored) {
// We are inspecting unexpected access.
// Hence, event encoding failures are not of interest.
}
}
}
Loading