diff --git a/projects/lua/Dockerfile b/projects/lua/Dockerfile index 75b0611076ab..60eed07dc94b 100644 --- a/projects/lua/Dockerfile +++ b/projects/lua/Dockerfile @@ -14,11 +14,14 @@ # ################################################################################ -FROM gcr.io/oss-fuzz-base/base-builder +FROM gcr.io/oss-fuzz-base/base-builder:ubuntu-24-04 RUN git clone https://github.com/ligurio/lunapark testdir -WORKDIR testdir +WORKDIR $SRC/testdir + RUN git clone --depth 1 --jobs $(nproc) https://github.com/ligurio/lunapark-corpus corpus_dir COPY build.sh $SRC/testdir/ + WORKDIR $SRC COPY build.sh $SRC/ COPY fuzz_lua.c $SRC/ +COPY compile_lua_fuzzer $SRC/ diff --git a/projects/lua/build.sh b/projects/lua/build.sh index da7328d1c919..a362e5f53912 100755 --- a/projects/lua/build.sh +++ b/projects/lua/build.sh @@ -22,7 +22,7 @@ if [ "$SANITIZER" == "introspector" ]; then export CXXFLAGS="${CXXFLAGS} -fsanitize=address" fi -PACKAGES="build-essential ninja-build cmake make" +PACKAGES="build-essential ninja-build cmake make luarocks" if [ "$ARCHITECTURE" = "i386" ]; then PACKAGES="$PACKAGES zlib1g-dev:i386 libreadline-dev:i386 libunwind-dev:i386" elif [ "$ARCHITECTURE" = "aarch64" ]; then @@ -74,10 +74,29 @@ fi : ${LD:="${CXX}"} : ${LDFLAGS:="${CXXFLAGS}"} # to make sure we link with sanitizer runtime +FUZZER_ARGS="" +# The static linkage with libFuzzer is unsupported on i386 [1] and +# the source code coverage tools can conflict with LibFuzzer, +# typically resulting in drastically slower execution speeds, +# crash reproduction failures, or inaccurate coverage reports, so +# libFuzzer static linkage is disabled when code coverage is +# enabled. +# +# 1. https://github.com/ligurio/lunapark/issues/180. +LAPI_TESTING="ON" +if [[ "$FUZZING_ENGINE" != "libfuzzer" ]] || + [[ "$ARCHITECTURE" == "i386" ]] || + [[ "$SANITIZER" == "coverage" ]]; then + FUZZER_ARGS="-DDISABLE_LIBFUZZER_STATIC_LINKAGE=ON" + LAPI_TESTING="OFF" +fi + cmake_args=( -DUSE_LUA=ON -DOSS_FUZZ=ON + -DENABLE_LAPI_TESTS=${LAPI_TESTING} $SANITIZERS_ARGS + $FUZZER_ARGS # C compiler -DCMAKE_C_COMPILER="${CC}" @@ -122,3 +141,58 @@ do cp $f $OUT/ [[ -e $corpus_dir ]] && find "$corpus_dir" -mindepth 1 -maxdepth 1 | zip -@ -j $OUT/"$name"_seed_corpus.zip done + +# Finish execution if libFuzzer is not used, because luzer +# is libFuzzer-based. +# Code coverage is not supported, +# see https://github.com/google/oss-fuzz/issues/14859. +# Building luzer on i386 is unsupported, +# https://github.com/ligurio/luzer/issues/83. +if [[ "$FUZZING_ENGINE" != libfuzzer ]] || + [[ "$SANITIZER" == "coverage" ]] || + [[ "$ARCHITECTURE" == "i386" ]]; then + echo "Lua API testing is not supported." + exit +fi + +luarocks --local install luarocks +eval $(luarocks path) + +# Build luarocks config for PUC Rio Lua 5.5, see [1] and [2]. +# 1. http://lua-users.org/wiki/LuaRocksConfig +# 2. https://github.com/luarocks/luarocks/blob/main/docs/config_file_format.md +luarocks config lua_version 5.5 +luarocks config variables.LUA_INCDIR $LUALIB_PATH +luarocks config variables.LUA_LIBDIR $LUALIB_PATH +luarocks config variables.LUA $LUALIB_PATH/lua + +VERBOSE=1 luarocks install --tree=lua_modules --server=https://luarocks.org/dev luzer LUA_LIBRARIES=$LUALIB_PATH/liblua.a LUA_INCLUDE_DIR=$LUALIB_PATH OSS_FUZZ=ON + +LUA_RUNTIME_NAME=lua + +for fuzzer in $(find $SRC -name '*_test.lua'); do + $SRC/compile_lua_fuzzer $LUA_RUNTIME_NAME $(basename $fuzzer) + cp $fuzzer "$OUT/" +done +cp $SRC/testdir/tests/lapi/lib.lua "$OUT/" + +# BAD BUILD: /tmp/not-out/tmpse6jp7h6/string_buffer_encode_test \ +# seems to have either startup crash or exit: +rm -f $OUT/table_foreachi_test* \ + $OUT/table_foreachi_test* \ + $OUT/table_clear_test* \ + $OUT/table_maxn_test* \ + $OUT/table_foreach_test* \ + $OUT/string_buffer_torture_test* \ + $OUT/bitop_tohex_test* \ + $OUT/jit_p_test* \ + $OUT/bitop_arshift_test* \ + $OUT/bitop_rol_test* \ + $OUT/bitop_tobit_test* \ + $OUT/bitop_ror_test* \ + $OUT/bitop_bswap_test* \ + $OUT/builtin_getfenv_test* \ + $OUT/string_buffer_encode_test* + +cp $LUALIB_PATH/$LUA_RUNTIME_NAME "$OUT/$LUA_RUNTIME_NAME" +cp -R lua_modules "$OUT/" diff --git a/projects/lua/compile_lua_fuzzer b/projects/lua/compile_lua_fuzzer new file mode 100755 index 000000000000..a5aa992e3223 --- /dev/null +++ b/projects/lua/compile_lua_fuzzer @@ -0,0 +1,36 @@ +#!/bin/bash -eu +# Copyright 2026 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. +# +################################################################################ + +# The Lua runtime name. +lua_runtime=$1 +# Path to the fuzz target source file relative to the project's root. +fuzz_target=$2 + +fuzzer_basename=$(basename -s .lua "$fuzz_target") + +# Create an execution wrapper that executes luzer with the correct +# arguments. +echo "#!/bin/bash + +# LLVMFuzzerTestOneInput so that the wrapper script is recognized +# as a fuzz target for 'check_build'. +project_dir=\$(dirname \"\$0\") +eval \$(luarocks --lua-version 5.5 --tree lua_modules path) +ASAN_OPTIONS=\$ASAN_OPTIONS:symbolize=1:external_symbolizer_path=\$project_dir/llvm-symbolizer:detect_leaks=0 \ +\$project_dir/$lua_runtime \$project_dir/$fuzz_target \$@" > "$OUT/$fuzzer_basename" + +chmod +x "$OUT/$fuzzer_basename" diff --git a/projects/lua/project.yaml b/projects/lua/project.yaml index f004feb3d07c..aeba15300e78 100644 --- a/projects/lua/project.yaml +++ b/projects/lua/project.yaml @@ -1,3 +1,4 @@ +base_os_version: ubuntu-24-04 homepage: "https://www.lua.org/" language: c primary_contact: "roberto@inf.puc-rio.br"