[31548] in CVS-changelog-for-Kerberos-V5

home help back first fref pref prev next nref lref last post

krb5 commit: Add OSS-Fuzz target for ccache marshalling

daemon@ATHENA.MIT.EDU (ghudson@mit.edu)
Sat Jun 13 02:55:18 2026

From: ghudson@mit.edu
To: cvs-krb5@mit.edu
Message-Id: <20260613065511.7246B105580@krbdev.mit.edu>
Date: Sat, 13 Jun 2026 02:55:11 -0400 (EDT)
MIME-Version: 1.0
Reply-To: krbdev@mit.edu
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Errors-To: cvs-krb5-bounces@mit.edu

https://github.com/krb5/krb5/commit/63b55949eff0ac47202d3d717d5b68ebad2fc6b1
commit 63b55949eff0ac47202d3d717d5b68ebad2fc6b1
Author: Arthur Chan <arthur.chan@adalogics.com>
Date:   Thu Jun 11 12:49:35 2026 +0100

    Add OSS-Fuzz target for ccache marshalling

 .gitignore                                         |   1 +
 src/tests/fuzzing/Makefile.in                      |   6 +
 src/tests/fuzzing/deps                             |  10 ++
 src/tests/fuzzing/fuzz_ccache.c                    | 133 +++++++++++++++++++++
 .../fuzz_ccache_seed_corpus/v1_principal_only      | Bin 0 -> 27 bytes
 .../fuzz_ccache_seed_corpus/v4_principal_only      | Bin 0 -> 29 bytes
 src/tests/fuzzing/oss-fuzz.sh                      |   9 +-
 7 files changed, 155 insertions(+), 4 deletions(-)

diff --git a/.gitignore b/.gitignore
index d4e978349..c7e18066a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -437,6 +437,7 @@ local.properties
 /src/tests/fuzzing/fuzz_aes
 /src/tests/fuzzing/fuzz_asn
 /src/tests/fuzzing/fuzz_attrset
+/src/tests/fuzzing/fuzz_ccache
 /src/tests/fuzzing/fuzz_chpw
 /src/tests/fuzzing/fuzz_crypto
 /src/tests/fuzzing/fuzz_des
diff --git a/src/tests/fuzzing/Makefile.in b/src/tests/fuzzing/Makefile.in
index 15bbbbf1a..d6aafc17b 100644
--- a/src/tests/fuzzing/Makefile.in
+++ b/src/tests/fuzzing/Makefile.in
@@ -11,6 +11,7 @@ OBJS= \
 	fuzz_aes.o \
 	fuzz_asn.o \
 	fuzz_attrset.o \
+	fuzz_ccache.o \
 	fuzz_chpw.o \
 	fuzz_crypto.o \
 	fuzz_des.o \
@@ -32,6 +33,7 @@ SRCS= \
 	$(srcdir)/fuzz_aes.c \
 	$(srcdir)/fuzz_asn.c \
 	$(srcdir)/fuzz_attrset.c \
+	$(srcdir)/fuzz_ccache.c \
 	$(srcdir)/fuzz_chpw.c \
 	$(srcdir)/fuzz_crypto.c \
 	$(srcdir)/fuzz_des.c \
@@ -53,6 +55,7 @@ FUZZ_TARGETS= \
 	fuzz_aes \
 	fuzz_asn \
 	fuzz_attrset \
+	fuzz_ccache \
 	fuzz_chpw \
 	fuzz_crypto \
 	fuzz_des \
@@ -84,6 +87,9 @@ fuzz_asn: fuzz_asn.o $(KRB5_BASE_DEPLIBS)
 fuzz_attrset: fuzz_attrset.o $(KRB5_BASE_DEPLIBS)
 	$(CXX_LINK) -o $@ fuzz_attrset.o -lkrad $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS)
 
+fuzz_ccache: fuzz_ccache.o $(KRB5_BASE_DEPLIBS)
+	$(CXX_LINK) -o $@ fuzz_ccache.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS)
+
 fuzz_chpw: fuzz_chpw.o $(KRB5_BASE_DEPLIBS)
 	$(CXX_LINK) -o $@ fuzz_chpw.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS)
 
diff --git a/src/tests/fuzzing/deps b/src/tests/fuzzing/deps
index fbd77e8ea..539d4fd2e 100644
--- a/src/tests/fuzzing/deps
+++ b/src/tests/fuzzing/deps
@@ -35,6 +35,16 @@ $(OUTPRE)fuzz_attrset.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
   $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
   $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
   fuzz_attrset.c
+$(OUTPRE)fuzz_ccache.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
+  $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
+  $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
+  $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+  $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
+  $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
+  $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+  $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+  $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+  $(top_srcdir)/include/socket-utils.h fuzz_ccache.c
 $(OUTPRE)fuzz_chpw.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
   $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
   $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
