fuzzing: add fuzz_iakerb harness for IAKERB acceptor path#1
Conversation
|
[CLAUDE CODE REVIEW - claude-opus-4-6] Good. Now I have all the context needed for a thorough review. Let me compile my findings. PR Review:
|
| Item | Status |
|---|---|
| Diff minimality | OK — 5 files, 107 insertions, minimal approach via forward declarations |
| Correct repo (upstream) | OK — krb5 fuzzing moved upstream in google/oss-fuzz#11951 |
| Files in projects/, not oss-fuzz/ | N/A — upstream PR |
| Conventions (naming, style, includes) | OK — matches fuzz_gss.c exactly |
| Copyright notice | OK — same BSD notice as existing harnesses, year 2026 (current year for new file) |
| Makefile.in alphabetical ordering | OK |
| oss-fuzz.sh array ordering | OK |
| Binary seeds justified | OK — ASN.1 DER protocol data, no text representation; IAKERB framing required |
| No unrelated changes | OK |
| One logical change | OK |
| Claims sourced | OK — Fuzz Introspector linked |
| 5-min local coverage report | MISSING — description acknowledges build env limitation |
| Build verification | NOT DONE LOCALLY — CI relied upon |
Flags
-
No local build/coverage verification (checklist items "Report overall fuzzing coverage after 5 minutes" and "Build works without --local_source"). The description is transparent about the Docker volume mount limitation. The static analysis of symbol availability is thorough and convincing, but this is still a gap — CI is the only build validation. If CI fails, the most likely cause would be a missing include or type mismatch not caught by visual inspection.
-
Minor:
#include <krb5.h>omitted.fuzz_gss.cincludes<krb5.h>and<string.h>whilefuzz_iakerb.conly includes<gssapi.h>. This is fine sincefuzz_iakerb.cdoesn't use any krb5 or string functions, but worth noting since it deviates from the pattern.
Related PRs
- [krb5] move fuzzers and build upstream google/oss-fuzz#11951 (2024-05-20): Moved fuzzers and build upstream — confirms this upstream PR is the correct venue.
- krb5: Add gss_accept_sec_context fuzz harness google/oss-fuzz#9800 (2023-02-28): Added the original
fuzz_gssharness. The IAKERB coverage gap described in this PR is a direct consequence of that harness usingGSS_C_NO_CREDENTIALthrough the mechglue.
No conflicting concurrent PRs found.
Verdict
LGTM — the harness is correct, well-motivated, and minimal. The coverage gap is real and verified. Submit, let CI validate the build, and check results with get_pr_ci_logs.
[CLAUDE CODE REVIEW - claude-opus-4-6]
|
CI failure analysis: Fuzzing check (cifuzz) — pre-existing failure in Fuzz Verify / Coverage step — the coverage build fails when linking the gssrpc library ( Neither failure is caused by the changes in this PR. The address-sanitizer build and fuzzer run steps in Fuzz Verify completed successfully. |
IAKERB sets GSS_C_MA_NOT_DFLT_MECH in krb5_gss_inquire_attrs_for_mech(), which causes gss_accept_sec_context() to return GSS_S_NO_CRED without invoking the mechanism when called without explicit acceptor credentials. The existing fuzz_gss harness calls gss_accept_sec_context() with GSS_C_NO_CREDENTIAL, so the IAKERB acceptor code path has 0% fuzzing coverage even though IAKERB seeds are present in fuzz_gss_seed_corpus/. Add fuzz_iakerb, which bypasses the mechglue and calls iakerb_gss_accept_sec_context() directly. This exercises: - iakerb_parse_token() (IAKERB header parsing and validation) - iakerb_acceptor_step() (realm discovery path and KDC-forward path) - iakerb_alloc_context() / iakerb_release_context() - The non-IAKERB fallback to krb5_gss_accept_sec_context_ext() Seed corpus contains two existing seeds from fuzz_gss_seed_corpus/: - realm_query.bin: IAKERB realm-discovery token (empty realm + empty request), exercises the iakerb_acceptor_realm() path without a KDC - start_accept_context.bin: full IAKERB token with realm and AS-REQ, exercises iakerb_parse_token() and the sendto_kdc error path
|
[CLAUDE CODE REVIEW - claude-opus-4-6] LGTM (seeded for batch CI validation of krb5) [CLAUDE CODE REVIEW - claude-opus-4-6] |
Fuzzing Coverage ReportTested: project No coverage data collected. Check the workflow run for build errors. Same harness config applied to both sides (baseline = base source + PR harness). Per-harness data from |
The IAKERB GSS-API mechanism sets
GSS_C_MA_NOT_DFLT_MECHinkrb5_gss_inquire_attrs_for_mech(). Whengss_accept_sec_context()iscalled with
GSS_C_NO_CREDENTIAL, the mechglue callsallow_mech_by_default()which returns false for IAKERB, causing thecall to return
GSS_S_NO_CREDbefore the IAKERB code is reached. Theexisting
fuzz_gssharness passesGSS_C_NO_CREDENTIAL, so everyiakerb_*function has 0% fuzzing coverage onFuzz Introspector
despite IAKERB seeds being present in
fuzz_gss_seed_corpus/.Add
fuzz_iakerb, which bypasses the mechglue and callsiakerb_gss_accept_sec_context()directly via forward declarations,keeping the diff minimal by avoiding changes to
LOCALINCLUDES.This exercises:
iakerb_parse_token()— IAKERB header parsing and validationiakerb_acceptor_step()— realm-discovery path and KDC-forward pathiakerb_alloc_context()/iakerb_release_context()krb5_gss_accept_sec_context_ext()The seed corpus reuses two existing entries from
fuzz_gss_seed_corpus/.IAKERB tokens are binary ASN.1 DER protocol data with no text
representation, so binary seeds are unavoidable. Raw IAKERB structure
bytes (e.g.
encode_krb5_iakerb_header) are not useful seeds herebecause
iakerb_is_iakerb_token()requires the GSSAPI wrapper(
g_verify_token_headercheck +IAKERB_TOK_PROXYindicator), sounwrapped structures fall to the non-IAKERB path already covered by
fuzz_gss. The two chosen seeds both have the proper GSSAPI framing andtarget distinct IAKERB-specific code paths:
realm_query.bin(18 bytes, empty realm — exercisesiakerb_acceptor_realm()without a KDC) and
start_accept_context.bin(212 bytes, full token withrealm and AS-REQ — exercises
iakerb_parse_token()andsendto_kdcerrorhandling).
Coverage baseline (Fuzz Introspector, production OSS-Fuzz run):
Overall krb5 line coverage: 22.32%. All
iakerb_*functions are at 0%coverage before this change.
Build note: Local compilation is not possible in this build
environment (Docker volume mounts resolve against the VM host filesystem,
not the agent container, so source files are inaccessible to the Docker
daemon). Static evidence for compilation correctness:
iakerb.c:808-815andiakerb.c:847-858exactly (
KRB5_CALLCONVis empty on Linux pergssapi.hin:50; neitherfunction is
static)--enable-static, so all symbols in the.aarchive are available at link time — no
.exportsrestriction appliesfuzz_gss(same$(GSS_LIBS)flags), whichis known to link successfully
CI will validate the actual build.