Reproducer:
// Hidden: requires ~2 GiB of memory. TEST_CASE("SECBUG-4104: oversized key length", "[.][secbug_4104]") { // `core::append` casts the key length to `std::int32_t`. 2^31 truncates to INT32_MIN, and libbson treats a // negative key length as a request to `strlen` the key, which is not NUL-terminated here. The embedded NUL check // in `BSON_APPEND_BYTES_ADD_CHECKED_STRING` is in the non-negative branch only, so it is skipped. constexpr std::size_t size = std::size_t{1} << 31; REQUIRE(static_cast<std::int32_t>(size) < 0); auto buf = std::unique_ptr<char[]>{new char[size]}; std::memset(buf.get(), 'a', size); stdx::string_view const key{buf.get(), size}; REQUIRE(key.size() == size); // Currently a heap-buffer-overflow read of `strlen` past the end of `buf` (observable under ASAN). bsoncxx::builder::basic::document doc; CHECK_THROWS_AS(doc.append(bsoncxx::builder::basic::kvp(key, 1.0)), bsoncxx::exception); }