Git fork

fuzz: port fuzz-url-decode-mem from OSS-Fuzz

Git's fuzz tests are run continuously as part of OSS-Fuzz [1]. Several
additional fuzz tests have been contributed directly to OSS-Fuzz;
however, these tests are vulnerable to bitrot because they are not built
during Git's CI runs, and thus breaking changes are much less likely to
be noticed by Git contributors.

Port one of these tests back to the Git project:
fuzz-url-decode-mem

This test was originally written by Eric Sesterhenn as part of a
security audit of Git [2]. It was then contributed to the OSS-Fuzz repo
in commit c58ac4492 (Git fuzzing: uncomment the existing and add new
targets. (#11486), 2024-02-21) by Jaroslav Lobačevski. I (Josh Steadmon)
have verified with both Eric and Jaroslav that they're OK with moving
this test to the Git project.

[1] https://github.com/google/oss-fuzz
[2] https://ostif.org/wp-content/uploads/2023/01/X41-OSTIF-Gitlab-Git-Security-Audit-20230117-public.pdf

Co-authored-by: Jaroslav Lobačevski <jarlob@gmail.com>
Co-authored-by: Josh Steadmon <steadmon@google.com>
Signed-off-by: Josh Steadmon <steadmon@google.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>

+46
+1
Makefile
··· 2427 2427 FUZZ_OBJS += oss-fuzz/fuzz-pack-headers.o 2428 2428 FUZZ_OBJS += oss-fuzz/fuzz-pack-idx.o 2429 2429 FUZZ_OBJS += oss-fuzz/fuzz-parse-attr-line.o 2430 + FUZZ_OBJS += oss-fuzz/fuzz-url-decode-mem.o 2430 2431 .PHONY: fuzz-objs 2431 2432 fuzz-objs: $(FUZZ_OBJS) 2432 2433
+1
ci/run-build-and-minimal-fuzzers.sh
··· 21 21 pack-headers 22 22 pack-idx 23 23 parse-attr-line 24 + url-decode-mem 24 25 " 25 26 26 27 for fuzzer in $fuzzers; do
+1
oss-fuzz/.gitignore
··· 5 5 fuzz-pack-headers 6 6 fuzz-pack-idx 7 7 fuzz-parse-attr-line 8 + fuzz-url-decode-mem
+43
oss-fuzz/fuzz-url-decode-mem.c
··· 1 + #include "git-compat-util.h" 2 + #include <stddef.h> 3 + #include <stdlib.h> 4 + #include <stdint.h> 5 + #include <string.h> 6 + #include <stdio.h> 7 + #include "url.h" 8 + 9 + int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); 10 + 11 + int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) 12 + { 13 + char *buf; 14 + char *r; 15 + const char *pbuf; 16 + 17 + buf = malloc(size + 1); 18 + if (!buf) 19 + return 0; 20 + 21 + memcpy(buf, data, size); 22 + buf[size] = 0; 23 + 24 + // start fuzzing 25 + r = url_decode(buf); 26 + free(r); 27 + 28 + r = url_percent_decode(buf); 29 + free(r); 30 + 31 + pbuf = (const char*) buf; 32 + r = url_decode_parameter_name(&pbuf); 33 + free(r); 34 + 35 + pbuf = (const char*) buf; 36 + r = url_decode_parameter_value(&pbuf); 37 + free(r); 38 + 39 + // cleanup 40 + free(buf); 41 + 42 + return 0; 43 + }