From 60d2d189adb2a253d9df184c69b5dc3bf6ec4640 Mon Sep 17 00:00:00 2001 From: Kevin Albertson Date: Mon, 30 Mar 2026 14:41:53 -0400 Subject: [PATCH 1/3] add regression test --- kms-message/test/test_kmip_reader_writer.c | 28 ++++++++++++++++++++++ kms-message/test/test_kms_request.c | 2 ++ 2 files changed, 30 insertions(+) diff --git a/kms-message/test/test_kmip_reader_writer.c b/kms-message/test/test_kmip_reader_writer.c index fa164a3b9..37b088387 100644 --- a/kms-message/test/test_kmip_reader_writer.c +++ b/kms-message/test/test_kmip_reader_writer.c @@ -443,6 +443,34 @@ kms_kmip_reader_find_and_recurse_test (void) free (data); } +void kms_kmip_reader_find_and_recurse_invalid_test (void); // -Wmissing-prototypes: for testing only. +void +kms_kmip_reader_find_and_recurse_invalid_test (void) +{ + uint8_t *data; + size_t datalen; + kmip_reader_t *reader; + size_t pos = 0; + size_t len = 0; + + // Structure with overly large length: + data = hex_to_data ( + "42 00 20 | 01 | 00 00 00 FF", // Struct with bad length + &datalen); + + reader = kmip_reader_new (data, datalen); + ASSERT (kmip_reader_find_and_recurse (reader, KMIP_TAG_CompromiseDate)); + + // Expect error: + ASSERT(!kmip_reader_find (reader, + KMIP_TAG_ApplicationSpecificInformation, + KMIP_ITEM_TYPE_Enumeration, + &pos, + &len)); + kmip_reader_destroy (reader); + free (data); +} + void kms_kmip_reader_find_and_read_enum_test (void); // -Wmissing-prototypes: for testing only. void kms_kmip_reader_find_and_read_enum_test (void) diff --git a/kms-message/test/test_kms_request.c b/kms-message/test/test_kms_request.c index 7e696c9fd..9fdb34171 100644 --- a/kms-message/test/test_kms_request.c +++ b/kms-message/test/test_kms_request.c @@ -1216,6 +1216,7 @@ extern void kms_kmip_reader_test (void); extern void kms_kmip_reader_negative_int_test (void); extern void kms_kmip_reader_find_test (void); extern void kms_kmip_reader_find_and_recurse_test (void); +extern void kms_kmip_reader_find_and_recurse_invalid_test (void); extern void kms_kmip_reader_find_and_read_enum_test (void); extern void kms_kmip_reader_find_and_read_bytes_test (void); extern void kms_kmip_request_register_secretdata_test (void); @@ -1280,6 +1281,7 @@ main (int argc, char *argv[]) RUN_TEST (kms_kmip_reader_negative_int_test); RUN_TEST (kms_kmip_reader_test); RUN_TEST (kms_kmip_reader_find_and_recurse_test); + RUN_TEST (kms_kmip_reader_find_and_recurse_invalid_test); RUN_TEST (kms_kmip_reader_find_and_read_enum_test); RUN_TEST (kms_kmip_reader_find_and_read_bytes_test); RUN_TEST (kms_kmip_request_register_secretdata_test); From 4e4d14492cf13384cadf85a65bf173500234ce2d Mon Sep 17 00:00:00 2001 From: Kevin Albertson Date: Mon, 30 Mar 2026 14:54:42 -0400 Subject: [PATCH 2/3] MONGOCRYPT-891 check length before recursing --- kms-message/src/kms_kmip_reader_writer.c | 1 + kms-message/test/test_kmip_reader_writer.c | 10 +--------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/kms-message/src/kms_kmip_reader_writer.c b/kms-message/src/kms_kmip_reader_writer.c index aea16657f..b9a7f6577 100644 --- a/kms-message/src/kms_kmip_reader_writer.c +++ b/kms-message/src/kms_kmip_reader_writer.c @@ -451,6 +451,7 @@ kmip_reader_find (kmip_reader_t *reader, if (read_tag == search_tag && read_type == type) { *pos = reader->pos; *length = read_length; + CHECK_REMAINING_BUFFER_AND_RET (compute_padded_length(read_length)); return true; } diff --git a/kms-message/test/test_kmip_reader_writer.c b/kms-message/test/test_kmip_reader_writer.c index 37b088387..94d721806 100644 --- a/kms-message/test/test_kmip_reader_writer.c +++ b/kms-message/test/test_kmip_reader_writer.c @@ -450,8 +450,6 @@ kms_kmip_reader_find_and_recurse_invalid_test (void) uint8_t *data; size_t datalen; kmip_reader_t *reader; - size_t pos = 0; - size_t len = 0; // Structure with overly large length: data = hex_to_data ( @@ -459,14 +457,8 @@ kms_kmip_reader_find_and_recurse_invalid_test (void) &datalen); reader = kmip_reader_new (data, datalen); - ASSERT (kmip_reader_find_and_recurse (reader, KMIP_TAG_CompromiseDate)); - // Expect error: - ASSERT(!kmip_reader_find (reader, - KMIP_TAG_ApplicationSpecificInformation, - KMIP_ITEM_TYPE_Enumeration, - &pos, - &len)); + ASSERT (!kmip_reader_find_and_recurse (reader, KMIP_TAG_CompromiseDate)); kmip_reader_destroy (reader); free (data); } From a4fc51d31f5c90010f7d7835e9e71edd34aee5ab Mon Sep 17 00:00:00 2001 From: Kevin Albertson Date: Mon, 30 Mar 2026 15:02:23 -0400 Subject: [PATCH 3/3] add check in kmip_reader_find_and_recurse as safety check --- kms-message/src/kms_kmip_reader_writer.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kms-message/src/kms_kmip_reader_writer.c b/kms-message/src/kms_kmip_reader_writer.c index b9a7f6577..9a139d919 100644 --- a/kms-message/src/kms_kmip_reader_writer.c +++ b/kms-message/src/kms_kmip_reader_writer.c @@ -478,6 +478,10 @@ kmip_reader_find_and_recurse (kmip_reader_t *reader, kmip_tag_type_t tag) } reader->pos = 0; + + if (pos + compute_padded_length (length) > reader->len) { + return false; + } reader->ptr = reader->ptr + pos; reader->len = length; return true;