diff --git a/arch/x86/lib/cmdline.c b/arch/x86/lib/cmdline.c index c65cd55504549a..f4caff8f8890c9 100644 --- a/arch/x86/lib/cmdline.c +++ b/arch/x86/lib/cmdline.c @@ -11,6 +11,8 @@ #include #include +#include + static inline int myisspace(u8 c) { return c <= ' '; /* Close enough approximation */ @@ -233,3 +235,28 @@ int cmdline_find_option(const char *cmdline, const char *option, char *buffer, return ret; } + +struct cmdline_find_option_arg { + const char *cmdline; + const char *option; +}; + +FUZZ_TEST(test_cmdline_find_option, struct cmdline_find_option_arg) +{ + char *buffer; + + KFUZZTEST_EXPECT_NOT_NULL(cmlind_find_option_arg, cmdline); + KFUZZTEST_EXPECT_NOT_NULL(cmlind_find_option_arg, option); + KFUZZTEST_ANNOTATE_STRING(cmdline_find_option_arg, cmdline); + KFUZZTEST_ANNOTATE_STRING(cmdline_find_option_arg, option); + + int bufsize = 1024; + buffer = kmalloc(bufsize, GFP_KERNEL); + if (!buffer || IS_ERR(buffer)) { + pr_warn("failed to allocate a kernel buffer"); + return; + } + + cmdline_find_option(arg->cmdline, arg->option, buffer, bufsize); + kfree(buffer); +} diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c index 423d13c475452c..e8477f8b0eafbf 100644 --- a/crypto/asymmetric_keys/pkcs7_parser.c +++ b/crypto/asymmetric_keys/pkcs7_parser.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "pkcs7_parser.h" #include "pkcs7.asn1.h" @@ -169,6 +170,20 @@ struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen) } EXPORT_SYMBOL_GPL(pkcs7_parse_message); +struct pkcs7_parse_message_arg { + const void *data; + size_t datalen; +}; + +FUZZ_TEST(test_pkcs7_parse_message, struct pkcs7_parse_message_arg) +{ + KFUZZTEST_EXPECT_NOT_NULL(pkcs7_parse_message_arg, data); + KFUZZTEST_ANNOTATE_LEN(pkcs7_parse_message_arg, datalen, data); + KFUZZTEST_EXPECT_LE(pkcs7_parse_message_arg, datalen, 16 * PAGE_SIZE); + + pkcs7_parse_message(arg->data, arg->datalen); +} + /** * pkcs7_get_content_data - Get access to the PKCS#7 content * @pkcs7: The preparsed PKCS#7 message to access diff --git a/crypto/asymmetric_keys/pkcs8_parser.c b/crypto/asymmetric_keys/pkcs8_parser.c index 105dcce27f711a..d72e538c405d27 100644 --- a/crypto/asymmetric_keys/pkcs8_parser.c +++ b/crypto/asymmetric_keys/pkcs8_parser.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "pkcs8.asn1.h" struct pkcs8_parse_context { @@ -130,6 +131,22 @@ static struct public_key *pkcs8_parse(const void *data, size_t datalen) return ERR_PTR(ret); } +struct pkcs8_parse_arg { + const void *data; + size_t datalen; +}; + +FUZZ_TEST(test_pkcs8_parse, struct pkcs8_parse_arg) +{ + const size_t max_size = 16 * 1024; + + KFUZZTEST_EXPECT_NOT_NULL(pkcs8_parse_arg, data); + if (arg->datalen > max_size) + return; + + pkcs8_parse(arg->data, arg->datalen); +} + /* * Attempt to parse a data blob for a key as a PKCS#8 private key. */ diff --git a/crypto/rsa_helper.c b/crypto/rsa_helper.c index 94266f29049c92..7e66de1ee23f47 100644 --- a/crypto/rsa_helper.c +++ b/crypto/rsa_helper.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "rsapubkey.asn1.h" #include "rsaprivkey.asn1.h" @@ -166,6 +167,22 @@ int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key, } EXPORT_SYMBOL_GPL(rsa_parse_pub_key); +struct rsa_parse_pub_key_arg { + const void *key; + size_t key_len; +}; + +FUZZ_TEST(test_rsa_parse_pub_key, struct rsa_parse_pub_key_arg) +{ + KFUZZTEST_EXPECT_NOT_NULL(rsa_parse_pub_key_arg, key); + // Bound the maximum size of the key that we accept. + if (arg->key_len > 16 * PAGE_SIZE) + return; + + struct rsa_key out; + rsa_parse_pub_key(&out, arg->key, arg->key_len); +} + /** * rsa_parse_priv_key() - decodes the BER encoded buffer and stores in the * provided struct rsa_key, pointers to the raw key @@ -184,3 +201,19 @@ int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key, return asn1_ber_decoder(&rsaprivkey_decoder, rsa_key, key, key_len); } EXPORT_SYMBOL_GPL(rsa_parse_priv_key); + +struct rsa_parse_priv_key_arg { + const void *key; + size_t key_len; +}; + +FUZZ_TEST(test_rsa_parse_priv_key, struct rsa_parse_priv_key_arg) +{ + KFUZZTEST_EXPECT_NOT_NULL(rsa_parse_priv_key_arg, key); + // bound the maximum size of the key that we accept + if (arg->key_len > 16 * PAGE_SIZE) + return; + + struct rsa_key out; + rsa_parse_priv_key(&out, arg->key, arg->key_len); +} diff --git a/lib/bitmap-str.c b/lib/bitmap-str.c index be745209507a40..1da0261efb5399 100644 --- a/lib/bitmap-str.c +++ b/lib/bitmap-str.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -399,6 +400,33 @@ int bitmap_parselist(const char *buf, unsigned long *maskp, int nmaskbits) } EXPORT_SYMBOL(bitmap_parselist); +struct bitmap_parselist_arg { + const char *buf; + int nmaskbits; +}; + +FUZZ_TEST(test_bitmap_parselist, struct bitmap_parselist_arg) +{ + unsigned long *maskp; + size_t maskp_size; + + KFUZZTEST_EXPECT_NOT_NULL(bitmap_parselist_arg, buf); + KFUZZTEST_EXPECT_IN_RANGE(bitmap_parselist_arg, nmaskbits, 16, + 1024 * 10); + KFUZZTEST_ANNOTATE_STRING(bitmap_parselist_arg, buf); + + // number of longs that we need to allocate + maskp_size = BITS_TO_LONGS(arg->nmaskbits) * sizeof(unsigned long); + maskp = kmalloc(maskp_size, GFP_KERNEL); + if (!maskp) { + pr_warn("bug: failed to allocate kernel buffer for maskp\n"); + return; + } + + bitmap_parselist(arg->buf, maskp, arg->nmaskbits); + + kfree(maskp); +} /** * bitmap_parselist_user() - convert user buffer's list format ASCII diff --git a/lib/oid_registry.c b/lib/oid_registry.c index 9b757a117f09f7..a7140395cd2341 100644 --- a/lib/oid_registry.c +++ b/lib/oid_registry.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "oid_registry_data.c" MODULE_DESCRIPTION("OID Registry"); @@ -85,8 +86,7 @@ enum OID look_up_OID(const void *data, size_t datasize) } } return oid; - next: - ; +next:; } return OID__NR; @@ -172,4 +172,38 @@ int sprint_oid(const void *data, size_t datasize, char *buffer, size_t bufsize) snprintf(buffer, bufsize, "(bad)"); return -EBADMSG; } + +struct sprint_oid_arg { + const char *data; + size_t datasize; + size_t bufsize; +}; + +FUZZ_TEST(test_sprint_oid, struct sprint_oid_arg) +{ + KFUZZTEST_EXPECT_NOT_NULL(sprint_oid_arg, data); + KFUZZTEST_EXPECT_IN_RANGE(sprint_oid_arg, bufsize, 16, PAGE_SIZE); + KFUZZTEST_ANNOTATE_LEN(sprint_oid_arg, datasize, data); + + /* limit to a reasonable bufsize */ + if (arg->bufsize > 4 * PAGE_SIZE) + return; + + /* This actually works - maybe a macro for this?? */ + if (ksize(arg) < sizeof(arg->data) + sizeof(arg->datasize) + + sizeof(arg->bufsize) + arg->datasize) { + pr_warn("invalid buffer size!\n"); + return; + } + + char *buffer = kmalloc(arg->bufsize, GFP_KERNEL); + if (!buffer) { + pr_warn("bug: unable to kmalloc a buffer\n"); + return; + } + + sprint_oid(arg->data, arg->datasize, buffer, arg->bufsize); + kfree(buffer); +} + EXPORT_SYMBOL_GPL(sprint_oid); diff --git a/lib/parser.c b/lib/parser.c index 73e8f8e5be73ff..b9e8c5b1eb88eb 100644 --- a/lib/parser.c +++ b/lib/parser.c @@ -10,6 +10,7 @@ #include #include #include +#include /* * max size needed by different bases to express U64 @@ -151,10 +152,39 @@ static int match_number(substring_t *s, int *result, int base) else if (val < (long)INT_MIN || val > (long)INT_MAX) ret = -ERANGE; else - *result = (int) val; + *result = (int)val; return ret; } +struct match_number_arg { + char *str; + size_t from; + size_t to; + int base; +}; + +FUZZ_TEST(test_match_number, struct match_number_arg) +{ + size_t str_len; + + KFUZZTEST_EXPECT_NOT_NULL(match_number_arg, str); + KFUZZTEST_ANNOTATE_STRING(match_number_arg, str); + KFUZZTEST_ANNOTATE_LEN(match_number_arg, str_len, str); + + str_len = strlen(arg->str); + + /* quite verbose - ideally should encode with some annotation system */ + if (arg->from >= str_len || arg->to >= str_len || arg->from > arg->to) { + return; + } + + substring_t s = { .from = arg->str + arg->from, + .to = arg->str + arg->to }; + + int result; + match_number(&s, &result, arg->base); +} + /** * match_u64int - scan a number in the given base from a substring_t * @s: substring to be scanned diff --git a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c index aaf64b95391507..0349d857b118a2 100644 --- a/net/atm/mpoa_proc.c +++ b/net/atm/mpoa_proc.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -281,6 +282,18 @@ static int parse_qos(const char *buff) return 1; } +struct parse_qos_arg { + const char *buff; +}; + +FUZZ_TEST(test_parse_qos, struct parse_qos_arg) +{ + int ret; + KFUZZTEST_EXPECT_NOT_NULL(parse_qos_arg, buff); + + ret = parse_qos(arg->buff); +} + /* * INITIALIZATION function - called when module is initialized/loaded. */