Skip to content

Commit 5c48b5f

Browse files
committed
MONGOCRYPT-794 fix possible double free on parse error (#988)
* test and fix `mc_FLE2FindEqualityPayloadV2_t` * fix unused `mc_FLE2FindEqualityPayload_t` Payload is unused but still fixed. The `mc_FLE2FindEqualityPayload_t` may be safe to remove * test and fix `mc_FLE2EncryptionPlaceholder_t` * test and fix `mc_FLE2InsertUpdatePayloadV2_t` * test and fix `mc_FLE2InsertUpdatePayload_t`
1 parent 677d0d9 commit 5c48b5f

9 files changed

+87
-7
lines changed

src/mc-fle2-encryption-placeholder.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,6 @@ bool mc_FLE2EncryptionPlaceholder_parse(mc_FLE2EncryptionPlaceholder_t *out,
179179
return true;
180180

181181
fail:
182-
mc_FLE2EncryptionPlaceholder_cleanup(out);
183182
return false;
184183
}
185184

src/mc-fle2-find-equality-payload-v2.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ bool mc_FLE2FindEqualityPayloadV2_parse(mc_FLE2FindEqualityPayloadV2_t *out,
111111

112112
return true;
113113
fail:
114-
mc_FLE2FindEqualityPayloadV2_cleanup(out);
115114
return false;
116115
}
117116

src/mc-fle2-find-equality-payload.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ bool mc_FLE2FindEqualityPayload_parse(mc_FLE2FindEqualityPayload_t *out,
114114

115115
return true;
116116
fail:
117-
mc_FLE2FindEqualityPayload_cleanup(out);
118117
return false;
119118
}
120119

src/mc-fle2-insert-update-payload-v2.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,6 @@ bool mc_FLE2InsertUpdatePayloadV2_parse(mc_FLE2InsertUpdatePayloadV2_t *out,
300300

301301
return true;
302302
fail:
303-
mc_FLE2InsertUpdatePayloadV2_cleanup(out);
304303
return false;
305304
}
306305

src/mc-fle2-insert-update-payload.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,6 @@ bool mc_FLE2InsertUpdatePayload_parse(mc_FLE2InsertUpdatePayload_t *out,
167167

168168
return true;
169169
fail:
170-
mc_FLE2InsertUpdatePayload_cleanup(out);
171170
return false;
172171
}
173172

test/test-mc-fle2-encryption-placeholder.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,8 +440,29 @@ static void _test_FLE2EncryptionPlaceholder_textSearch_parse(_mongocrypt_tester_
440440
}
441441
}
442442

443+
static void _test_FLE2EncryptionPlaceholder_parse_errors(_mongocrypt_tester_t *tester) {
444+
bson_t *input_bson = TMP_BSON(BSON_STR({
445+
"t" : {"$numberInt" : "1"},
446+
"a" : {"$numberInt" : "1"},
447+
"ki" : {"$binary" : {"base64" : "EjRWeBI0mHYSNBI0VniQEg==", "subType" : "04"}},
448+
"ku" : {"$binary" : {"base64" : "q83vqxI0mHYSNBI0VniQEg==", "subType" : "04"}},
449+
"v" : "foobar",
450+
"cm" : "wrong type!"
451+
}));
452+
453+
mc_FLE2EncryptionPlaceholder_t payload;
454+
mc_FLE2EncryptionPlaceholder_init(&payload);
455+
mongocrypt_status_t *status = mongocrypt_status_new();
456+
ASSERT_FAILS_STATUS(mc_FLE2EncryptionPlaceholder_parse(&payload, input_bson, status),
457+
status,
458+
"'cm' must be an int64");
459+
mc_FLE2EncryptionPlaceholder_cleanup(&payload);
460+
mongocrypt_status_destroy(status);
461+
}
462+
443463
void _mongocrypt_tester_install_fle2_encryption_placeholder(_mongocrypt_tester_t *tester) {
444464
INSTALL_TEST(_test_FLE2EncryptionPlaceholder_parse);
445465
INSTALL_TEST(_test_FLE2EncryptionPlaceholder_range_parse);
446466
INSTALL_TEST(_test_FLE2EncryptionPlaceholder_textSearch_parse);
447-
}
467+
INSTALL_TEST(_test_FLE2EncryptionPlaceholder_parse_errors);
468+
}

test/test-mc-fle2-find-equality-payload-v2.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,25 @@ static void _test_FLE2FindEqualityPayloadV2_roundtrip(_mongocrypt_tester_t *test
7373

7474
#undef TEST_FIND_EQ_PAYLOAD_HEX_V2
7575

76+
static void _test_FLE2FindEqualityPayloadV2_errors(_mongocrypt_tester_t *tester) {
77+
bson_t *input_bson = TMP_BSON(BSON_STR({
78+
"d" : {"$binary" : {"base64" : "AAAA", "subType" : "00"}},
79+
"s" : {"$binary" : {"base64" : "AAAA", "subType" : "00"}},
80+
"l" : {"$binary" : {"base64" : "AAAA", "subType" : "00"}},
81+
"cm" : "wrong type!"
82+
}));
83+
84+
mc_FLE2FindEqualityPayloadV2_t payload;
85+
mc_FLE2FindEqualityPayloadV2_init(&payload);
86+
mongocrypt_status_t *status = mongocrypt_status_new();
87+
ASSERT_FAILS_STATUS(mc_FLE2FindEqualityPayloadV2_parse(&payload, input_bson, status),
88+
status,
89+
"Field 'cm' expected to hold an int64");
90+
mc_FLE2FindEqualityPayloadV2_cleanup(&payload);
91+
mongocrypt_status_destroy(status);
92+
}
93+
7694
void _mongocrypt_tester_install_fle2_payload_find_equality_v2(_mongocrypt_tester_t *tester) {
7795
INSTALL_TEST(_test_FLE2FindEqualityPayloadV2_roundtrip);
78-
}
96+
INSTALL_TEST(_test_FLE2FindEqualityPayloadV2_errors);
97+
}