diff --git a/src/tests/fuzzing/fuzz_ccache.c b/src/tests/fuzzing/fuzz_ccache.c
new file mode 100644
index 000000000..ae79d4087
--- /dev/null
+++ b/src/tests/fuzzing/fuzz_ccache.c
@@ -0,0 +1,133 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* tests/fuzzing/fuzz_ccache.c - fuzzing harness for the FILE ccache parser */
+/*
+ * Copyright (C) 2026 by Arthur Chan. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This harness fuzzes the FILE credential cache parser in
+ * lib/krb5/ccache/cc_file.c.  The fuzz input is written verbatim to a
+ * temporary file, which is then resolved as a "FILE:" ccache and read back;
+ * then the cache's default principal is fetched and its credentials are
+ * iterated to drive the parser (version, header, principal and credential
+ * unmarshalling).
+ */
+
+#include <k5-int.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define kMinInputLength 2
+#define kMaxInputLength 4096
+
+extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
+
+/* krb5_init_context is expensive, so create the context once and reuse it. */
+static krb5_context
+get_context(void)
+{
+    static krb5_context context = NULL;
+    static int initialized = 0;
+
+    if (!initialized) {
+        initialized = 1;
+        if (krb5_init_context(&context) != 0)
+            context = NULL;
+    }
+    return context;
+}
+
+/* Iterate over every credential in the cache to exercise the parser. */
+static void
+iterate_creds(krb5_context context, krb5_ccache ccache)
+{
+    krb5_error_code ret;
+    krb5_cc_cursor cursor;
+    krb5_creds cred;
+
+    ret = krb5_cc_start_seq_get(context, ccache, &cursor);
+    if (ret)
+        return;
+
+    while (krb5_cc_next_cred(context, ccache, &cursor, &cred) == 0)
+        krb5_free_cred_contents(context, &cred);
+
+    krb5_cc_end_seq_get(context, ccache, &cursor);
+}
+
+int
+LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+    krb5_error_code ret;
+    krb5_context context;
+    krb5_ccache ccache;
+    krb5_principal princ;
+    char tmpl[] = "/tmp/fuzz_ccache.XXXXXX";
+    char name[64];
+    int fd;
+
+    if (size < kMinInputLength || size > kMaxInputLength)
+        return 0;
+
+    context = get_context();
+    if (context == NULL)
+        return 0;
+
+    /* Write the fuzz input to a temporary file. */
+    fd = mkstemp(tmpl);
+    if (fd < 0)
+        return 0;
+    if (write(fd, data, size) != (ssize_t)size) {
+        close(fd);
+        unlink(tmpl);
+        return 0;
+    }
+    close(fd);
+
+    snprintf(name, sizeof(name), "FILE:%s", tmpl);
+
+    ret = krb5_cc_resolve(context, name, &ccache);
+    if (ret) {
+        unlink(tmpl);
+        return 0;
+    }
+
+    /* Fetch the default principal, then walk the credentials. */
+    ret = krb5_cc_get_principal(context, ccache, &princ);
+    if (!ret)
+        krb5_free_principal(context, princ);
+
+    iterate_creds(context, ccache);
+
+    krb5_cc_close(context, ccache);
+    unlink(tmpl);
+
+    return 0;
+}
diff --git a/src/tests/fuzzing/fuzz_ccache_seed_corpus/v1_principal_only b/src/tests/fuzzing/fuzz_ccache_seed_corpus/v1_principal_only
new file mode 100644
index 000000000..dab7e2fa6
Binary files /dev/null and b/src/tests/fuzzing/fuzz_ccache_seed_corpus/v1_principal_only differ
diff --git a/src/tests/fuzzing/fuzz_ccache_seed_corpus/v4_principal_only b/src/tests/fuzzing/fuzz_ccache_seed_corpus/v4_principal_only
new file mode 100644
index 000000000..6dde9d673
Binary files /dev/null and b/src/tests/fuzzing/fuzz_ccache_seed_corpus/v4_principal_only differ
diff --git a/src/tests/fuzzing/oss-fuzz.sh b/src/tests/fuzzing/oss-fuzz.sh
index b01d4bcbd..313adfc53 100644
--- a/src/tests/fuzzing/oss-fuzz.sh
+++ b/src/tests/fuzzing/oss-fuzz.sh
@@ -15,10 +15,11 @@ popd
 # Copy fuzz targets and seed corpus to $OUT.
 pushd src/tests/fuzzing
 
-fuzzers=("fuzz_aes" "fuzz_asn" "fuzz_attrset" "fuzz_chpw" "fuzz_crypto"
-         "fuzz_des" "fuzz_gss" "fuzz_json" "fuzz_kdc" "fuzz_krad" "fuzz_krb"
-         "fuzz_krb5_ticket" "fuzz_marshal_cred" "fuzz_marshal_princ"
-         "fuzz_ndr" "fuzz_oid" "fuzz_pac" "fuzz_profile" "fuzz_util")
+fuzzers=("fuzz_aes" "fuzz_asn" "fuzz_attrset" "fuzz_ccache" "fuzz_chpw"
+	 "fuzz_crypto" "fuzz_des" "fuzz_gss" "fuzz_json" "fuzz_kdc"
+	 "fuzz_krad" "fuzz_krb" "fuzz_krb5_ticket" "fuzz_marshal_cred"
+	 "fuzz_marshal_princ" "fuzz_ndr" "fuzz_oid" "fuzz_pac" "fuzz_profile"
+	 "fuzz_util")
 
 for fuzzer in "${fuzzers[@]}"; do
     cp "$fuzzer" "$OUT/$fuzzer"
_______________________________________________
cvs-krb5 mailing list
cvs-krb5@mit.edu
https://mailman.mit.edu/mailman/listinfo/cvs-krb5

home help back first fref pref prev next nref lref last post