Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 24 additions & 0 deletions projects/exim/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2025 Google LLC
#
# Licensed 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.

FROM gcr.io/oss-fuzz-base/base-builder

RUN apt-get update && \
apt-get install -y --no-install-recommends \
libssl-dev libdb-dev libpcre2-dev libsqlite3-dev && \
rm -rf /var/lib/apt/lists/*

RUN git clone --depth 1 https://github.com/Exim/exim.git

COPY build.sh fuzz_smtp_input.c $SRC/
39 changes: 39 additions & 0 deletions projects/exim/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash -eu
# Copyright 2025 Google LLC
#
# Licensed 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.


cd "$SRC/exim/src"

# Build Exim as a library for fuzzing
cp src/EDITME Local/Makefile 2>/dev/null || cp EDITME Local/Makefile 2>/dev/null || true

# Compile Exim core parsing functions as a shared object
$CC $CFLAGS -I src -DCOMPILE_UTILITY \
-c src/parse.c -o parse.o 2>/dev/null || \
$CC $CFLAGS -c src/parse.c -o parse.o

$CC $CFLAGS \
-c "$SRC/fuzz_smtp_input.c" -o fuzz_smtp_input.o

$CC $CFLAGS $LIB_FUZZING_ENGINE \
fuzz_smtp_input.o parse.o \
-o "$OUT/fuzz_smtp_input"

# Simple seed corpus
mkdir -p seed_corpus
echo "user@example.com" > seed_corpus/simple.txt
echo '"quoted local"@example.com' > seed_corpus/quoted.txt
echo "user+tag@sub.domain.org" > seed_corpus/tag.txt
zip -j "$OUT/fuzz_smtp_input_seed_corpus.zip" seed_corpus/*
42 changes: 42 additions & 0 deletions projects/exim/fuzz_smtp_input.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2025 Google LLC.
//
// Licensed 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.

/* Fuzz harness for Exim SMTP input parsing and header processing */
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>

/* Forward declarations for Exim internal functions */
extern void mime_decode_header(unsigned char *string, size_t len);
extern int parse_extract_address(unsigned char *input, unsigned char **error,
int *start, int *end, int *domain,
int allow_brackets);

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size < 1 || size > 65536) return 0;

unsigned char *input = (unsigned char *)malloc(size + 1);
if (!input) return 0;
memcpy(input, data, size);
input[size] = '\0';

/* Try to parse as an RFC 5321 address */
unsigned char *error_msg = NULL;
int start = 0, end = 0, domain = 0;
parse_extract_address(input, &error_msg, &start, &end, &domain, 0);

free(input);
return 0;
}
13 changes: 13 additions & 0 deletions projects/exim/project.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
homepage: "https://www.exim.org/"
main_repo: "https://github.com/Exim/exim"
language: c
primary_contact: "exim-dev@exim.org"
auto_ccs:
- "exim-dev@exim.org"
fuzzing_engines:
- libfuzzer
- afl
- honggfuzz
sanitizers:
- address
- undefined
25 changes: 25 additions & 0 deletions projects/redis/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright 2025 Google LLC
#
# Licensed 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.
#
################################################################################

FROM gcr.io/oss-fuzz-base/base-builder

RUN apt-get update && apt-get install -y --no-install-recommends \
pkg-config libssl-dev libhiredis-dev

RUN git clone --depth=1 https://github.com/redis/redis

WORKDIR redis
COPY build.sh fuzz_resp_parser.c fuzz_rdb_load.c $SRC/
75 changes: 75 additions & 0 deletions projects/redis/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/bin/bash -eu
# Copyright 2025 Google LLC
#
# Licensed 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.

cd $SRC/redis

# Build Redis with fuzzing flags
# Use MALLOC=libc to avoid jemalloc issues in the fuzzing environment
# Disable TLS, Lua, and modules to reduce build complexity
make CC="$CC" CFLAGS="$CFLAGS -DFUZZ_BUILD" MALLOC=libc BUILD_TLS=no \
DISABLE_DEBUG=yes -j$(nproc) 2>&1 | tail -5