test/test-mc-fle2-payload-iup-v2.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,31 @@ static void _test_mc_FLE2InsertUpdatePayloadV2_parses_crypto_params(_mongocrypt_
242242
mc_FLE2InsertUpdatePayloadV2_cleanup(&got);
243243
}
244244

245+
static void _test_mc_FLE2InsertUpdatePayloadV2_parse_errors(_mongocrypt_tester_t *tester) {
246+
bson_t *input_bson = TMP_BSON(BSON_STR({
247+
"d" : {"$binary" : {"base64" : "AAAA", "subType" : "00"}}, //
248+
"t" : "wrong type!"
249+
}));
250+
_mongocrypt_buffer_t input_buf;
251+
_mongocrypt_buffer_init_size(&input_buf, 1 + input_bson->len);
252+
input_buf.data[0] = (uint8_t)MC_SUBTYPE_FLE2InsertUpdatePayloadV2;
253+
memcpy(input_buf.data + 1, bson_get_data(input_bson), input_bson->len);
254+
255+
mc_FLE2InsertUpdatePayloadV2_t payload;
256+
mc_FLE2InsertUpdatePayloadV2_init(&payload);
257+
mongocrypt_status_t *status = mongocrypt_status_new();
258+
ASSERT_FAILS_STATUS(mc_FLE2InsertUpdatePayloadV2_parse(&payload, &input_buf, status),
259+
status,
260+
"Field 't' expected to hold an int32");
261+
mc_FLE2InsertUpdatePayloadV2_cleanup(&payload);
262+
mongocrypt_status_destroy(status);
263+
_mongocrypt_buffer_cleanup(&input_buf);
264+
}
265+
245266
void _mongocrypt_tester_install_fle2_payload_iup_v2(_mongocrypt_tester_t *tester) {
246267
INSTALL_TEST(_test_FLE2InsertUpdatePayloadV2_parse);
247268
INSTALL_TEST(_test_mc_FLE2InsertUpdatePayloadV2_decrypt);
248269
INSTALL_TEST(_test_mc_FLE2InsertUpdatePayloadV2_includes_crypto_params);
249270
INSTALL_TEST(_test_mc_FLE2InsertUpdatePayloadV2_parses_crypto_params);
271+
INSTALL_TEST(_test_mc_FLE2InsertUpdatePayloadV2_parse_errors);
250272
}

test/test-mc-fle2-payload-iup.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17+
#include "mc-fle-blob-subtype-private.h"
1718
#include "mc-fle2-insert-update-payload-private.h"
1819
#include "test-mongocrypt.h"
1920

@@ -160,7 +161,29 @@ static void test_FLE2InsertUpdatePayload_decrypt(_mongocrypt_tester_t *tester) {
160161

161162
#undef TEST_IUP_HEX
162163

164+
static void test_FLE2InsertUpdatePayload_parse_errors(_mongocrypt_tester_t *tester) {
165+
bson_t *input_bson = TMP_BSON(BSON_STR({
166+
"d" : {"$binary" : {"base64" : "AAAA", "subType" : "00"}}, //
167+
"t" : "wrong type!"
168+
}));
169+
_mongocrypt_buffer_t input_buf;
170+
_mongocrypt_buffer_init_size(&input_buf, 1 + input_bson->len);
171+
input_buf.data[0] = (uint8_t)MC_SUBTYPE_FLE2InsertUpdatePayload;
172+
memcpy(input_buf.data + 1, bson_get_data(input_bson), input_bson->len);
173+
174+
mc_FLE2InsertUpdatePayload_t payload;
175+
mc_FLE2InsertUpdatePayload_init(&payload);
176+
mongocrypt_status_t *status = mongocrypt_status_new();
177+
ASSERT_FAILS_STATUS(mc_FLE2InsertUpdatePayload_parse(&payload, &input_buf, status),
178+
status,
179+
"Field 't' expected to hold an int32");
180+
mc_FLE2InsertUpdatePayload_cleanup(&payload);
181+
mongocrypt_status_destroy(status);
182+
_mongocrypt_buffer_cleanup(&input_buf);
183+
}
184+
163185
void _mongocrypt_tester_install_fle2_payload_iup(_mongocrypt_tester_t *tester) {
164186
INSTALL_TEST(test_FLE2InsertUpdatePayload_parse);
165187
INSTALL_TEST(test_FLE2InsertUpdatePayload_decrypt);
188+
INSTALL_TEST(test_FLE2InsertUpdatePayload_parse_errors);
166189
}

0 commit comments

Comments
 (0)