Skip to content

Commit eba8bb7

Browse files
committed
Reject empty metadata sections
1 parent 712cd42 commit eba8bb7

6 files changed

Lines changed: 40 additions & 3 deletions

File tree

Changes.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
`sockaddr` with an unsupported address family. The function now rejects any
55
family other than `AF_INET` and `AF_INET6` with
66
`MMDB_INVALID_NETWORK_ADDRESS_ERROR`.
7+
- Fixed metadata parsing for files that end immediately after the
8+
`\xAB\xCD\xEFMaxMind.com` marker. Such files are now rejected as invalid
9+
metadata instead of allowing a zero-length metadata section to reach the
10+
decoder.
711

812
## 1.13.3 - 2026-03-05
913

src/maxminddb.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ static const uint8_t *find_metadata(const uint8_t *file_content,
518518
}
519519
} while (NULL != tmp);
520520

521-
if (search_area == start) {
521+
if (search_area == start || max_size <= 0) {
522522
return NULL;
523523
}
524524

@@ -1431,6 +1431,13 @@ static int decode_one(const MMDB_s *const mmdb,
14311431
MMDB_entry_data_s *entry_data) {
14321432
const uint8_t *mem = mmdb->data_section;
14331433

1434+
if (mmdb->data_section_size == 0) {
1435+
// decode_one is also called with a fake mmdb whose data_section
1436+
// points at the metadata; either way an empty section is invalid.
1437+
DEBUG_MSG("decode_one called with an empty section");
1438+
return MMDB_INVALID_DATA_ERROR;
1439+
}
1440+
14341441
// We subtract rather than add as it possible that offset + 1
14351442
// could overflow for a corrupt database while an underflow
14361443
// from data_section_size - 1 should not be possible.

t/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ set(TEST_TARGET_NAMES
1717
get_value_t
1818
ipv4_start_cache_t
1919
ipv6_lookup_in_ipv4_t
20+
metadata_marker_t
2021
metadata_pointers_t
2122
metadata_t
2223
no_map_get_value_t

t/Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ check_PROGRAMS = \
2323
gai_error_t get_value_t \
2424
get_value_pointer_bug_t invalid_sockaddr_t \
2525
ipv4_start_cache_t ipv6_lookup_in_ipv4_t max_depth_t metadata_t \
26-
metadata_pointers_t no_map_get_value_t overflow_bounds_t read_node_t \
26+
metadata_marker_t metadata_pointers_t no_map_get_value_t \
27+
overflow_bounds_t read_node_t \
2728
threads_t version_t
2829

2930
data_pool_t_LDFLAGS = $(AM_LDFLAGS) -lm

t/metadata_marker_t.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include "maxminddb_test_helper.h"
2+
3+
static void test_trailing_metadata_marker(void) {
4+
char *db_file =
5+
bad_database_path("libmaxminddb-metadata-marker-only.mmdb");
6+
MMDB_s mmdb;
7+
int status = MMDB_open(db_file, MMDB_MODE_MMAP, &mmdb);
8+
cmp_ok(status,
9+
"==",
10+
MMDB_INVALID_METADATA_ERROR,
11+
"MMDB_open rejects a file containing only the metadata marker");
12+
13+
if (status == MMDB_SUCCESS) {
14+
MMDB_close(&mmdb);
15+
}
16+
17+
free(db_file);
18+
}
19+
20+
int main(void) {
21+
plan(NO_PLAN);
22+
test_trailing_metadata_marker();
23+
done_testing();
24+
}

0 commit comments

Comments
 (0)