/src/mod_auth_openidc/test/fuzz/fuzz.h
Line | Count | Source |
1 | | /* |
2 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
3 | | * contributor license agreements. Licensed under the Apache License, |
4 | | * Version 2.0 (the "License"); you may not use this file except in |
5 | | * compliance with the License. You may obtain a copy of the License at |
6 | | * |
7 | | * http://www.apache.org/licenses/LICENSE-2.0 |
8 | | * |
9 | | * Copyright (C) 2017-2026 ZmartZone Holding BV - hans.zandbelt@openidc.com |
10 | | * |
11 | | * fuzz.h -- shared declarations for the fuzz targets under test/fuzz/. |
12 | | * |
13 | | * Each target implements the libFuzzer entry point below. The same object |
14 | | * builds two ways: |
15 | | * - linked with standalone.c + plain cc -> a corpus-replay binary run by |
16 | | * test/fuzz/run-fuzzers.sh as part of `make check` (regression guard); |
17 | | * - compiled with `clang -fsanitize=fuzzer` -> a real libFuzzer binary |
18 | | * (libFuzzer provides main); see test/fuzz/build.sh. |
19 | | */ |
20 | | |
21 | | #ifndef _MOD_AUTH_OPENIDC_TEST_FUZZ_H_ |
22 | | #define _MOD_AUTH_OPENIDC_TEST_FUZZ_H_ |
23 | | |
24 | | #include <apr_pools.h> |
25 | | #include <stddef.h> |
26 | | #include <stdint.h> |
27 | | #include <string.h> |
28 | | |
29 | | /* the one entry point every fuzz target implements */ |
30 | | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); |
31 | | |
32 | | /* |
33 | | * Copy the fuzzer's input bytes into a NUL-terminated string on the given pool. |
34 | | * |
35 | | * Deliberately not apr_pstrmemdup(): APR declares that function with |
36 | | * __attribute__((alloc_size(3))), which tells the compiler the result is n |
37 | | * bytes long although APR allocates n + 1 -- so under gcc's UBSan object-size |
38 | | * check (the CI sanitizers job builds the targets with -fsanitize=undefined |
39 | | * -fno-sanitize-recover) a harness that reads the terminator, or [0] of an |
40 | | * empty input, is reported as an out-of-object load and the replay aborts. |
41 | | * apr_palloc's own size annotation is truthful, so this copy is not. |
42 | | */ |
43 | 29.3k | static inline char *fuzz_strndup(apr_pool_t *pool, const uint8_t *data, size_t size) { |
44 | 29.3k | char *s = apr_palloc(pool, size + 1); |
45 | 29.3k | if (size > 0) |
46 | 29.3k | memcpy(s, data, size); |
47 | 29.3k | s[size] = '\0'; |
48 | 29.3k | return s; |
49 | 29.3k | } Unexecuted instantiation: fuzz_response_header.c:fuzz_strndup Unexecuted instantiation: fuzz_json.c:fuzz_strndup Unexecuted instantiation: fuzz_state_cookie.c:fuzz_strndup fuzz_bearer_token.c:fuzz_strndup Line | Count | Source | 43 | 6.70k | static inline char *fuzz_strndup(apr_pool_t *pool, const uint8_t *data, size_t size) { | 44 | 6.70k | char *s = apr_palloc(pool, size + 1); | 45 | 6.70k | if (size > 0) | 46 | 6.68k | memcpy(s, data, size); | 47 | 6.70k | s[size] = '\0'; | 48 | 6.70k | return s; | 49 | 6.70k | } |
fuzz_redirect_uri.c:fuzz_strndup Line | Count | Source | 43 | 4.30k | static inline char *fuzz_strndup(apr_pool_t *pool, const uint8_t *data, size_t size) { | 44 | 4.30k | char *s = apr_palloc(pool, size + 1); | 45 | 4.30k | if (size > 0) | 46 | 4.28k | memcpy(s, data, size); | 47 | 4.30k | s[size] = '\0'; | 48 | 4.30k | return s; | 49 | 4.30k | } |
fuzz_backchannel_logout.c:fuzz_strndup Line | Count | Source | 43 | 7.08k | static inline char *fuzz_strndup(apr_pool_t *pool, const uint8_t *data, size_t size) { | 44 | 7.08k | char *s = apr_palloc(pool, size + 1); | 45 | 7.08k | if (size > 0) | 46 | 7.08k | memcpy(s, data, size); | 47 | 7.08k | s[size] = '\0'; | 48 | 7.08k | return s; | 49 | 7.08k | } |
Unexecuted instantiation: fuzz_discovery_response.c:fuzz_strndup fuzz_authz_response.c:fuzz_strndup Line | Count | Source | 43 | 6.86k | static inline char *fuzz_strndup(apr_pool_t *pool, const uint8_t *data, size_t size) { | 44 | 6.86k | char *s = apr_palloc(pool, size + 1); | 45 | 6.86k | if (size > 0) | 46 | 6.83k | memcpy(s, data, size); | 47 | 6.86k | s[size] = '\0'; | 48 | 6.86k | return s; | 49 | 6.86k | } |
Unexecuted instantiation: fuzz_jwt.c:fuzz_strndup Unexecuted instantiation: fuzz_cookie.c:fuzz_strndup fuzz_post_preserve.c:fuzz_strndup Line | Count | Source | 43 | 763 | static inline char *fuzz_strndup(apr_pool_t *pool, const uint8_t *data, size_t size) { | 44 | 763 | char *s = apr_palloc(pool, size + 1); | 45 | 763 | if (size > 0) | 46 | 763 | memcpy(s, data, size); | 47 | 763 | s[size] = '\0'; | 48 | 763 | return s; | 49 | 763 | } |
Unexecuted instantiation: fuzz_pem_key.c:fuzz_strndup Unexecuted instantiation: fuzz_metadata.c:fuzz_strndup fuzz_strings.c:fuzz_strndup Line | Count | Source | 43 | 3.26k | static inline char *fuzz_strndup(apr_pool_t *pool, const uint8_t *data, size_t size) { | 44 | 3.26k | char *s = apr_palloc(pool, size + 1); | 45 | 3.26k | if (size > 0) | 46 | 3.26k | memcpy(s, data, size); | 47 | 3.26k | s[size] = '\0'; | 48 | 3.26k | return s; | 49 | 3.26k | } |
Unexecuted instantiation: fuzz_jwks.c:fuzz_strndup fuzz_current_url.c:fuzz_strndup Line | Count | Source | 43 | 377 | static inline char *fuzz_strndup(apr_pool_t *pool, const uint8_t *data, size_t size) { | 44 | 377 | char *s = apr_palloc(pool, size + 1); | 45 | 377 | if (size > 0) | 46 | 377 | memcpy(s, data, size); | 47 | 377 | s[size] = '\0'; | 48 | 377 | return s; | 49 | 377 | } |
Unexecuted instantiation: fuzz_url.c:fuzz_strndup Unexecuted instantiation: fuzz_base64.c:fuzz_strndup Unexecuted instantiation: fuzz_form_params.c:fuzz_strndup |
50 | | |
51 | | /* |
52 | | * One-time fixture setup (oidc_test_setup), implemented by every target. |
53 | | * libFuzzer and honggfuzz call this once at startup; AFL++'s driver calls it |
54 | | * *before* spawning its deferred forkserver, and that ordering is the point: |
55 | | * the full post-config fixture init must run once in the forkserver parent, |
56 | | * not inside every forked child's first LLVMFuzzerTestOneInput call, where |
57 | | * afl-fuzz's per-exec timeout (5s in the OSS-Fuzz build check) counts it. |
58 | | * afl-fuzz also injects LSAN_OPTIONS containing fast_unwind_on_malloc=0 into |
59 | | * the target environment, which makes ASan DWARF-unwind every allocation the |
60 | | * init makes and inflates that first exec from ~0.2s to seconds -- the cause |
61 | | * of the "All test cases time out" OSS-Fuzz build-check failures on the afl |
62 | | * engine. Targets keep a lazy fallback in LLVMFuzzerTestOneInput for runners |
63 | | * that do not call this (the standalone corpus-replay main). |
64 | | */ |
65 | | int LLVMFuzzerInitialize(int *argc, char ***argv); |
66 | | |
67 | | #endif /* _MOD_AUTH_OPENIDC_TEST_FUZZ_H_ */ |