# Extract object files needed for fuzz_resp_parser
RESP_OBJS="src/resp_parser.o src/sds.o src/zmalloc.o"

# Build fuzz_resp_parser: only needs resp_parser + sds + zmalloc
$CC $CFLAGS -I src -I deps/hiredis -I deps/linenoise \
$SRC/fuzz_resp_parser.c \
$RESP_OBJS \
$LIB_FUZZING_ENGINE \
-lpthread -lm \
-o $OUT/fuzz_resp_parser

# Seed corpus: valid RESP3 messages
mkdir -p $OUT/fuzz_resp_parser_seed_corpus
echo -n "+OK\r\n" > $OUT/fuzz_resp_parser_seed_corpus/simple_ok
echo -n "-ERR bad cmd\r\n" > $OUT/fuzz_resp_parser_seed_corpus/error
echo -n ":42\r\n" > $OUT/fuzz_resp_parser_seed_corpus/integer
echo -n "\$6\r\nfoobar\r\n" > $OUT/fuzz_resp_parser_seed_corpus/bulk
echo -n "*2\r\n\$3\r\nfoo\r\n\$3\r\nbar\r\n" > $OUT/fuzz_resp_parser_seed_corpus/array
echo -n "_\r\n" > $OUT/fuzz_resp_parser_seed_corpus/null
echo -n "#t\r\n" > $OUT/fuzz_resp_parser_seed_corpus/bool_true
echo -n "#f\r\n" > $OUT/fuzz_resp_parser_seed_corpus/bool_false
echo -n ",3.14\r\n" > $OUT/fuzz_resp_parser_seed_corpus/double
echo -n "(12345678901234567890\r\n" > $OUT/fuzz_resp_parser_seed_corpus/big_num
echo -n "=15\r\ntxt:hello world\r\n" > $OUT/fuzz_resp_parser_seed_corpus/verbatim
echo -n "~3\r\n:1\r\n:2\r\n:3\r\n" > $OUT/fuzz_resp_parser_seed_corpus/set
echo -n "%2\r\n+key1\r\n:1\r\n+key2\r\n:2\r\n" > $OUT/fuzz_resp_parser_seed_corpus/map
zip -j $OUT/fuzz_resp_parser_seed_corpus.zip $OUT/fuzz_resp_parser_seed_corpus/*

# Dictionary for RESP3 tokens
cat > $OUT/fuzz_resp_parser.dict << 'DICT'
# RESP3 type prefixes
"+"
"-"
":"
"$"
"*"
"_"
","
"#t"
"#f"
"("
"="
"~"
"%"
"|"
">"
"\r\n"
"*-1"
"$-1"
DICT

echo "Build complete."
49 changes: 49 additions & 0 deletions projects/redis/fuzz_rdb_load.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2025 Google LLC
*
* Licensed 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.
*/

/*
* OSS-Fuzz harness for Redis RDB file parser.
* Writes arbitrary input to a temp file and calls rdbLoad().
*/
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/* Forward declaration to avoid pulling in all of server.h */
int rdbLoad(char *filename, void *rsi, int rdbflags);

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size < 9) return 0; /* Need at least "REDIS0011" header */

char tmpfile[] = "/tmp/fuzz_rdb_XXXXXX";
int fd = mkstemp(tmpfile);
if (fd < 0) return 0;

if (write(fd, data, size) != (ssize_t)size) {
close(fd);
unlink(tmpfile);
return 0;
}
close(fd);

rdbLoad(tmpfile, NULL, 0);

unlink(tmpfile);
return 0;
}
75 changes: 75 additions & 0 deletions projects/redis/fuzz_resp_parser.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright 2025 Google LLC
*
* Licensed 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.
*/

/*
* OSS-Fuzz harness for Redis RESP3 protocol parser (resp_parser.c).
* Feeds arbitrary bytes as a RESP3 reply stream.
*/
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>

#include "resp_parser.h"

