container-environment-bootstrap.sh 3.4 KB

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