From ba7520da7d198e0cac27fcfda96647ae4be08701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20C=2E=20S=C3=A1nchez?= Date: Wed, 5 Feb 2025 17:52:52 -0500 Subject: [PATCH 01/14] check return value of bson_init_static CID: 100057 --- src/libmongoc/src/mongoc/mongoc-server-description.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libmongoc/src/mongoc/mongoc-server-description.c b/src/libmongoc/src/mongoc/mongoc-server-description.c index 439e8498e34..248e7ac6ab0 100644 --- a/src/libmongoc/src/mongoc/mongoc-server-description.c +++ b/src/libmongoc/src/mongoc/mongoc-server-description.c @@ -790,7 +790,7 @@ mongoc_server_description_new_copy (const mongoc_server_description_t *descripti const uint8_t *data = bson_get_data (©->last_hello_response) + offset; \ uint32_t len = description->FIELD.len; \ MONGOC_DEBUG_ASSERT (offset + len <= copy->last_hello_response.len); \ - bson_init_static (©->FIELD, data, len); \ + BSON_ASSERT (bson_init_static (©->FIELD, data, len)); \ } else { \ bson_init (©->FIELD); \ } \ From c5d318a6792d0926501b59250ce154b5a1fd3cff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20C=2E=20S=C3=A1nchez?= Date: Wed, 5 Feb 2025 18:16:06 -0500 Subject: [PATCH 02/14] check return value of malloc CID: 100087 --- src/libbson/src/jsonsl/jsonsl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libbson/src/jsonsl/jsonsl.c b/src/libbson/src/jsonsl/jsonsl.c index 045132aa2dc..74b57d40eab 100644 --- a/src/libbson/src/jsonsl/jsonsl.c +++ b/src/libbson/src/jsonsl/jsonsl.c @@ -1149,6 +1149,9 @@ void jsonsl_jpr_match_state_init(jsonsl_t jsn, return; } jsn->jprs = (jsonsl_jpr_t *)malloc(sizeof(jsonsl_jpr_t) * njprs); + if (!jsn->jprs) { + return; + } jsn->jpr_count = njprs; jsn->jpr_root = (size_t*)calloc(1, sizeof(size_t) * njprs * jsn->levels_max); memcpy(jsn->jprs, jprs, sizeof(jsonsl_jpr_t) * njprs); From e096053a31687aa5bcdc2f2f991312d3aeade215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20C=2E=20S=C3=A1nchez?= Date: Thu, 6 Feb 2025 10:36:47 -0500 Subject: [PATCH 03/14] add bounds check to ensure int32_t fits in size_t CID: 112395 --- src/tools/mongoc-stat.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tools/mongoc-stat.c b/src/tools/mongoc-stat.c index 4aa0bba763c..43b24baed6c 100644 --- a/src/tools/mongoc-stat.c +++ b/src/tools/mongoc-stat.c @@ -29,6 +29,11 @@ #include #include +#define BSON_INSIDE +#define MONGOC_INSIDE +#include +#undef MONGOC_INSIDE +#undef BSON_INSIDE #pragma pack(1) typedef struct { @@ -108,6 +113,7 @@ mongoc_counters_new_from_pid (unsigned pid) return NULL; } + BSON_ASSERT (mlib_in_range (size_t, len)); size = len; if (MAP_FAILED == (mem = mmap (NULL, size, PROT_READ, MAP_SHARED, fd, 0))) { From 3bf95a7d8d113df59f5431fffa33f86d0557bf5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20C=2E=20S=C3=A1nchez?= Date: Thu, 6 Feb 2025 11:19:56 -0500 Subject: [PATCH 04/14] check return value of bson_iter_init CID: 115840, 115848, 115851, 115853 --- src/libmongoc/src/mongoc/mongoc-client-session.c | 4 +++- src/libmongoc/src/mongoc/mongoc-collection.c | 8 ++++++-- src/libmongoc/src/mongoc/mongoc-uri.c | 10 ++++++++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/libmongoc/src/mongoc/mongoc-client-session.c b/src/libmongoc/src/mongoc/mongoc-client-session.c index af595e5544f..0ffbd210d8f 100644 --- a/src/libmongoc/src/mongoc/mongoc-client-session.c +++ b/src/libmongoc/src/mongoc/mongoc-client-session.c @@ -886,7 +886,9 @@ _max_time_ms_failure (bson_t *reply) return true; } - bson_iter_init (&iter, reply); + if (!bson_iter_init (&iter, reply)) { + return false; + } if (bson_iter_find_descendant (&iter, "writeConcernError.codeName", &descendant) && BSON_ITER_HOLDS_UTF8 (&descendant) && 0 == strcmp (bson_iter_utf8 (&descendant, NULL), MAX_TIME_MS_EXPIRED)) { return true; diff --git a/src/libmongoc/src/mongoc/mongoc-collection.c b/src/libmongoc/src/mongoc/mongoc-collection.c index 64dd81a231a..5bfb38438cd 100644 --- a/src/libmongoc/src/mongoc/mongoc-collection.c +++ b/src/libmongoc/src/mongoc/mongoc-collection.c @@ -1255,8 +1255,12 @@ _mongoc_collection_index_keys_equal (const bson_t *expected, const bson_t *actua bson_iter_t iter_expected; bson_iter_t iter_actual; - bson_iter_init (&iter_expected, expected); - bson_iter_init (&iter_actual, actual); + if (!bson_iter_init (&iter_expected, expected)) { + return false; + } + if (!bson_iter_init (&iter_actual, actual)) { + return false; + } while (bson_iter_next (&iter_expected)) { /* If the key document has fewer items than expected, indexes are unequal diff --git a/src/libmongoc/src/mongoc/mongoc-uri.c b/src/libmongoc/src/mongoc/mongoc-uri.c index 6cac707770f..383b04e1ae0 100644 --- a/src/libmongoc/src/mongoc/mongoc-uri.c +++ b/src/libmongoc/src/mongoc/mongoc-uri.c @@ -953,7 +953,10 @@ mongoc_uri_options_validate_names (const bson_t *a, const bson_t *b, bson_error_ /* Scan `a` looking for deprecated names * where the canonical name was also used in `a`, * or was used in `b`. */ - bson_iter_init (&key_iter, a); + if (!bson_iter_init (&key_iter, a)) { + return false; + } + while (bson_iter_next (&key_iter)) { key = bson_iter_key (&key_iter); value = bson_iter_utf8_unsafe (&key_iter, &value_len); @@ -1017,7 +1020,10 @@ mongoc_uri_apply_options (mongoc_uri_t *uri, const bson_t *options, bool from_dn size_t value_len; bool bval; - bson_iter_init (&iter, options); + if (!bson_iter_init (&iter, options)) { + return false; + } + while (bson_iter_next (&iter)) { key = bson_iter_key (&iter); canon = mongoc_uri_canonicalize_option (key); From 33ce86f901ccb1da6c05834ee7eda3b3ea916f2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20C=2E=20S=C3=A1nchez?= Date: Thu, 6 Feb 2025 13:47:47 -0500 Subject: [PATCH 05/14] check bounds on return value from sysconf CID: 134019 --- src/libmongoc/src/mongoc/mongoc-counters.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libmongoc/src/mongoc/mongoc-counters.c b/src/libmongoc/src/mongoc/mongoc-counters.c index fef74d29542..502227e87df 100644 --- a/src/libmongoc/src/mongoc/mongoc-counters.c +++ b/src/libmongoc/src/mongoc/mongoc-counters.c @@ -111,7 +111,9 @@ mongoc_counters_calc_size (void) (n_cpu * n_groups * sizeof (mongoc_counter_slots_t))); #ifdef BSON_OS_UNIX - return BSON_MAX (sysconf (_SC_PAGESIZE), size); + long pg_sz = sysconf (_SC_PAGESIZE); + BSON_ASSERT (pg_sz > 0); + return BSON_MAX (pg_sz, size); #else return size; #endif From 0cd7445a84b841a70c5fb4a7ea476bbc7f956fc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20C=2E=20S=C3=A1nchez?= Date: Thu, 6 Feb 2025 14:21:56 -0500 Subject: [PATCH 06/14] check return when calling pthread_once/InitOnceExecuteOnce CID: 138314 --- src/common/src/common-b64.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/common/src/common-b64.c b/src/common/src/common-b64.c index c41d963b212..0ae3da2082b 100644 --- a/src/common/src/common-b64.c +++ b/src/common/src/common-b64.c @@ -263,14 +263,20 @@ static const uint8_t mongoc_b64rmap_invalid = 0xff; #if defined(BSON_OS_UNIX) #include #define mongoc_common_once_t pthread_once_t -#define mongoc_common_once pthread_once +#define mongoc_common_once(o, c) \ + do { \ + Assert (pthread_once ((o), (c)) == 0); \ + } while (0) #define MONGOC_COMMON_ONCE_FUN(n) void n (void) #define MONGOC_COMMON_ONCE_RETURN return #define MONGOC_COMMON_ONCE_INIT PTHREAD_ONCE_INIT #else #define mongoc_common_once_t INIT_ONCE #define MONGOC_COMMON_ONCE_INIT INIT_ONCE_STATIC_INIT -#define mongoc_common_once(o, c) InitOnceExecuteOnce (o, c, NULL, NULL) +#define mongoc_common_once(o, c) \ + do { \ + Assert (InitOnceExecuteOnce (o, c, NULL, NULL) != 0); \ + } while (0) #define MONGOC_COMMON_ONCE_FUN(n) BOOL CALLBACK n (PINIT_ONCE _ignored_a, PVOID _ignored_b, PVOID *_ignored_c) #define MONGOC_COMMON_ONCE_RETURN return true #endif From 8faf0364d3108a4c5c41a5531088e493ae27afbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20C=2E=20S=C3=A1nchez?= Date: Tue, 11 Feb 2025 17:47:03 -0500 Subject: [PATCH 07/14] explicit cast to int64_t CID: 138986 --- src/libbson/src/bson/bson-json.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libbson/src/bson/bson-json.c b/src/libbson/src/bson/bson-json.c index 3952203746d..308df723ca6 100644 --- a/src/libbson/src/bson/bson-json.c +++ b/src/libbson/src/bson/bson-json.c @@ -620,9 +620,10 @@ _bson_json_read_integer (bson_json_reader_t *reader, uint64_t val, int64_t sign) if (rs == BSON_JSON_REGULAR) { BASIC_CB_BAIL_IF_NOT_NORMAL ("integer"); + BSON_ASSERT (mlib_in_range (int, len)); if (val <= INT32_MAX || (sign == -1 && val <= (uint64_t) INT32_MAX + 1)) { - bson_append_int32 (STACK_BSON_CHILD, key, (int) len, (int) (val * sign)); + bson_append_int32 (STACK_BSON_CHILD, key, (int) len, (int32_t) ((int64_t) val * sign)); } else if (sign == -1) { #if defined(_WIN32) && !defined(__MINGW32__) // Unary negation of unsigned integer is deliberate. From a6c0bb573c27b4072f54008c5c014db5ea2e8f7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20C=2E=20S=C3=A1nchez?= Date: Tue, 11 Feb 2025 19:32:20 -0500 Subject: [PATCH 08/14] bounds check when summing return from send() CID: 138989 --- src/libmongoc/src/mongoc/mongoc-socket.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libmongoc/src/mongoc/mongoc-socket.c b/src/libmongoc/src/mongoc/mongoc-socket.c index 5558419caef..6154ef38e4f 100644 --- a/src/libmongoc/src/mongoc/mongoc-socket.c +++ b/src/libmongoc/src/mongoc/mongoc-socket.c @@ -1207,6 +1207,7 @@ _mongoc_socket_try_sendv_slow (mongoc_socket_t *sock, /* IN */ RETURN (ret ? ret : -1); } + BSON_ASSERT (mlib_cmp (wrote, <=, SSIZE_MAX - ret)); ret += wrote; if (mlib_cmp (wrote, !=, iov[i].iov_len)) { From 9e0abfcb5e3537558bc12255072dff390ca50d0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20C=2E=20S=C3=A1nchez?= Date: Thu, 13 Feb 2025 13:56:15 -0500 Subject: [PATCH 09/14] acquire mutex before modifying topology CID: 156373 --- .../src/mongoc/mongoc-topology-background-monitoring.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring.c b/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring.c index c42b32b54df..1aaa736f28f 100644 --- a/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring.c +++ b/src/libmongoc/src/mongoc/mongoc-topology-background-monitoring.c @@ -311,10 +311,12 @@ _mongoc_topology_background_monitoring_stop (mongoc_topology_t *topology) } /* Signal all RTT monitors to shut down. */ + bson_mutex_lock (&topology->tpld_modification_mtx); for (size_t i = 0u; i < n_rtt_monitors; i++) { server_monitor = mongoc_set_get_item (topology->rtt_monitors, i); mongoc_server_monitor_request_shutdown (server_monitor); } + bson_mutex_unlock (&topology->tpld_modification_mtx); for (size_t i = 0u; i < n_srv_monitors; i++) { /* Wait for the thread to shutdown. */ From 2509ba11941cc3581f9c559c96402bba282cb582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20C=2E=20S=C3=A1nchez?= Date: Thu, 13 Feb 2025 14:29:01 -0500 Subject: [PATCH 10/14] ensure a NULL pointer is not dereferenced CID: 157950 --- src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c | 4 ++++ src/libmongoc/src/mongoc/mongoc-stream-tls.c | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c b/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c index 3145f876cea..2989c912524 100644 --- a/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c +++ b/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c @@ -843,6 +843,10 @@ create_stream_with_ctx ( mongoc_stream_t * mongoc_stream_tls_openssl_new (mongoc_stream_t *base_stream, const char *host, mongoc_ssl_opt_t *opt, int client) { + if (!opt) { + RETURN (NULL); + } + SSL_CTX *ssl_ctx = _mongoc_openssl_ctx_new (opt); if (!ssl_ctx) { diff --git a/src/libmongoc/src/mongoc/mongoc-stream-tls.c b/src/libmongoc/src/mongoc/mongoc-stream-tls.c index 19f62d5afe8..8c567cb643f 100644 --- a/src/libmongoc/src/mongoc/mongoc-stream-tls.c +++ b/src/libmongoc/src/mongoc/mongoc-stream-tls.c @@ -194,13 +194,13 @@ mongoc_stream_tls_new_with_hostname (mongoc_stream_t *base_stream, const char *h /* !client is only used for testing, * when the streams are pretending to be the server */ - if (!client || opt->weak_cert_validation) { + if (opt && (!client || opt->weak_cert_validation)) { opt->allow_invalid_hostname = true; } #ifndef _WIN32 /* Silly check for Unix Domain Sockets */ - if (!host || (host[0] == '/' && !access (host, F_OK))) { + if (opt && (!host || (host[0] == '/' && !access (host, F_OK)))) { opt->allow_invalid_hostname = true; } #endif @@ -255,13 +255,13 @@ mongoc_stream_tls_new_with_hostname_and_openssl_context ( /* !client is only used for testing, * when the streams are pretending to be the server */ - if (!client || opt->weak_cert_validation) { + if (opt && (!client || opt->weak_cert_validation)) { opt->allow_invalid_hostname = true; } #ifndef _WIN32 /* Silly check for Unix Domain Sockets */ - if (!host || (host[0] == '/' && !access (host, F_OK))) { + if (opt && (!host || (host[0] == '/' && !access (host, F_OK)))) { opt->allow_invalid_hostname = true; } #endif From 084b2f10ad7c47e976ffc87822433ef6d7a2a64c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20C=2E=20S=C3=A1nchez?= Date: Tue, 18 Feb 2025 19:14:53 -0500 Subject: [PATCH 11/14] static cast to ensure proper comparison Co-authored-by: vector-of-bool --- src/libmongoc/src/mongoc/mongoc-counters.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libmongoc/src/mongoc/mongoc-counters.c b/src/libmongoc/src/mongoc/mongoc-counters.c index 502227e87df..3ce070828f4 100644 --- a/src/libmongoc/src/mongoc/mongoc-counters.c +++ b/src/libmongoc/src/mongoc/mongoc-counters.c @@ -113,7 +113,7 @@ mongoc_counters_calc_size (void) #ifdef BSON_OS_UNIX long pg_sz = sysconf (_SC_PAGESIZE); BSON_ASSERT (pg_sz > 0); - return BSON_MAX (pg_sz, size); + return BSON_MAX ((size_t) pg_sz, size); #else return size; #endif From 41ac6b55799de10a50222e30a6de777331b2966f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20C=2E=20S=C3=A1nchez?= Date: Tue, 18 Feb 2025 18:36:58 -0500 Subject: [PATCH 12/14] remove wrapping macros --- src/tools/mongoc-stat.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/tools/mongoc-stat.c b/src/tools/mongoc-stat.c index 43b24baed6c..a47bb47e8c1 100644 --- a/src/tools/mongoc-stat.c +++ b/src/tools/mongoc-stat.c @@ -29,11 +29,7 @@ #include #include -#define BSON_INSIDE -#define MONGOC_INSIDE #include -#undef MONGOC_INSIDE -#undef BSON_INSIDE #pragma pack(1) typedef struct { From 93a023084468a2456f9dbd25529d74e9d4452060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20C=2E=20S=C3=A1nchez?= Date: Tue, 18 Feb 2025 18:50:16 -0500 Subject: [PATCH 13/14] use BSON_ASSERT instead of Boolean check for opt --- src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c | 4 +--- src/libmongoc/src/mongoc/mongoc-stream-tls.c | 5 +++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c b/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c index 2989c912524..d9727471027 100644 --- a/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c +++ b/src/libmongoc/src/mongoc/mongoc-stream-tls-openssl.c @@ -843,9 +843,7 @@ create_stream_with_ctx ( mongoc_stream_t * mongoc_stream_tls_openssl_new (mongoc_stream_t *base_stream, const char *host, mongoc_ssl_opt_t *opt, int client) { - if (!opt) { - RETURN (NULL); - } + BSON_ASSERT (opt); SSL_CTX *ssl_ctx = _mongoc_openssl_ctx_new (opt); diff --git a/src/libmongoc/src/mongoc/mongoc-stream-tls.c b/src/libmongoc/src/mongoc/mongoc-stream-tls.c index 8c567cb643f..9cb2565ac9a 100644 --- a/src/libmongoc/src/mongoc/mongoc-stream-tls.c +++ b/src/libmongoc/src/mongoc/mongoc-stream-tls.c @@ -252,16 +252,17 @@ mongoc_stream_tls_new_with_hostname_and_openssl_context ( mongoc_stream_t *base_stream, const char *host, mongoc_ssl_opt_t *opt, int client, SSL_CTX *ssl_ctx) { BSON_ASSERT (base_stream); + BSON_ASSERT (opt); /* !client is only used for testing, * when the streams are pretending to be the server */ - if (opt && (!client || opt->weak_cert_validation)) { + if (!client || opt->weak_cert_validation) { opt->allow_invalid_hostname = true; } #ifndef _WIN32 /* Silly check for Unix Domain Sockets */ - if (opt && (!host || (host[0] == '/' && !access (host, F_OK)))) { + if (!host || (host[0] == '/' && !access (host, F_OK))) { opt->allow_invalid_hostname = true; } #endif From ad9b33603279f2606aa3114c15d0667e444b9745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20C=2E=20S=C3=A1nchez?= Date: Tue, 18 Feb 2025 20:00:08 -0500 Subject: [PATCH 14/14] also check return value of calloc --- src/libbson/src/jsonsl/jsonsl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libbson/src/jsonsl/jsonsl.c b/src/libbson/src/jsonsl/jsonsl.c index 74b57d40eab..5f4a0d04a12 100644 --- a/src/libbson/src/jsonsl/jsonsl.c +++ b/src/libbson/src/jsonsl/jsonsl.c @@ -1154,6 +1154,10 @@ void jsonsl_jpr_match_state_init(jsonsl_t jsn, } jsn->jpr_count = njprs; jsn->jpr_root = (size_t*)calloc(1, sizeof(size_t) * njprs * jsn->levels_max); + if (!jsn->jpr_root) { + free(jsn->jprs); + return; + } memcpy(jsn->jprs, jprs, sizeof(jsonsl_jpr_t) * njprs); /* Set the initial jump table values */