From f328adff43c5916e149abd598f06898ecd4762f5 Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Fri, 3 Nov 2023 11:56:29 +0000 Subject: [PATCH] QUIC SRTM: Add fuzzer for SRTM Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/22612) --- fuzz/build.info | 12 ++- fuzz/quic-srtm.c | 119 ++++++++++++++++++++++++++ test/recipes/99-test_fuzz_quic_srtm.t | 25 ++++++ 3 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 fuzz/quic-srtm.c create mode 100644 test/recipes/99-test_fuzz_quic_srtm.t diff --git a/fuzz/build.info b/fuzz/build.info index de7cadc79e..bbbc7c9654 100644 --- a/fuzz/build.info +++ b/fuzz/build.info @@ -30,7 +30,7 @@ IF[{- !$disabled{"fuzz-afl"} || !$disabled{"fuzz-libfuzzer"} -}] ENDIF IF[{- !$disabled{"quic"} -}] - PROGRAMS{noinst}=quic-client + PROGRAMS{noinst}=quic-client quic-srtm ENDIF SOURCE[asn1]=asn1.c driver.c fuzz_rand.c @@ -97,6 +97,10 @@ IF[{- !$disabled{"fuzz-afl"} || !$disabled{"fuzz-libfuzzer"} -}] INCLUDE[quic-client]=../include {- $ex_inc -} DEPEND[quic-client]=../libcrypto.a ../libssl.a {- $ex_lib -} + SOURCE[quic-srtm]=quic-srtm.c driver.c fuzz_rand.c + INCLUDE[quic-srtm]=../include {- $ex_inc -} + DEPEND[quic-srtm]=../libcrypto.a ../libssl.a {- $ex_lib -} + SOURCE[server]=server.c driver.c fuzz_rand.c INCLUDE[server]=../include {- $ex_inc -} DEPEND[server]=../libcrypto ../libssl {- $ex_lib -} @@ -128,7 +132,7 @@ IF[{- !$disabled{tests} -}] ENDIF IF[{- !$disabled{"quic"} -}] - PROGRAMS{noinst}=quic-client-test + PROGRAMS{noinst}=quic-client-test quic-srtm-test ENDIF SOURCE[asn1-test]=asn1.c test-corpus.c fuzz_rand.c @@ -196,6 +200,10 @@ IF[{- !$disabled{tests} -}] INCLUDE[quic-client-test]=../include DEPEND[quic-client-test]=../libcrypto.a ../libssl.a + SOURCE[quic-srtm-test]=quic-srtm.c test-corpus.c fuzz_rand.c + INCLUDE[quic-srtm-test]=../include + DEPEND[quic-srtm-test]=../libcrypto.a ../libssl.a + SOURCE[server-test]=server.c test-corpus.c fuzz_rand.c INCLUDE[server-test]=../include DEPEND[server-test]=../libcrypto ../libssl diff --git a/fuzz/quic-srtm.c b/fuzz/quic-srtm.c new file mode 100644 index 0000000000..eb676c2279 --- /dev/null +++ b/fuzz/quic-srtm.c @@ -0,0 +1,119 @@ +/* + * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * https://www.openssl.org/source/license.html + * or in the file LICENSE in the source distribution. + */ + +#include +#include +#include +#include "fuzzer.h" +#include "internal/quic_srtm.h" + +int FuzzerInitialize(int *argc, char ***argv) +{ + FuzzerSetRand(); + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS | OPENSSL_INIT_ASYNC, NULL); + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); + ERR_clear_error(); + return 1; +} + +/* + * Fuzzer input "protocol": + * Big endian + * Zero or more of: + * ADD - u8(0x00) u64(opaque) u64(seq_num) u128(token) + * REMOVE - u8(0x01) u64(opaque) u64(seq_num) + * CULL - u8(0x02) u64(opaque) + * LOOKUP - u8(0x03) u128(token) u64(idx) + */ +enum { + CMD_ADD, + CMD_REMOVE, + CMD_CULL, + CMD_LOOKUP +}; + +int FuzzerTestOneInput(const uint8_t *buf, size_t len) +{ + int rc = 0; + QUIC_SRTM *srtm = NULL; + PACKET pkt; + unsigned int cmd; + uint64_t arg_opaque, arg_seq_num, arg_idx; + QUIC_STATELESS_RESET_TOKEN arg_token; + + if ((srtm = ossl_quic_srtm_new(NULL, NULL)) == NULL) { + rc = -1; + goto err; + } + + if (!PACKET_buf_init(&pkt, buf, len)) + goto err; + + while (PACKET_remaining(&pkt) > 0) { + if (!PACKET_get_1(&pkt, &cmd)) + goto err; + + switch (cmd) { + case CMD_ADD: + if (!PACKET_get_net_8(&pkt, &arg_opaque) + || !PACKET_get_net_8(&pkt, &arg_seq_num) + || !PACKET_copy_bytes(&pkt, arg_token.token, + sizeof(arg_token.token))) + continue; /* just stop */ + + ossl_quic_srtm_add(srtm, (void *)(uintptr_t)arg_opaque, + arg_seq_num, &arg_token); + ossl_quic_srtm_check(srtm); + break; + + case CMD_REMOVE: + if (!PACKET_get_net_8(&pkt, &arg_opaque) + || !PACKET_get_net_8(&pkt, &arg_seq_num)) + continue; /* just stop */ + + ossl_quic_srtm_remove(srtm, (void *)(uintptr_t)arg_opaque, + arg_seq_num); + ossl_quic_srtm_check(srtm); + break; + + case CMD_CULL: + if (!PACKET_get_net_8(&pkt, &arg_opaque)) + continue; /* just stop */ + + ossl_quic_srtm_cull(srtm, (void *)(uintptr_t)arg_opaque); + ossl_quic_srtm_check(srtm); + break; + + case CMD_LOOKUP: + if (!PACKET_copy_bytes(&pkt, arg_token.token, + sizeof(arg_token.token)) + || !PACKET_get_net_8(&pkt, &arg_idx)) + continue; /* just stop */ + + ossl_quic_srtm_lookup(srtm, &arg_token, (size_t)arg_idx, + NULL, NULL); + ossl_quic_srtm_check(srtm); + break; + + default: + /* Other bytes are treated as no-ops */ + continue; + } + } + +err: + ossl_quic_srtm_free(srtm); + return rc; +} + +void FuzzerCleanup(void) +{ + FuzzerClearRand(); +} diff --git a/test/recipes/99-test_fuzz_quic_srtm.t b/test/recipes/99-test_fuzz_quic_srtm.t new file mode 100644 index 0000000000..de27a8764a --- /dev/null +++ b/test/recipes/99-test_fuzz_quic_srtm.t @@ -0,0 +1,25 @@ +#!/usr/bin/env perl +# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use warnings; + +use OpenSSL::Test qw/:DEFAULT srctop_file/; +use OpenSSL::Test::Utils; + +my $fuzzer = "quic-srtm"; +setup("test_fuzz_${fuzzer}"); + +plan skip_all => "This test requires quic support" + if disabled("quic"); + +plan tests => 2; # one more due to below require_ok(...) + +require_ok(srctop_file('test','recipes','fuzz.pl')); + +fuzz_ok($fuzzer);