container-environment-bootstrap.sh 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #!/usr/bin/env bash
  2. set -euo pipefail
  3. #################
  4. # Prerequisites #
  5. #################
  6. for cmd in python3 git wget zip; do
  7. command -v "$cmd" >/dev/null 2>&1 || {
  8. printf '[%s] Required command %s not found, exiting.\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$cmd" >&2
  9. exit 1
  10. }
  11. done
  12. #############
  13. # Functions #
  14. #############
  15. download_and_concatenate_common_dictionaries() {
  16. # Assign the first argument as the target file where all contents will be concatenated
  17. local target_file="$1"
  18. # Shift the arguments so the first argument (target_file path) is removed
  19. # and only URLs are left for the loop below.
  20. shift
  21. for url in "$@"; do
  22. wget -qO- "$url" >>"$target_file"
  23. # Ensure there's a newline between each file's content
  24. echo >>"$target_file"
  25. done
  26. }
  27. prepare_dictionaries_for_fuzz_targets() {
  28. local dictionaries_dir="$1"
  29. local fuzz_targets_dir="$2"
  30. local common_base_dictionary_filename="$WORK/__base.dict"
  31. printf '[%s] Copying .dict files from %s to %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$dictionaries_dir" "$SRC/"
  32. cp -v "$dictionaries_dir"/*.dict "$SRC/"
  33. download_and_concatenate_common_dictionaries "$common_base_dictionary_filename" \
  34. "https://raw.githubusercontent.com/google/fuzzing/master/dictionaries/utf8.dict" \
  35. "https://raw.githubusercontent.com/google/fuzzing/master/dictionaries/pem.dict"
  36. find "$fuzz_targets_dir" -name 'fuzz_*.py' -print0 | while IFS= read -r -d '' fuzz_harness; do
  37. if [[ -r "$common_base_dictionary_filename" ]]; then
  38. # Strip the `.py` extension from the filename and replace it with `.dict`.
  39. fuzz_harness_dictionary_filename="$(basename "$fuzz_harness" .py).dict"
  40. local output_file="$SRC/$fuzz_harness_dictionary_filename"
  41. printf '[%s] Appending %s to %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$common_base_dictionary_filename" "$output_file"
  42. if [[ -s "$output_file" ]]; then
  43. # If a dictionary file for this fuzzer already exists and is not empty,
  44. # we append a new line to the end of it before appending any new entries.
  45. #
  46. # LibFuzzer will happily ignore multiple empty lines in a dictionary but fail with an error
  47. # if any single line has incorrect syntax (e.g., if we accidentally add two entries to the same line.)
  48. # See docs for valid syntax: https://llvm.org/docs/LibFuzzer.html#id32
  49. echo >>"$output_file"
  50. fi
  51. cat "$common_base_dictionary_filename" >>"$output_file"
  52. fi
  53. done
  54. }
  55. ########################
  56. # Main execution logic #
  57. ########################
  58. prepare_dictionaries_for_fuzz_targets "$SRC/dulwich/fuzzing/dictionaries" "$SRC/dulwich/fuzzing/"
  59. apt-get update && apt-get install -y libgpgme-dev libgpg-error-dev
  60. # The OSS-Fuzz base image includes a modified cargo executable for pure rust projects
  61. # but it can cause linking errors with PyO3's extension-module feature so we remove it.
  62. rm -rf /usr/local/bin/cargo
  63. # Install the Rust toolchain so the Rust extensions can be built in build.sh.
  64. curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly --profile minimal -y
  65. # The OSS-Fuzz base image has outdated dependencies by default so we upgrade them below.
  66. python3 -m pip install --upgrade pip
  67. # Upgrade to the latest versions known to work at the time the below changes were introduced:
  68. python3 -m pip install -U 'atheris>=2.3.0' 'setuptools~=73.0' 'pyinstaller>=6.10' setuptools-rust