From: Arjun Date: Mon, 30 Sep 2024 11:44:10 +0000 (+0530) Subject: Add coverage to existing OSS-Fuzz targets X-Git-Tag: krb5-1.22-beta1~60 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7cc16a52b4ea68939da6407ed66914a792441463;p=thirdparty%2Fkrb5.git 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@mit.edu: added initializers to variables used in cleanup handlers; edited commit message] --- diff --git a/src/tests/fuzzing/Makefile.in b/src/tests/fuzzing/Makefile.in index 05dea371e8..2ab3108b16 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 018fb4ed02..507645a48e 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 0000000000..2178d65a04 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 0d970125e1..a3440eaef1 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 a88f753140..0b541f444c 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 7181ab9a77..07b130a839 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 e421ff3058..b41fd62694 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 4cc6daa1c9..7692bace72 100644 --- a/src/tests/fuzzing/fuzz_ndr.c +++ b/src/tests/fuzzing/fuzz_ndr.c @@ -37,6 +37,8 @@ #include #include +#include + #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 f9f5635f44..38488420eb 100644 --- a/src/tests/fuzzing/fuzz_pac.c +++ b/src/tests/fuzzing/fuzz_pac.c @@ -36,26 +36,57 @@ #include "autoconf.h" #include +#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 95a5b488de..e62decf7b7 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 8779b4c61c..91641ad1cb 100644 --- a/src/tests/fuzzing/fuzz_util.c +++ b/src/tests/fuzzing/fuzz_util.c @@ -39,6 +39,9 @@ #include #include #include +#include + +#include #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);