Skip to content
Draft
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
6 changes: 4 additions & 2 deletions projects/cpython3/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ FROM gcr.io/oss-fuzz-base/base-builder
RUN apt-get update && \
apt-get install -y build-essential libncursesw5-dev \
libreadline-dev libssl-dev libgdbm-dev \
libc6-dev libsqlite3-dev tk-dev libbz2-dev \
zlib1g-dev libffi-dev
libc6-dev libsqlite3-dev libbz2-dev \
zlib1g-dev libffi-dev libmpdec-dev \
liblzma-dev libzstd-dev uuid-dev \
libgdbm-compat-dev

RUN git clone https://github.com/python/cpython.git cpython3
WORKDIR cpython3
Expand Down
33 changes: 30 additions & 3 deletions projects/cpython3/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ CFLAGS="${CFLAGS} -UNDEBUG"
# We use some internal CPython API.
CFLAGS="${CFLAGS} -IInclude/internal/"

# Build all stdlib C extension modules statically into libpython
# rather than as shared .so files, so they are linked into the fuzzers.
export MODULE_BUILDTYPE=static

FLAGS=()
FLAGS+=("--disable-test-modules")
case $SANITIZER in
address)
FLAGS+=("--with-address-sanitizer")
Expand All @@ -49,19 +54,41 @@ case $SANITIZER in
esac
./configure "${FLAGS[@]:-}" --prefix $OUT

# When building modules statically, HACL* crypto object files must be linked
# via static archives (.a) instead of raw .o files to avoid duplicate symbols
# across _blake2, _sha*, _hmac modules that share HACL* objects.
# Only patch the MODULE_ dependency lines, not the LIBHACL variable definitions.
sed -i '/^MODULE__/s/LIB_SHARED/LIB_STATIC/g' Makefile

# We use altinstall to avoid having the Makefile create symlinks
make -j$(nproc) altinstall

# When modules are statically linked into libpython, the fuzzer binaries
# need the system libraries that those modules depend on (e.g. -lsqlite3,
# -lz, -lssl). These are tracked in the Makefile's MODLIBS variable but
# are not included by python-config --ldflags.
PYTHON=$(ls $OUT/bin/python3.* | grep -v config | head -1)
MODLIBS=$($PYTHON -c "import sysconfig; print(sysconfig.get_config_var('MODLIBS'))")

FUZZ_DIR=Modules/_xxtestfuzz
for fuzz_test in $(cat $FUZZ_DIR/fuzz_tests.txt)
do
# Template fuzzers have their own .c file; original targets use fuzzer.c
if [ -f "$FUZZ_DIR/${fuzz_test}.c" ]; then
FUZZ_SOURCE="$FUZZ_DIR/${fuzz_test}.c"
FUZZ_DEFINES=""
else
FUZZ_SOURCE="$FUZZ_DIR/fuzzer.c"
FUZZ_DEFINES="-D _Py_FUZZ_ONE -D _Py_FUZZ_$fuzz_test"
fi

# Build (but don't link) the fuzzing stub with a C compiler
$CC $CFLAGS $($OUT/bin/python*-config --cflags) $FUZZ_DIR/fuzzer.c \
-D _Py_FUZZ_ONE -D _Py_FUZZ_$fuzz_test -c -Wno-unused-function \
$CC $CFLAGS $($OUT/bin/python*-config --cflags) $FUZZ_SOURCE \
$FUZZ_DEFINES -c -Wno-unused-function \
-o $WORK/$fuzz_test.o
# Link with C++ compiler to appease libfuzzer
$CXX $CXXFLAGS -rdynamic $WORK/$fuzz_test.o -o $OUT/$fuzz_test \
$LIB_FUZZING_ENGINE $($OUT/bin/python*-config --ldflags --embed)
$LIB_FUZZING_ENGINE $($OUT/bin/python*-config --ldflags --embed) $MODLIBS

# Zip up and copy any seed corpus
if [ -d "${FUZZ_DIR}/${fuzz_test}_corpus" ]; then
Expand Down
Loading