Skip to content

Commit ce20fd4

Browse files
authored
CDRIVER-4820 check return values of bson_snprintf (#1642)
CDRIVER-4820 check return values of `bson_snprintf`
1 parent b294552 commit ce20fd4

18 files changed

+112
-58
lines changed

src/libbson/src/bson/bson-decimal128.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,9 @@ bson_decimal128_to_string (const bson_decimal128_t *dec, /* IN */
269269
}
270270
/* Exponent */
271271
*(str_out++) = 'E';
272-
bson_snprintf (str_out, 6, "%+d", scientific_exponent);
272+
// Truncation is OK.
273+
int req = bson_snprintf (str_out, 6, "%+d", scientific_exponent);
274+
BSON_ASSERT (req > 0);
273275
} else {
274276
/* Regular format with no decimal place */
275277
if (exponent >= 0) {

src/libbson/src/bson/bson-keys.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include <bson/bson-keys.h>
2121
#include <bson/bson-string.h>
22+
#include <bson/bson-cmp.h>
2223

2324

2425
static const char *gUint32Strs[] = {
@@ -141,5 +142,9 @@ bson_uint32_to_string (uint32_t value, /* IN */
141142

142143
*strptr = str;
143144

144-
return bson_snprintf (str, size, "%u", value);
145+
int ret = bson_snprintf (str, size, "%u", value);
146+
// Truncation is OK.
147+
BSON_ASSERT (ret > 0);
148+
BSON_ASSERT (bson_in_range_size_t_signed (ret));
149+
return (size_t) ret;
145150
}

src/libmongoc/src/mongoc/mongoc-client.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,9 @@ mongoc_client_connect_tcp (int32_t connecttimeoutms, const mongoc_host_list_t *h
618618
BSON_ASSERT (connecttimeoutms);
619619
BSON_ASSERT (host);
620620

621-
bson_snprintf (portstr, sizeof portstr, "%hu", host->port);
621+
// Expect no truncation.
622+
int req = bson_snprintf (portstr, sizeof portstr, "%hu", host->port);
623+
BSON_ASSERT (bson_cmp_less_su (req, sizeof portstr));
622624

623625
memset (&hints, 0, sizeof hints);
624626
hints.ai_family = host->family;
@@ -712,7 +714,13 @@ mongoc_client_connect_unix (const mongoc_host_list_t *host, bson_error_t *error)
712714

713715
memset (&saddr, 0, sizeof saddr);
714716
saddr.sun_family = AF_UNIX;
715-
bson_snprintf (saddr.sun_path, sizeof saddr.sun_path - 1, "%s", host->host);
717+
// Expect no truncation.
718+
int req = bson_snprintf (saddr.sun_path, sizeof saddr.sun_path - 1, "%s", host->host);
719+
720+
if (bson_cmp_greater_equal_su (req, sizeof saddr.sun_path - 1)) {
721+
bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failed to define socket address path.");
722+
RETURN (NULL);
723+
}
716724

717725
sock = mongoc_socket_new (AF_UNIX, SOCK_STREAM, 0);
718726

src/libmongoc/src/mongoc/mongoc-cluster-aws.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,9 @@ generate_AWS_ROLE_SESSION_NAME (bson_error_t *error)
354354

355355
size_t i;
356356
for (i = 0; i < NUM_BYTES; i++) {
357-
bson_snprintf (out + (2 * i), 3, "%02x", data[i]);
357+
// Expect no truncation.
358+
int req = bson_snprintf (out + (2 * i), 3, "%02x", data[i]);
359+
BSON_ASSERT (req < 3);
358360
}
359361
out[NUM_BYTES * 2] = '\0';
360362

src/libmongoc/src/mongoc/mongoc-counters.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,9 @@ _mongoc_counters_cleanup (void)
136136
int pid;
137137

138138
pid = getpid ();
139-
bson_snprintf (name, sizeof name, "/mongoc-%u", pid);
139+
// Truncation is OK.
140+
int req = bson_snprintf (name, sizeof name, "/mongoc-%u", pid);
141+
BSON_ASSERT (req > 0);
140142
shm_unlink (name);
141143
#endif
142144
}
@@ -168,7 +170,9 @@ mongoc_counters_alloc (size_t size)
168170
}
169171

170172
pid = getpid ();
171-
bson_snprintf (name, sizeof name, "/mongoc-%u", pid);
173+
// Truncation is OK.
174+
int req = bson_snprintf (name, sizeof name, "/mongoc-%u", pid);
175+
BSON_ASSERT (req > 0);
172176

173177
#ifndef O_NOFOLLOW
174178
#define O_NOFOLLOW 0

src/libmongoc/src/mongoc/mongoc-crypt.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,9 @@ _prefix_mongocryptd_error (bson_error_t *error)
166166
{
167167
char buf[sizeof (error->message)];
168168

169-
bson_snprintf (buf, sizeof (buf), "mongocryptd error: %s:", error->message);
169+
// Truncation is OK.
170+
int req = bson_snprintf (buf, sizeof (buf), "mongocryptd error: %s:", error->message);
171+
BSON_ASSERT (req > 0);
170172
memcpy (error->message, buf, sizeof (buf));
171173
}
172174

@@ -175,7 +177,9 @@ _prefix_keyvault_error (bson_error_t *error)
175177
{
176178
char buf[sizeof (error->message)];
177179

178-
bson_snprintf (buf, sizeof (buf), "key vault error: %s:", error->message);
180+
// Truncation is OK.
181+
int req = bson_snprintf (buf, sizeof (buf), "key vault error: %s:", error->message);
182+
BSON_ASSERT (req > 0);
179183
memcpy (error->message, buf, sizeof (buf));
180184
}
181185

src/libmongoc/src/mongoc/mongoc-gridfs-bucket.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,18 @@ mongoc_gridfs_bucket_new (mongoc_database_t *db,
102102
"bucketName \"%s\" must have fewer than %d characters",
103103
gridfs_opts.bucketName,
104104
(int) (sizeof (buf) - (strlen (".chunks") + 1)));
105+
return NULL;
105106
}
106107

107108
bucket = (mongoc_gridfs_bucket_t *) bson_malloc0 (sizeof *bucket);
108109

109-
bson_snprintf (buf, sizeof (buf), "%s.chunks", gridfs_opts.bucketName);
110+
// Expect no truncation from above, checking no error occurred.
111+
int req = bson_snprintf (buf, sizeof (buf), "%s.chunks", gridfs_opts.bucketName);
112+
BSON_ASSERT (req > 0);
110113
bucket->chunks = mongoc_database_get_collection (db, buf);
111114

112-
bson_snprintf (buf, sizeof (buf), "%s.files", gridfs_opts.bucketName);
115+
req = bson_snprintf (buf, sizeof (buf), "%s.files", gridfs_opts.bucketName);
116+
BSON_ASSERT (req > 0);
113117
bucket->files = mongoc_database_get_collection (db, buf);
114118

115119
if (gridfs_opts.writeConcern) {

src/libmongoc/src/mongoc/mongoc-gridfs.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,13 @@ _mongoc_gridfs_new (mongoc_client_t *client, const char *db, const char *prefix,
116116

117117
gridfs->client = client;
118118

119-
bson_snprintf (buf, sizeof (buf), "%s.chunks", prefix);
119+
// Expect no truncation from above, checking no error occurred.
120+
int req = bson_snprintf (buf, sizeof (buf), "%s.chunks", prefix);
121+
BSON_ASSERT (req > 0);
120122
gridfs->chunks = mongoc_client_get_collection (client, db, buf);
121123

122-
bson_snprintf (buf, sizeof (buf), "%s.files", prefix);
124+
req = bson_snprintf (buf, sizeof (buf), "%s.files", prefix);
125+
BSON_ASSERT (req > 0);
123126
gridfs->files = mongoc_client_get_collection (client, db, buf);
124127

125128
r = _mongoc_gridfs_ensure_index (gridfs, error);

src/libmongoc/src/mongoc/mongoc-handshake.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,10 @@ _get_os_version (void)
301301
#endif
302302

303303
if (res) {
304-
bson_snprintf (
304+
// Truncation is OK.
305+
int req = bson_snprintf (
305306
ret, HANDSHAKE_OS_VERSION_MAX, "%lu.%lu (%lu)", osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber);
307+
BSON_ASSERT (req > 0);
306308
found = true;
307309
} else {
308310
MONGOC_WARNING ("Error with GetVersionEx(): %lu", GetLastError ());

src/libmongoc/src/mongoc/mongoc-host-list-private.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424

2525
BSON_BEGIN_DECLS
2626

27-
mongoc_host_list_t *
28-
_mongoc_host_list_push (const char *host, uint16_t port, int family, mongoc_host_list_t *next);
29-
3027
void
3128
_mongoc_host_list_upsert (mongoc_host_list_t **list, const mongoc_host_list_t *new_host);
3229

src/libmongoc/src/mongoc/mongoc-host-list.c

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -21,36 +21,6 @@
2121
#include "mongoc-util-private.h"
2222
#include "utlist.h"
2323

24-
/*
25-
*--------------------------------------------------------------------------
26-
*
27-
* _mongoc_host_list_push --
28-
*
29-
* Add a host to the front of the list and return it.
30-
*
31-
* Side effects:
32-
* None.
33-
*
34-
*--------------------------------------------------------------------------
35-
*/
36-
mongoc_host_list_t *
37-
_mongoc_host_list_push (const char *host, uint16_t port, int family, mongoc_host_list_t *next)
38-
{
39-
mongoc_host_list_t *h;
40-
41-
BSON_ASSERT (host);
42-
43-
h = bson_malloc0 (sizeof (mongoc_host_list_t));
44-
bson_strncpy (h->host, host, sizeof h->host);
45-
h->port = port;
46-
bson_snprintf (h->host_and_port, sizeof h->host_and_port, "%s:%hu", host, port);
47-
48-
h->family = family;
49-
h->next = next;
50-
51-
return h;
52-
}
53-
5424
static mongoc_host_list_t *
5525
_mongoc_host_list_find_host_and_port (mongoc_host_list_t *hosts, const char *host_and_port)
5626
{

src/libmongoc/src/mongoc/mongoc-read-prefs.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ mongoc_read_prefs_add_tag (mongoc_read_prefs_t *read_prefs, const bson_t *tag)
8585
BSON_ASSERT (read_prefs);
8686

8787
key = bson_count_keys (&read_prefs->tags);
88-
bson_snprintf (str, sizeof str, "%d", key);
88+
// Expect no truncation.
89+
int req = bson_snprintf (str, sizeof str, "%d", key);
90+
BSON_ASSERT (bson_cmp_less_su (req, sizeof str));
8991

9092
if (tag) {
9193
bson_append_document (&read_prefs->tags, str, -1, tag);

src/libmongoc/src/mongoc/mongoc-sasl.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,9 @@ _mongoc_sasl_get_canonicalized_name (mongoc_stream_t *node_stream, /* IN */
165165
if (sock) {
166166
canonicalized = mongoc_socket_getnameinfo (sock);
167167
if (canonicalized) {
168-
bson_snprintf (name, namelen, "%s", canonicalized);
168+
// Truncation is OK.
169+
int req = bson_snprintf (name, namelen, "%s", canonicalized);
170+
BSON_ASSERT (req > 0);
169171
bson_free (canonicalized);
170172
RETURN (true);
171173
}

src/libmongoc/src/mongoc/mongoc-socket.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1516,20 +1516,27 @@ mongoc_socket_inet_ntop (struct addrinfo *rp, /* IN */
15161516
{
15171517
void *ptr;
15181518
char tmp[256];
1519+
int req;
15191520

15201521
switch (rp->ai_family) {
15211522
case AF_INET:
15221523
ptr = &((struct sockaddr_in *) rp->ai_addr)->sin_addr;
15231524
inet_ntop (rp->ai_family, ptr, tmp, sizeof (tmp));
1524-
bson_snprintf (buf, buflen, "ipv4 %s", tmp);
1525+
// Truncation is OK.
1526+
req = bson_snprintf (buf, buflen, "ipv4 %s", tmp);
1527+
BSON_ASSERT (req > 0);
15251528
break;
15261529
case AF_INET6:
15271530
ptr = &((struct sockaddr_in6 *) rp->ai_addr)->sin6_addr;
15281531
inet_ntop (rp->ai_family, ptr, tmp, sizeof (tmp));
1529-
bson_snprintf (buf, buflen, "ipv6 %s", tmp);
1532+
// Truncation is OK.
1533+
req = bson_snprintf (buf, buflen, "ipv6 %s", tmp);
1534+
BSON_ASSERT (req > 0);
15301535
break;
15311536
default:
1532-
bson_snprintf (buf, buflen, "unknown ip %d", rp->ai_family);
1537+
// Truncation is OK.
1538+
req = bson_snprintf (buf, buflen, "unknown ip %d", rp->ai_family);
1539+
BSON_ASSERT (req > 0);
15331540
break;
15341541
}
15351542
}

src/libmongoc/src/mongoc/mongoc-topology-scanner.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,9 @@ mongoc_topology_scanner_node_setup_tcp (mongoc_topology_scanner_node_t *node, bs
850850
}
851851

852852
if (!node->dns_results) {
853-
bson_snprintf (portstr, sizeof portstr, "%hu", host->port);
853+
// Expect no truncation.
854+
int req = bson_snprintf (portstr, sizeof portstr, "%hu", host->port);
855+
BSON_ASSERT (bson_cmp_less_su (req, sizeof portstr));
854856

855857
memset (&hints, 0, sizeof hints);
856858
hints.ai_family = host->family;
@@ -910,7 +912,13 @@ mongoc_topology_scanner_node_connect_unix (mongoc_topology_scanner_node_t *node,
910912

911913
memset (&saddr, 0, sizeof saddr);
912914
saddr.sun_family = AF_UNIX;
913-
bson_snprintf (saddr.sun_path, sizeof saddr.sun_path - 1, "%s", host->host);
915+
// Expect no truncation.
916+
int req = bson_snprintf (saddr.sun_path, sizeof saddr.sun_path - 1, "%s", host->host);
917+
918+
if (bson_cmp_greater_equal_su (req, sizeof saddr.sun_path - 1)) {
919+
bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failed to define socket address path.");
920+
RETURN (false);
921+
}
914922

915923
sock = mongoc_socket_new (AF_UNIX, SOCK_STREAM, 0);
916924

src/libmongoc/src/mongoc/mongoc-util.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ _mongoc_hex_md5 (const char *input)
7474
mcommon_md5_finish (&md5, digest);
7575

7676
for (i = 0; i < sizeof digest; i++) {
77-
bson_snprintf (&digest_str[i * 2], 3, "%02x", digest[i]);
77+
// Expect no truncation.
78+
int req = bson_snprintf (&digest_str[i * 2], 3, "%02x", digest[i]);
79+
BSON_ASSERT (req < 3);
7880
}
7981
digest_str[sizeof digest_str - 1] = '\0';
8082

@@ -1008,7 +1010,9 @@ bin_to_hex (const uint8_t *bin, uint32_t len)
10081010
char *out = bson_malloc0 (2u * len + 1u);
10091011

10101012
for (uint32_t i = 0u; i < len; i++) {
1011-
bson_snprintf (out + (2u * i), 3, "%02x", bin[i]);
1013+
// Expect no truncation.
1014+
int req = bson_snprintf (out + (2u * i), 3, "%02x", bin[i]);
1015+
BSON_ASSERT (req < 3);
10121016
}
10131017

10141018
return out;

src/libmongoc/tests/test-mongoc-dns.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,36 @@ typedef struct {
7474
} context_t;
7575

7676

77+
/*
78+
*--------------------------------------------------------------------------
79+
*
80+
* _mongoc_host_list_push --
81+
*
82+
* Add a host to the front of the list and return it.
83+
*
84+
* Side effects:
85+
* None.
86+
*
87+
*--------------------------------------------------------------------------
88+
*/
89+
static mongoc_host_list_t *
90+
_mongoc_host_list_push (const char *host, uint16_t port, int family, mongoc_host_list_t *next)
91+
{
92+
mongoc_host_list_t *h;
93+
94+
BSON_ASSERT (host);
95+
96+
h = bson_malloc0 (sizeof (mongoc_host_list_t));
97+
bson_strncpy (h->host, host, sizeof h->host);
98+
h->port = port;
99+
bson_snprintf (h->host_and_port, sizeof h->host_and_port, "%s:%hu", host, port);
100+
101+
h->family = family;
102+
h->next = next;
103+
104+
return h;
105+
}
106+
77107
static void
78108
topology_changed (const mongoc_apm_topology_changed_t *event)
79109
{

src/libmongoc/tests/test-mongoc-gridfs-bucket.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,8 +1035,8 @@ test_gridfs_bucket_opts (void)
10351035
bson_destroy (opts);
10361036
mongoc_gridfs_bucket_destroy (gridfs);
10371037

1038-
/* one character shorter should be okay though. */
1039-
*(bucket_name + ((int) (128 - strlen ("chunks") - 1))) = '\0';
1038+
/* two characters shorter should be okay though. */
1039+
*(bucket_name + ((int) (128 - strlen ("chunks") - 2))) = '\0';
10401040
opts = BCON_NEW ("bucketName", bucket_name);
10411041
gridfs = mongoc_gridfs_bucket_new (db, opts, NULL, &error);
10421042
ASSERT_OR_PRINT (gridfs, error);

0 commit comments

Comments
 (0)