krb5 commit: Add coverage to existing OSS-Fuzz targets
ghudson at mit.edu
ghudson at mit.edu
Tue Nov 5 10:50:14 EST 2024
https://github.com/krb5/krb5/commit/7cc16a52b4ea68939da6407ed66914a792441463
commit 7cc16a52b4ea68939da6407ed66914a792441463
Author: Arjun <pkillarjun at protonmail.com>
Date: Mon Sep 30 17:14:10 2024 +0530
Add coverage to existing OSS-Fuzz targets
Also fix the dependencies of fuzz_chpw, remove NDROBJ from Makefile in
favor of including ndr.c from fuzz_ndr.c, and add one new corpus for
fuzz_gss.
[ghudson at mit.edu: added initializers to variables used in cleanup
handlers; edited commit message]
src/tests/fuzzing/Makefile.in | 7 ++--
src/tests/fuzzing/deps | 37 ++++++++++---------
.../fuzzing/fuzz_gss_seed_corpus/realm_query.bin | Bin 0 -> 18 bytes
src/tests/fuzzing/fuzz_json.c | 13 +++++--
src/tests/fuzzing/fuzz_krb5_ticket.c | 28 ++++++++++++---
src/tests/fuzzing/fuzz_marshal_cred.c | 19 +++++-----
src/tests/fuzzing/fuzz_marshal_princ.c | 19 +++++-----
src/tests/fuzzing/fuzz_ndr.c | 14 ++++++--
src/tests/fuzzing/fuzz_pac.c | 37 +++++++++++++++++--
src/tests/fuzzing/fuzz_profile.c | 12 +++++--
src/tests/fuzzing/fuzz_util.c | 39 +++++++++++++++++++++
11 files changed, 171 insertions(+), 54 deletions(-)
diff --git a/src/tests/fuzzing/Makefile.in b/src/tests/fuzzing/Makefile.in
index 05dea371e..2ab3108b1 100644
--- a/src/tests/fuzzing/Makefile.in
+++ b/src/tests/fuzzing/Makefile.in
@@ -2,8 +2,7 @@ mydir=tests$(S)fuzzing
BUILDTOP=$(REL)..$(S)..
LOCALINCLUDES = -I$(srcdir)/../../lib/krb5/ccache -I$(srcdir)/../../kdc \
- -I$(srcdir)/../../util/profile
-NDROBJ = $(BUILDTOP)/kdc/ndr.o
+ -I$(srcdir)/../../util/profile -I$(srcdir)/../../util/support
OBJS = \
fuzz_chpw.o \
@@ -49,7 +48,7 @@ all: $(FUZZ_TARGETS)
# OSS-Fuzz requires fuzz targets to be linked with the C++ linker,
# even if they are written in C.
-fuzz_chpw: fuzz_chpw.o $(SUPPORT_DEPLIB)
+fuzz_chpw: fuzz_chpw.o $(KRB5_BASE_DEPLIBS)
$(CXX_LINK) -o $@ fuzz_chpw.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS)
fuzz_gss: fuzz_gss.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS)
@@ -71,7 +70,7 @@ fuzz_marshal_princ: fuzz_marshal_princ.o $(KRB5_BASE_DEPLIBS)
$(CXX_LINK) -o $@ fuzz_marshal_princ.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS)
fuzz_ndr: fuzz_ndr.o $(KRB5_BASE_DEPLIBS)
- $(CXX_LINK) -o $@ fuzz_ndr.o $(NDROBJ) $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS)
+ $(CXX_LINK) -o $@ fuzz_ndr.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS)
fuzz_pac: fuzz_pac.o $(KRB5_BASE_DEPLIBS)
$(CXX_LINK) -o $@ fuzz_pac.o $(KRB5_BASE_LIBS) $(FUZZ_LDFLAGS)
diff --git a/src/tests/fuzzing/deps b/src/tests/fuzzing/deps
index 018fb4ed0..507645a48 100644
--- a/src/tests/fuzzing/deps
+++ b/src/tests/fuzzing/deps
@@ -73,22 +73,23 @@ $(OUTPRE)fuzz_ndr.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
$(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \
$(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
$(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(VERTO_DEPS) \
- $(srcdir)/../../kdc/kdc_util.h $(srcdir)/../../kdc/realm_data.h \
- $(srcdir)/../../kdc/reqstate.h $(top_srcdir)/include/gssrpc/auth.h \
- $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \
- $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \
- $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \
- $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \
- $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/k5-buf.h \
- $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(srcdir)/../../kdc/kdc_util.h $(srcdir)/../../kdc/ndr.c \
+ $(srcdir)/../../kdc/realm_data.h $(srcdir)/../../kdc/reqstate.h \
+ $(top_srcdir)/include/gssrpc/auth.h $(top_srcdir)/include/gssrpc/auth_gss.h \
+ $(top_srcdir)/include/gssrpc/auth_unix.h $(top_srcdir)/include/gssrpc/clnt.h \
+ $(top_srcdir)/include/gssrpc/rename.h $(top_srcdir)/include/gssrpc/rpc.h \
+ $(top_srcdir)/include/gssrpc/rpc_msg.h $(top_srcdir)/include/gssrpc/svc.h \
+ $(top_srcdir)/include/gssrpc/svc_auth.h $(top_srcdir)/include/gssrpc/xdr.h \
+ $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-input.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/kdb.h $(top_srcdir)/include/krb5.h \
- $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/kdcpreauth_plugin.h \
- $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/net-server.h \
- $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
- fuzz_ndr.c
+ $(top_srcdir)/include/k5-utf8.h $(top_srcdir)/include/kdb.h \
+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+ $(top_srcdir)/include/krb5/kdcpreauth_plugin.h $(top_srcdir)/include/krb5/plugin.h \
+ $(top_srcdir)/include/net-server.h $(top_srcdir)/include/port-sockets.h \
+ $(top_srcdir)/include/socket-utils.h fuzz_ndr.c
$(OUTPRE)fuzz_pac.$(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 \
@@ -106,12 +107,14 @@ $(OUTPRE)fuzz_profile.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
fuzz_profile.c
$(OUTPRE)fuzz_util.$(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-base64.h \
- $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
- $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-hex.h \
+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../util/support/hashtab.c \
+ $(top_srcdir)/include/k5-base64.h $(top_srcdir)/include/k5-buf.h \
+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
+ $(top_srcdir)/include/k5-hashtab.h $(top_srcdir)/include/k5-hex.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/k5-queue.h $(top_srcdir)/include/k5-thread.h \
+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/k5-utf8.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_util.c
diff --git a/src/tests/fuzzing/fuzz_gss_seed_corpus/realm_query.bin b/src/tests/fuzzing/fuzz_gss_seed_corpus/realm_query.bin
new file mode 100644
index 000000000..2178d65a0
Binary files /dev/null and b/src/tests/fuzzing/fuzz_gss_seed_corpus/realm_query.bin differ
diff --git a/src/tests/fuzzing/fuzz_json.c b/src/tests/fuzzing/fuzz_json.c
index 0d970125e..a3440eaef 100644
--- a/src/tests/fuzzing/fuzz_json.c
+++ b/src/tests/fuzzing/fuzz_json.c
@@ -48,8 +48,8 @@ int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
krb5_error_code ret;
- char *data_in;
- k5_json_value decoded;
+ k5_json_value decoded = NULL;
+ char *data_in = NULL, *data_out;
if (size < kMinInputLength || size > kMaxInputLength)
return 0;
@@ -58,8 +58,15 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
if (data_in == NULL)
return 0;
- k5_json_decode(data_in, &decoded);
+ ret = k5_json_decode(data_in, &decoded);
+ if (ret)
+ goto cleanup;
+ ret = k5_json_encode(decoded, &data_out);
+ if (!ret)
+ free(data_out);
+
+cleanup:
free(data_in);
k5_json_release(decoded);
diff --git a/src/tests/fuzzing/fuzz_krb5_ticket.c b/src/tests/fuzzing/fuzz_krb5_ticket.c
index a88f75314..0b541f444 100644
--- a/src/tests/fuzzing/fuzz_krb5_ticket.c
+++ b/src/tests/fuzzing/fuzz_krb5_ticket.c
@@ -46,21 +46,39 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
- krb5_data data_in;
- krb5_ticket *ticket;
- krb5_context context;
+ krb5_error_code ret;
+ krb5_context context = NULL;
+ krb5_keytab defkt = NULL;
+ krb5_data data_in, *data_out;
+ krb5_ticket *ticket = NULL;
if (size < kMinInputLength || size > kMaxInputLength)
return 0;
data_in = make_data((void *)data, size);
- if (krb5_init_context(&context) != 0)
+ ret = krb5_init_context(&context);
+ if (ret)
return 0;
- krb5_decode_ticket(&data_in, &ticket);
+ ret = krb5_kt_default(context, &defkt);
+ if (ret)
+ goto cleanup;
+ ret = krb5_decode_ticket(&data_in, &ticket);
+ if (ret)
+ goto cleanup;
+
+ ret = encode_krb5_ticket(ticket, &data_out);
+ if (!ret)
+ krb5_free_data(context, data_out);
+
+ krb5_server_decrypt_ticket_keytab(context, defkt, ticket);
+
+cleanup:
krb5_free_ticket(context, ticket);
+ if (defkt != NULL)
+ krb5_kt_close(context, defkt);
krb5_free_context(context);
return 0;
diff --git a/src/tests/fuzzing/fuzz_marshal_cred.c b/src/tests/fuzzing/fuzz_marshal_cred.c
index 7181ab9a7..07b130a83 100644
--- a/src/tests/fuzzing/fuzz_marshal_cred.c
+++ b/src/tests/fuzzing/fuzz_marshal_cred.c
@@ -46,21 +46,24 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
+ krb5_error_code ret;
+ krb5_creds cred;
int version;
- krb5_creds cred = { 0 };
- krb5_context context;
+ struct k5buf buf;
if (size < kMinInputLength || size > kMaxInputLength)
return 0;
- if (krb5_init_context(&context) != 0)
- return 0;
-
for (version = FIRST_VERSION; version <= 4; version++) {
- k5_unmarshal_cred(data, size, version, &cred);
- krb5_free_cred_contents(context, &cred);
+ ret = k5_unmarshal_cred(data, size, version, &cred);
+ if (!ret) {
+ k5_buf_init_dynamic(&buf);
+ k5_marshal_cred(&buf, version, &cred);
+ k5_buf_free(&buf);
+ }
+
+ krb5_free_cred_contents(NULL, &cred);
}
- krb5_free_context(context);
return 0;
}
diff --git a/src/tests/fuzzing/fuzz_marshal_princ.c b/src/tests/fuzzing/fuzz_marshal_princ.c
index e421ff305..b41fd6269 100644
--- a/src/tests/fuzzing/fuzz_marshal_princ.c
+++ b/src/tests/fuzzing/fuzz_marshal_princ.c
@@ -46,21 +46,24 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
- int version;
+ krb5_error_code ret;
krb5_principal princ;
- krb5_context context;
+ int version;
+ struct k5buf buf;
if (size < kMinInputLength || size > kMaxInputLength)
return 0;
- if (krb5_init_context(&context) != 0)
- return 0;
-
for (version = FIRST_VERSION; version <= 4; version++) {
- k5_unmarshal_princ(data, size, version, &princ);
- krb5_free_principal(context, princ);
+ ret = k5_unmarshal_princ(data, size, version, &princ);
+ if (!ret) {
+ k5_buf_init_dynamic(&buf);
+ k5_marshal_princ(&buf, version, princ);
+ k5_buf_free(&buf);
+ }
+
+ krb5_free_principal(NULL, princ);
}
- krb5_free_context(context);
return 0;
}
diff --git a/src/tests/fuzzing/fuzz_ndr.c b/src/tests/fuzzing/fuzz_ndr.c
index 4cc6daa1c..7692bace7 100644
--- a/src/tests/fuzzing/fuzz_ndr.c
+++ b/src/tests/fuzzing/fuzz_ndr.c
@@ -37,6 +37,8 @@
#include <k5-int.h>
#include <kdc_util.h>
+#include <ndr.c>
+
#define kMinInputLength 2
#define kMaxInputLength 1024
@@ -45,15 +47,21 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
- krb5_data data_in;
- struct pac_s4u_delegation_info *di = NULL;
+ krb5_error_code ret;
+ krb5_data data_in, data_out = empty_data();
+ struct pac_s4u_delegation_info *di;
if (size < kMinInputLength || size > kMaxInputLength)
return 0;
data_in = make_data((void *)data, size);
- ndr_dec_delegation_info(&data_in, &di);
+
+ ret = ndr_dec_delegation_info(&data_in, &di);
+ if (!ret)
+ (void)ndr_enc_delegation_info(di, &data_out);
+
ndr_free_delegation_info(di);
+ krb5_free_data_contents(NULL, &data_out);
return 0;
}
diff --git a/src/tests/fuzzing/fuzz_pac.c b/src/tests/fuzzing/fuzz_pac.c
index f9f5635f4..38488420e 100644
--- a/src/tests/fuzzing/fuzz_pac.c
+++ b/src/tests/fuzzing/fuzz_pac.c
@@ -36,26 +36,57 @@
#include "autoconf.h"
#include <k5-int.h>
+#define U(x) (uint8_t *)x
#define kMinInputLength 2
#define kMaxInputLength 1024
+static const krb5_keyblock kdc_keyblock = {
+ 0, ENCTYPE_ARCFOUR_HMAC,
+ 16, U("\xB2\x86\x75\x71\x48\xAF\x7F\xD2\x52\xC5\x36\x03\xA1\x50\xB7\xE7")
+};
+
+static const krb5_keyblock member_keyblock = {
+ 0, ENCTYPE_ARCFOUR_HMAC,
+ 16, U("\xD2\x17\xFA\xEA\xE5\xE6\xB5\xF9\x5C\xCC\x94\x07\x7A\xB8\xA5\xFC")
+};
+
+static time_t authtime = 1120440609;
+static const char *user = "w2003final$@WIN2K3.THINKER.LOCAL";
+
extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
+ krb5_error_code ret;
+ krb5_context context = NULL;
krb5_pac pac;
- krb5_context context;
+ krb5_principal princ = NULL;
if (size < kMinInputLength || size > kMaxInputLength)
return 0;
- if (krb5_init_context(&context) != 0)
+ ret = krb5_init_context(&context);
+ if (ret)
return 0;
- krb5_pac_parse(context, data, size, &pac);
+ ret = krb5_parse_name(context, user, &princ);
+ if (ret)
+ goto cleanup;
+
+ ret = krb5_pac_parse(context, data, size, &pac);
+ if (ret)
+ goto cleanup;
+
+ krb5_pac_verify(context, pac, authtime, princ, NULL, NULL);
+ krb5_pac_verify_ext(context, pac, authtime, princ, NULL, NULL, TRUE);
+ krb5_pac_verify(context, pac, authtime, princ, &member_keyblock,
+ &kdc_keyblock);
krb5_pac_free(context, pac);
+
+cleanup:
+ krb5_free_principal(context, princ);
krb5_free_context(context);
return 0;
diff --git a/src/tests/fuzzing/fuzz_profile.c b/src/tests/fuzzing/fuzz_profile.c
index 95a5b488d..e62decf7b 100644
--- a/src/tests/fuzzing/fuzz_profile.c
+++ b/src/tests/fuzzing/fuzz_profile.c
@@ -46,8 +46,9 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
+ errcode_t ret;
FILE *fp_w, *fp_r;
- char file_name[256];
+ char file_name[256], *output;
struct profile_node *root;
if (size < kMinInputLength || size > kMaxInputLength)
@@ -55,7 +56,7 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
snprintf(file_name, sizeof(file_name), "/tmp/libfuzzer.%d", getpid());
- /* Write data into the file.*/
+ /* Write data into the file. */
fp_w = fopen(file_name, "w");
if (!fp_w)
return 1;
@@ -69,7 +70,12 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
initialize_prof_error_table();
- if (profile_parse_file(fp_r, &root, NULL) == 0) {
+ ret = profile_parse_file(fp_r, &root, NULL);
+ if (!ret) {
+ ret = profile_write_tree_to_buffer(root, &output);
+ if (!ret)
+ free(output);
+
profile_verify_node(root);
profile_free_node(root);
}
diff --git a/src/tests/fuzzing/fuzz_util.c b/src/tests/fuzzing/fuzz_util.c
index 8779b4c61..91641ad1c 100644
--- a/src/tests/fuzzing/fuzz_util.c
+++ b/src/tests/fuzzing/fuzz_util.c
@@ -39,6 +39,9 @@
#include <k5-base64.h>
#include <k5-hex.h>
#include <string.h>
+#include <k5-utf8.h>
+
+#include <hashtab.c>
#define kMinInputLength 2
#define kMaxInputLength 256
@@ -54,6 +57,21 @@ fuzz_base64(const char *data_in, size_t size)
free(k5_base64_decode(data_in, &len));
}
+static void
+fuzz_hashtab(const char *data_in, size_t size)
+{
+ int st;
+ struct k5_hashtab *ht;
+
+ k5_hashtab_create(NULL, 4, &ht);
+ if (ht == NULL)
+ return;
+
+ k5_hashtab_add(ht, data_in, size, &st);
+
+ k5_hashtab_free(ht);
+}
+
static void
fuzz_hex(const char *data_in, size_t size)
{
@@ -96,6 +114,25 @@ fuzz_parse_host(const char *data_in, size_t size)
free(host_out);
}
+static void
+fuzz_utf8(const char *data_in, size_t size)
+{
+ krb5_ucs4 u = 0;
+ char *utf8;
+ uint8_t *utf16;
+ size_t utf16len;
+
+ krb5int_utf8_to_ucs4(data_in, &u);
+
+ k5_utf8_to_utf16le(data_in, &utf16, &utf16len);
+ if (utf16 != NULL)
+ free(utf16);
+
+ k5_utf16le_to_utf8((const uint8_t *)data_in, size, &utf8);
+ if (utf8 != NULL)
+ free(utf8);
+}
+
extern int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
@@ -110,9 +147,11 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
return 0;
fuzz_base64(data_in, size);
+ fuzz_hashtab(data_in, size);
fuzz_hex(data_in, size);
fuzz_name(data_in, size);
fuzz_parse_host(data_in, size);
+ fuzz_utf8(data_in, size);
free(data_in);
More information about the cvs-krb5
mailing list