From a5b9b1e2bcbc3675618812b1162f8909faec2199 Mon Sep 17 00:00:00 2001 From: Angel Castillo Date: Fri, 29 Nov 2024 17:55:30 +0800 Subject: [PATCH] fix: fix fuzz findings --- ...h-23986f99679cd8b4f69c6b2ccc79c2ef0886e0b3 | 1 + ...h-f5ca50f4204486f1b6284ee29ecfad3f6ed4ce28 | 1 + ...k-3313ef1bb4ed55d4f9f0591bdd3e3a02d6138966 | 1 + ...k-ce2bb0d6a1f2acf9ba28c5889c9dbfc38f31532a | 1 + ...k-e61e847e47a640bbe0d0db6ae4390efc742c28f3 | 1 + ...m-893f002584ceb91b3e986886611cbd35687eb4b9 | 1 + .../cbor_reader/cbor_reader_collections.c | 11 ++-- lib/src/transaction_body/transaction_body.c | 10 +++- lib/src/transaction_body/transaction_output.c | 54 +++++++++++++++++++ lib/tests/transaction/transaction.cpp | 36 +++++++++++++ 10 files changed, 111 insertions(+), 6 deletions(-) create mode 100644 fuzz/tx_corpus/crash-23986f99679cd8b4f69c6b2ccc79c2ef0886e0b3 create mode 100644 fuzz/tx_corpus/crash-f5ca50f4204486f1b6284ee29ecfad3f6ed4ce28 create mode 100644 fuzz/tx_corpus/leak-3313ef1bb4ed55d4f9f0591bdd3e3a02d6138966 create mode 100644 fuzz/tx_corpus/leak-ce2bb0d6a1f2acf9ba28c5889c9dbfc38f31532a create mode 100644 fuzz/tx_corpus/leak-e61e847e47a640bbe0d0db6ae4390efc742c28f3 create mode 100644 fuzz/tx_corpus/oom-893f002584ceb91b3e986886611cbd35687eb4b9 diff --git a/fuzz/tx_corpus/crash-23986f99679cd8b4f69c6b2ccc79c2ef0886e0b3 b/fuzz/tx_corpus/crash-23986f99679cd8b4f69c6b2ccc79c2ef0886e0b3 new file mode 100644 index 00000000..3827542b --- /dev/null +++ b/fuzz/tx_corpus/crash-23986f99679cd8b4f69c6b2ccc79c2ef0886e0b3 @@ -0,0 +1 @@ +85A0A406854646ABA0A4068546ABA0A406854646ABA0A406858546ABE406A0A4015F \ No newline at end of file diff --git a/fuzz/tx_corpus/crash-f5ca50f4204486f1b6284ee29ecfad3f6ed4ce28 b/fuzz/tx_corpus/crash-f5ca50f4204486f1b6284ee29ecfad3f6ed4ce28 new file mode 100644 index 00000000..3086e25b --- /dev/null +++ b/fuzz/tx_corpus/crash-f5ca50f4204486f1b6284ee29ecfad3f6ed4ce28 @@ -0,0 +1 @@ +90A0A1039f5f \ No newline at end of file diff --git a/fuzz/tx_corpus/leak-3313ef1bb4ed55d4f9f0591bdd3e3a02d6138966 b/fuzz/tx_corpus/leak-3313ef1bb4ed55d4f9f0591bdd3e3a02d6138966 new file mode 100644 index 00000000..bc2c5266 --- /dev/null +++ b/fuzz/tx_corpus/leak-3313ef1bb4ed55d4f9f0591bdd3e3a02d6138966 @@ -0,0 +1 @@ +88A2080210A2010000F0 \ No newline at end of file diff --git a/fuzz/tx_corpus/leak-ce2bb0d6a1f2acf9ba28c5889c9dbfc38f31532a b/fuzz/tx_corpus/leak-ce2bb0d6a1f2acf9ba28c5889c9dbfc38f31532a new file mode 100644 index 00000000..4d421bd8 --- /dev/null +++ b/fuzz/tx_corpus/leak-ce2bb0d6a1f2acf9ba28c5889c9dbfc38f31532a @@ -0,0 +1 @@ +9A80820260A30208048010A30108010A30100424008f37086f30088f88fff8f9889898 \ No newline at end of file diff --git a/fuzz/tx_corpus/leak-e61e847e47a640bbe0d0db6ae4390efc742c28f3 b/fuzz/tx_corpus/leak-e61e847e47a640bbe0d0db6ae4390efc742c28f3 new file mode 100644 index 00000000..4e7772be --- /dev/null +++ b/fuzz/tx_corpus/leak-e61e847e47a640bbe0d0db6ae4390efc742c28f3 @@ -0,0 +1 @@ +84A104818206820101 \ No newline at end of file diff --git a/fuzz/tx_corpus/oom-893f002584ceb91b3e986886611cbd35687eb4b9 b/fuzz/tx_corpus/oom-893f002584ceb91b3e986886611cbd35687eb4b9 new file mode 100644 index 00000000..1a6dfbf3 --- /dev/null +++ b/fuzz/tx_corpus/oom-893f002584ceb91b3e986886611cbd35687eb4b9 @@ -0,0 +1 @@ +88a10808a10482a10804a1808388a10808a10480a108a10481a41aA1180481a108a10481a41aA11808a10240a10808a10240802208a10240a10808a1024a818844444889688908540802208a10240a220208a10482a1a10804a18083384082a1a14082a1a10a408a121108a10482a10804a1808338a3384082a1a14082a1a10a408a12110804a18083384082a1a18083384082a1a14082a1a10a408a121108a10482a10804a1808338a3384082a1a14082a1a10a408a12110804a18083384082a1a14082a1a10809a1024082020a08a102408207a10482a10804a1808338a10808a188a0a0482a1a10804a18083384082a1a14082a1a10a408a11211080083384082a1a14082a1a10809a1024082020a08a102408207a10482a10804a1808338a10808a188a0a0482a1a10804a18083383A04082a1a14082a1a10a40a10240a10808a10240802208a10240a1080884082a1a14082a1a10a408a11211080083384082a1a14082a1a10809a1024082020a08a102408207a10482a10804a1808338a10808a188a0a0482a1a10804a18083383A04082a1a14082a1a10a40a10240a10240802208a10240a10808a1024a818844444889688908540802208a10240a220208a10482a1a10804a18083384082a1a14082a1a10a408a121108a10482a10804a1808338a3384082a1a14082a1a10a408a12110804a18083384082a1a14082a1a1080a18083384082a1a14082a1a10a408a11211080083384082a1a14082a1a10809a1024082020a08a102408207a10482a10804a1808338a10808a188a0a0482a1a10804a18083383A04082a1a14082a1a10a40a10240a10808a10240802208a10240a1080884082a1a14082a1a10a408a11211080083384082a1a14082a1a10809a1024082020a08a102408207a10482a10804a1808338a10808a188a0a0482a1a10804a18083383A04082a1a14082a1a10a40808338a3384082a1a14082a1a10a408a12110804a18083384082a1a14082a1a10809a1024082020a08a102408207a082a1a14082a1a10809a1024082020a08a102408207a10482a10804a1808338a10808a188a0a0482a1a10804a18083384082a1a14082a1a10a408a112110804a18083384082a1a14082a1a1080983384082a1a14082a1a10809a1024082020a08a102408207a10482a10804a1808338a10808a188a0a0482a1a10804a18083384082a1a14082a1a10a408a11211080083384082a1a14082a1a10809a1024082020a08a102408207a10482a10804a1808338a10808a188a0a0482a1a10804a18083383A04082a1a14082a1a10a40a10240a10808a10240802208a10240a1080884082a1a14082a1a10a408a11211080083384082a1a14082a1a10809a1024082020a08a102408207a10482a10804a1808338a10808a188a0a0482a1a10804a18083383A04082a1a14082a1a10a40a10240a10240802208a10240a10808a1024a818844444889688908540802208a10240a220208a10482a1a10804a18083384082a1a14082a1a10a408a121108a10482a10804a1808338a3384082a1a14082a1a10a408a12110804a18083384082a1a14082a1a1080a18083384082a1a14082a1a10a408a11211080083384082a1a14082a1a10809a1024082020a08a102408207a10482a10804a1808338a10808a188a0a0482a1a10804a18083383A04082a1a14082a1a10a40a10240a10808a10240802208a10240a1080884082a1a14082a1a10a408a11211080083384082a1a14082a1a10809a1024082020a08a102408207a10482a10804a1808338a10808a188a0a0482a1a10804a18083383A04082a1a14082a1a10a40808338a3384082a1a14082a1a10a408a12110804a18083384082a1a14082a1a10809a1024082020a08a102408207a082a1a14082a1a10809a1024082020a08a102408207a10482a10804a1808338a10808a188a0a0482a1a10804a18083384082a1a14082a1a10a408a112110804a18083384082a1a14082a1a10809a10240820102408204008022220808a10240820720a0C3104082a1a10808a1024082040080220400802222088022220808a1024082020a104004a18083384082a1a14082a1a10809a1024082020a04a18083384082a1a14082a1a10809a10240820a07C3104082a1a10808a1024082040080220400802222088022220808a1024082020a104004a18083a10240820102408204008022220808a1024082020a07C3104082a1a10808a1024082040080220400802222088022220808a1024082020a104004a18083384082a1a14082a1a10809a1024082020a04a18083384082a1a14082a1a10809a10240820a07C3104082a1a10808a1024082040080220400802222088022220808a1024082020a104004a18083384082a1a14082a1a10809a1024082020a04a18083384082a1a14082a1a10809a10240820102408204008022220808a1024082020a07C3104082a1a10808a1024082040080220400802222088022220808a1024082020a104004a18083384082a1a14082a1a10809a1024082020a08a102408204008022220808a1024082020a07C3104082a1a10808a10240820400802204008022220808a1024082020a104082a1a10808a1024082040080222202 \ No newline at end of file diff --git a/lib/src/cbor/cbor_reader/cbor_reader_collections.c b/lib/src/cbor/cbor_reader/cbor_reader_collections.c index 1d92652d..dca32daf 100644 --- a/lib/src/cbor/cbor_reader/cbor_reader_collections.c +++ b/lib/src/cbor/cbor_reader/cbor_reader_collections.c @@ -217,7 +217,10 @@ _cbor_reader_read_indefinite_length_concatenated(cardano_cbor_reader_t* reader, cardano_buffer_t* concat = cardano_buffer_new(INITIAL_CONCAT_BUFFER_CAPACITY); - if ((concat == NULL) || (cardano_buffer_get_size(data) == 0U)) + size_t i = HEADER_BYTE_SIZE; + const size_t size = cardano_buffer_get_size(data); + + if ((concat == NULL) || (size <= HEADER_BYTE_SIZE)) { cardano_buffer_unref(&data); cardano_buffer_unref(&concat); @@ -225,9 +228,7 @@ _cbor_reader_read_indefinite_length_concatenated(cardano_cbor_reader_t* reader, return CARDANO_ERROR_DECODING; } - size_t i = HEADER_BYTE_SIZE; - byte_t initial_byte = cardano_buffer_get_data(data)[i]; - const size_t size = cardano_buffer_get_size(data); + byte_t initial_byte = cardano_buffer_get_data(data)[i]; while (initial_byte != CBOR_INITIAL_BYTE_INDEFINITE_LENGTH_BREAK) { @@ -236,7 +237,7 @@ _cbor_reader_read_indefinite_length_concatenated(cardano_cbor_reader_t* reader, cardano_buffer_t* slice = cardano_buffer_slice(data, i, cardano_buffer_get_size(data)); - if (slice == NULL) + if ((slice == NULL) || (cardano_buffer_get_size(slice) == 0U)) { cardano_buffer_unref(&data); cardano_buffer_unref(&concat); diff --git a/lib/src/transaction_body/transaction_body.c b/lib/src/transaction_body/transaction_body.c index a9d05592..be1006eb 100644 --- a/lib/src/transaction_body/transaction_body.c +++ b/lib/src/transaction_body/transaction_body.c @@ -1532,7 +1532,15 @@ cardano_transaction_body_from_cbor(cardano_cbor_reader_t* reader, cardano_transa *transaction_body = body; - return cardano_cbor_validate_end_map("transaction_body", reader); + cardano_error_t validation_result = cardano_cbor_validate_end_map("transaction_body", reader); + + if (validation_result != CARDANO_SUCCESS) + { + cardano_transaction_body_unref(transaction_body); + return validation_result; + } + + return CARDANO_SUCCESS; } cardano_error_t diff --git a/lib/src/transaction_body/transaction_output.c b/lib/src/transaction_body/transaction_output.c index 230b3d5c..668bb660 100644 --- a/lib/src/transaction_body/transaction_output.c +++ b/lib/src/transaction_body/transaction_output.c @@ -179,7 +179,13 @@ cardano_transaction_output_from_cbor(cardano_cbor_reader_t* reader, cardano_tran if (peek_result != CARDANO_SUCCESS) { + cardano_address_unref(&address); + cardano_value_unref(&value); + cardano_datum_unref(&datum); + cardano_script_unref(&script_ref); + *transaction_output = NULL; + return peek_result; } @@ -194,6 +200,11 @@ cardano_transaction_output_from_cbor(cardano_cbor_reader_t* reader, cardano_tran if (read_key_result != CARDANO_SUCCESS) { + cardano_address_unref(&address); + cardano_value_unref(&value); + cardano_datum_unref(&datum); + cardano_script_unref(&script_ref); + *transaction_output = NULL; return read_key_result; } @@ -202,13 +213,20 @@ cardano_transaction_output_from_cbor(cardano_cbor_reader_t* reader, cardano_tran { case 0U: { + cardano_address_unref(&address); cardano_buffer_t* address_bytes = NULL; const cardano_error_t read_address_result = cardano_cbor_reader_read_bytestring(reader, &address_bytes); if (read_address_result != CARDANO_SUCCESS) { + cardano_address_unref(&address); + cardano_value_unref(&value); + cardano_datum_unref(&datum); + cardano_script_unref(&script_ref); + *transaction_output = NULL; + return read_address_result; } @@ -232,6 +250,7 @@ cardano_transaction_output_from_cbor(cardano_cbor_reader_t* reader, cardano_tran } case 1U: { + cardano_value_unref(&value); const cardano_error_t read_value_result = cardano_value_from_cbor(reader, &value); if (read_value_result != CARDANO_SUCCESS) @@ -250,6 +269,7 @@ cardano_transaction_output_from_cbor(cardano_cbor_reader_t* reader, cardano_tran } case 2U: { + cardano_datum_unref(&datum); const cardano_error_t read_datum_result = cardano_datum_from_cbor(reader, &datum); if (read_datum_result != CARDANO_SUCCESS) @@ -268,6 +288,7 @@ cardano_transaction_output_from_cbor(cardano_cbor_reader_t* reader, cardano_tran } case 3U: { + cardano_script_unref(&script_ref); cardano_cbor_tag_t tag; const cardano_error_t read_tag_result = cardano_cbor_reader_read_tag(reader, &tag); @@ -375,6 +396,7 @@ cardano_transaction_output_from_cbor(cardano_cbor_reader_t* reader, cardano_tran if ((new_output_result != CARDANO_SUCCESS) || (set_value_result != CARDANO_SUCCESS) || (set_datum_result != CARDANO_SUCCESS) || (set_script_result != CARDANO_SUCCESS)) { *transaction_output = NULL; + return new_output_result; } } @@ -386,7 +408,13 @@ cardano_transaction_output_from_cbor(cardano_cbor_reader_t* reader, cardano_tran if (read_array_result != CARDANO_SUCCESS) { + cardano_address_unref(&address); + cardano_value_unref(&value); + cardano_datum_unref(&datum); + cardano_script_unref(&script_ref); + *transaction_output = NULL; + return read_array_result; } @@ -396,7 +424,13 @@ cardano_transaction_output_from_cbor(cardano_cbor_reader_t* reader, cardano_tran if (read_address_result != CARDANO_SUCCESS) { + cardano_address_unref(&address); + cardano_value_unref(&value); + cardano_datum_unref(&datum); + cardano_script_unref(&script_ref); + *transaction_output = NULL; + return read_address_result; } @@ -406,7 +440,13 @@ cardano_transaction_output_from_cbor(cardano_cbor_reader_t* reader, cardano_tran if (address_from_bytes_result != CARDANO_SUCCESS) { + cardano_address_unref(&address); + cardano_value_unref(&value); + cardano_datum_unref(&datum); + cardano_script_unref(&script_ref); + *transaction_output = NULL; + return address_from_bytes_result; } @@ -415,7 +455,12 @@ cardano_transaction_output_from_cbor(cardano_cbor_reader_t* reader, cardano_tran if (read_value_result != CARDANO_SUCCESS) { cardano_address_unref(&address); + cardano_value_unref(&value); + cardano_datum_unref(&datum); + cardano_script_unref(&script_ref); + *transaction_output = NULL; + return read_value_result; } @@ -428,6 +473,9 @@ cardano_transaction_output_from_cbor(cardano_cbor_reader_t* reader, cardano_tran { cardano_address_unref(&address); cardano_value_unref(&value); + cardano_datum_unref(&datum); + cardano_script_unref(&script_ref); + *transaction_output = NULL; return read_datum_result; @@ -440,6 +488,9 @@ cardano_transaction_output_from_cbor(cardano_cbor_reader_t* reader, cardano_tran { cardano_address_unref(&address); cardano_value_unref(&value); + cardano_datum_unref(&datum); + cardano_script_unref(&script_ref); + *transaction_output = NULL; return datum_from_hash_result; @@ -453,6 +504,8 @@ cardano_transaction_output_from_cbor(cardano_cbor_reader_t* reader, cardano_tran cardano_address_unref(&address); cardano_value_unref(&value); cardano_datum_unref(&datum); + cardano_script_unref(&script_ref); + *transaction_output = NULL; return expect_end_array_result; @@ -465,6 +518,7 @@ cardano_transaction_output_from_cbor(cardano_cbor_reader_t* reader, cardano_tran cardano_address_unref(&address); cardano_value_unref(&value); cardano_datum_unref(&datum); + cardano_script_unref(&script_ref); if ((new_output_result != CARDANO_SUCCESS) || (set_value_result != CARDANO_SUCCESS) || (set_datum_result != CARDANO_SUCCESS)) { diff --git a/lib/tests/transaction/transaction.cpp b/lib/tests/transaction/transaction.cpp index 500121a6..b5a45864 100644 --- a/lib/tests/transaction/transaction.cpp +++ b/lib/tests/transaction/transaction.cpp @@ -1112,4 +1112,40 @@ TEST(cardano_transaction_has_script_data, returnsFalseIfNoScriptData) // Cleanup cardano_transaction_unref(&transaction); +} + +TEST(cardano_transaction_from_cbor, returnsDecodingErrorIfRepeatedKeyInOutput) +{ + // Arrange + cardano_transaction_t* transaction = NULL; + const char* cbor = "9a80820260a30208048010a30108010a30100424008f37086f30088f88fff8f9889898"; + cardano_cbor_reader_t* reader = cardano_cbor_reader_from_hex(cbor, strlen(cbor)); + + // Act + cardano_error_t result = cardano_transaction_from_cbor(reader, &transaction); + + // Assert + EXPECT_EQ(result, CARDANO_ERROR_DECODING); + + // Cleanup + cardano_cbor_reader_unref(&reader); + cardano_transaction_unref(&transaction); +} + +TEST(cardano_transaction_from_cbor, returnsDecodingErrorIfInvalidAddressInKeyInOutput) +{ + // Arrange + cardano_transaction_t* transaction = NULL; + const char* cbor = "88A2080210A2010000F0"; + cardano_cbor_reader_t* reader = cardano_cbor_reader_from_hex(cbor, strlen(cbor)); + + // Act + cardano_error_t result = cardano_transaction_from_cbor(reader, &transaction); + + // Assert + EXPECT_EQ(result, CARDANO_ERROR_DECODING); + + // Cleanup + cardano_cbor_reader_unref(&reader); + cardano_transaction_unref(&transaction); } \ No newline at end of file