MMDB_get_entry_data_list() now validates that the claimed array/map size is
plausible given the remaining bytes in the data section. A crafted database
could previously claim millions of array elements while only having a few
bytes of data, causing disproportionate memory allocation (memory
amplification DoS).MMDB_read_node() and find_ipv4_start_node()
pointer arithmetic. The node_number * record_length multiplication was
performed in uint32_t, which could overflow for very large databases. Now
cast to uint64_t before multiplying, matching the pattern already used in
find_address_in_search_tree().mmdblookup's metadata dump. %i
was used for unsigned types and %llu for uint64_t, which is technically
undefined behavior. Now uses the portable PRIu32, PRIu16, and PRIu64
macros from <inttypes.h>.find_address_in_search_tree(). The addition of node_count and
data_section_size was performed in uint32_t arithmetic, which could wrap
on very large databases, causing valid lookups to be incorrectly rejected as
corrupt.mmdblookup when displaying metadata for
a database with an out-of-range build_epoch. The gmtime() return value is
now checked before passing to strftime().MMDB_close() now NULLs the file_content, data_section, and
metadata_section pointers and zeroes file_size, data_section_size, and
metadata_section_size after unmapping. Previously, calling MMDB_close()
twice on the same struct (or calling it after a failed MMDB_open() that
succeeded at mapping) would double-munmap the file content, which is undefined
behavior.print_indentation() when...1.13.1-1.fc431.13.1-1.fc431.13.1-1.fc431.13.1-1.fc43