static void null_cb(void *ctx, const char *proto, size_t proto_len) { (void)ctx; (void)proto; (void)proto_len; }
static void bulk_cb(void *ctx, const char *str, size_t len, const char *proto, size_t proto_len) { (void)ctx; (void)str; (void)len; (void)proto; (void)proto_len; }
static void simple_cb(void *ctx, const char *str, size_t len, const char *proto, size_t proto_len) { (void)ctx; (void)str; (void)len; (void)proto; (void)proto_len; }
static void long_cb(void *ctx, long long val, const char *proto, size_t proto_len) { (void)ctx; (void)val; (void)proto; (void)proto_len; }
static void bool_cb(void *ctx, int val, const char *proto, size_t proto_len) { (void)ctx; (void)val; (void)proto; (void)proto_len; }
static void double_cb(void *ctx, double val, const char *proto, size_t proto_len) { (void)ctx; (void)val; (void)proto; (void)proto_len; }
static void big_num_cb(void *ctx, const char *str, size_t len, const char *proto, size_t proto_len) { (void)ctx; (void)str; (void)len; (void)proto; (void)proto_len; }
static void verbatim_cb(void *ctx, const char *fmt, const char *str, size_t len, const char *proto, size_t proto_len) { (void)ctx; (void)fmt; (void)str; (void)len; (void)proto; (void)proto_len; }
static void array_cb(ReplyParser *parser, void *ctx, size_t len, const char *proto) { (void)parser; (void)ctx; (void)len; (void)proto; }
static void set_cb(ReplyParser *parser, void *ctx, size_t len, const char *proto) { (void)parser; (void)ctx; (void)len; (void)proto; }
static void map_cb(ReplyParser *parser, void *ctx, size_t len, const char *proto) { (void)parser; (void)ctx; (void)len; (void)proto; }
static void attr_cb(ReplyParser *parser, void *ctx, size_t len, const char *proto) { (void)parser; (void)ctx; (void)len; (void)proto; }
static void error_handler(void *ctx) { (void)ctx; }

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size == 0) return 0;

char *buf = (char *)malloc(size + 2);
if (!buf) return 0;
memcpy(buf, data, size);
buf[size] = '\r';
buf[size + 1] = '\0';

ReplyParser parser;
memset(&parser, 0, sizeof(parser));
parser.curr_location = buf;
parser.callbacks.null_array_callback = null_cb;
parser.callbacks.null_bulk_string_callback = null_cb;
parser.callbacks.bulk_string_callback = bulk_cb;
parser.callbacks.error_callback = simple_cb;
parser.callbacks.simple_str_callback = simple_cb;
parser.callbacks.long_callback = long_cb;
parser.callbacks.bool_callback = bool_cb;
parser.callbacks.double_callback = double_cb;
parser.callbacks.big_number_callback = big_num_cb;
parser.callbacks.verbatim_string_callback = verbatim_cb;
parser.callbacks.array_callback = array_cb;
parser.callbacks.set_callback = set_cb;
parser.callbacks.map_callback = map_cb;
parser.callbacks.attribute_callback = attr_cb;
parser.callbacks.null_callback = null_cb;
parser.callbacks.error = error_handler;

parseReply(&parser, NULL);

free(buf);
return 0;
}
14 changes: 14 additions & 0 deletions projects/redis/project.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
homepage: "https://redis.io/"
main_repo: "https://github.com/redis/redis"
language: c
primary_contact: "security@redis.io"
auto_ccs:
- "security@redis.io"
fuzzing_engines:
- libfuzzer
- afl
- honggfuzz
sanitizers:
- address
- undefined
- memory
25 changes: 25 additions & 0 deletions projects/vim/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright 2025 Google LLC
#
# Licensed 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.

FROM gcr.io/oss-fuzz-base/base-builder

RUN apt-get update && apt-get install -y --no-install-recommends \
libncurses5-dev libncursesw5-dev libacl1-dev libgpm-dev \
python3-dev lua5.3 liblua5.3-dev perl libperl-dev \
libxt-dev autoconf

RUN git clone --depth=1 https://github.com/vim/vim

WORKDIR vim
COPY build.sh fuzz_regexp.c fuzz_vimscript.c $SRC/
Loading