From b642e233a797a85e7f08f44eca5c3e2b5d68d9f1 Mon Sep 17 00:00:00 2001 From: Sandu Liviu Catalin Date: Thu, 25 May 2017 22:56:09 +0300 Subject: [PATCH] Update the MaxmindDB library to the latest version. --- config/gcc32/maxminddb_config.h | 6 ++--- config/gcc64/maxminddb_config.h | 6 ++--- config/mingw32/maxminddb_config.h | 6 ++--- config/mingw64/maxminddb_config.h | 6 ++--- external/MaxmindDB/maxminddb.c | 41 +++++++++++++++++++++++-------- include/maxminddb.h | 2 +- 6 files changed, 44 insertions(+), 23 deletions(-) diff --git a/config/gcc32/maxminddb_config.h b/config/gcc32/maxminddb_config.h index 12e934e9..62d2cb38 100644 --- a/config/gcc32/maxminddb_config.h +++ b/config/gcc32/maxminddb_config.h @@ -112,7 +112,7 @@ #define PACKAGE_NAME "libmaxminddb" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "libmaxminddb 1.2.0" +#define PACKAGE_STRING "libmaxminddb 1.2.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "libmaxminddb" @@ -121,13 +121,13 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.2.0" +#define PACKAGE_VERSION "1.2.1" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ -#define VERSION "1.2.0" +#define VERSION "1.2.1" /* Define for Solaris 2.5.1 so the uint32_t typedef from , , or is not used. If the typedef were allowed, the diff --git a/config/gcc64/maxminddb_config.h b/config/gcc64/maxminddb_config.h index 1f522e90..fd76481b 100644 --- a/config/gcc64/maxminddb_config.h +++ b/config/gcc64/maxminddb_config.h @@ -112,7 +112,7 @@ #define PACKAGE_NAME "libmaxminddb" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "libmaxminddb 1.2.0" +#define PACKAGE_STRING "libmaxminddb 1.2.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "libmaxminddb" @@ -121,13 +121,13 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.2.0" +#define PACKAGE_VERSION "1.2.1" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ -#define VERSION "1.2.0" +#define VERSION "1.2.1" /* Define for Solaris 2.5.1 so the uint32_t typedef from , , or is not used. If the typedef were allowed, the diff --git a/config/mingw32/maxminddb_config.h b/config/mingw32/maxminddb_config.h index 57a644e5..8330403b 100644 --- a/config/mingw32/maxminddb_config.h +++ b/config/mingw32/maxminddb_config.h @@ -110,7 +110,7 @@ #define PACKAGE_NAME "libmaxminddb" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "libmaxminddb 1.2.0" +#define PACKAGE_STRING "libmaxminddb 1.2.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "libmaxminddb" @@ -119,13 +119,13 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.2.0" +#define PACKAGE_VERSION "1.2.1" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ -#define VERSION "1.2.0" +#define VERSION "1.2.1" /* Define for Solaris 2.5.1 so the uint32_t typedef from , , or is not used. If the typedef were allowed, the diff --git a/config/mingw64/maxminddb_config.h b/config/mingw64/maxminddb_config.h index 8971512f..40753cb0 100644 --- a/config/mingw64/maxminddb_config.h +++ b/config/mingw64/maxminddb_config.h @@ -110,7 +110,7 @@ #define PACKAGE_NAME "libmaxminddb" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "libmaxminddb 1.2.0" +#define PACKAGE_STRING "libmaxminddb 1.2.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "libmaxminddb" @@ -119,13 +119,13 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.2.0" +#define PACKAGE_VERSION "1.2.1" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ -#define VERSION "1.2.0" +#define VERSION "1.2.1" /* Define for Solaris 2.5.1 so the uint32_t typedef from , , or is not used. If the typedef were allowed, the diff --git a/external/MaxmindDB/maxminddb.c b/external/MaxmindDB/maxminddb.c index a7780c89..8dbe4a74 100644 --- a/external/MaxmindDB/maxminddb.c +++ b/external/MaxmindDB/maxminddb.c @@ -283,6 +283,16 @@ int MMDB_open(const char *const filename, uint32_t flags, MMDB_s *const mmdb) } mmdb->data_section_size = (uint32_t)mmdb->file_size - search_tree_size - MMDB_DATA_SECTION_SEPARATOR; + + // Although it is likely not possible to construct a database with valid + // valid metadata, as parsed above, and a data_section_size less than 3, + // we do this check as later we assume it is at least three when doing + // bound checks. + if (mmdb->data_section_size < 3) { + status = MMDB_INVALID_DATA_ERROR; + goto cleanup; + } + mmdb->metadata_section = metadata; mmdb->ipv4_start_node.node_value = 0; mmdb->ipv4_start_node.netmask = 0; @@ -1384,7 +1394,10 @@ LOCAL int decode_one(MMDB_s *mmdb, uint32_t offset, { const uint8_t *mem = mmdb->data_section; - if (offset + 1 > mmdb->data_section_size) { + // We subtract rather than add as it possible that offset + 1 + // could overflow for a corrupt database while an underflow + // from data_section_size - 1 should not be possible. + if (offset > mmdb->data_section_size - 1) { DEBUG_MSGF("Offset (%d) past data section (%d)", offset, mmdb->data_section_size); return MMDB_INVALID_DATA_ERROR; @@ -1403,7 +1416,8 @@ LOCAL int decode_one(MMDB_s *mmdb, uint32_t offset, DEBUG_MSGF("Type: %i (%s)", type, type_num_to_name(type)); if (type == MMDB_DATA_TYPE_EXTENDED) { - if (offset + 1 > mmdb->data_section_size) { + // Subtracting 1 to avoid possible overflow on offset + 1 + if (offset > mmdb->data_section_size - 1) { DEBUG_MSGF("Extended type offset (%d) past data section (%d)", offset, mmdb->data_section_size); @@ -1416,10 +1430,13 @@ LOCAL int decode_one(MMDB_s *mmdb, uint32_t offset, entry_data->type = type; if (type == MMDB_DATA_TYPE_POINTER) { - int psize = ((ctrl >> 3) & 3) + 1; + uint8_t psize = ((ctrl >> 3) & 3) + 1; DEBUG_MSGF("Pointer size: %i", psize); - if (offset + psize > mmdb->data_section_size) { + // We check that the offset does not extend past the end of the + // database and that the subtraction of psize did not underflow. + if (offset > mmdb->data_section_size - psize || + mmdb->data_section_size < psize) { DEBUG_MSGF("Pointer offset (%d) past data section (%d)", offset + psize, mmdb->data_section_size); @@ -1436,7 +1453,8 @@ LOCAL int decode_one(MMDB_s *mmdb, uint32_t offset, uint32_t size = ctrl & 31; switch (size) { case 29: - if (offset + 1 > mmdb->data_section_size) { + // We subtract when checking offset to avoid possible overflow + if (offset > mmdb->data_section_size - 1) { DEBUG_MSGF("String end (%d, case 29) past data section (%d)", offset, mmdb->data_section_size); @@ -1445,7 +1463,8 @@ LOCAL int decode_one(MMDB_s *mmdb, uint32_t offset, size = 29 + mem[offset++]; break; case 30: - if (offset + 2 > mmdb->data_section_size) { + // We subtract when checking offset to avoid possible overflow + if (offset > mmdb->data_section_size - 2) { DEBUG_MSGF("String end (%d, case 30) past data section (%d)", offset, mmdb->data_section_size); @@ -1455,7 +1474,8 @@ LOCAL int decode_one(MMDB_s *mmdb, uint32_t offset, offset += 2; break; case 31: - if (offset + 3 > mmdb->data_section_size) { + // We subtract when checking offset to avoid possible overflow + if (offset > mmdb->data_section_size - 3) { DEBUG_MSGF("String end (%d, case 31) past data section (%d)", offset, mmdb->data_section_size); @@ -1483,9 +1503,10 @@ LOCAL int decode_one(MMDB_s *mmdb, uint32_t offset, return MMDB_SUCCESS; } - // check that the data doesn't extend past the end of the memory - // buffer - if (offset + size > mmdb->data_section_size) { + // Check that the data doesn't extend past the end of the memory + // buffer and that the calculation in doing this did not underflow. + if (offset > mmdb->data_section_size - size || + mmdb->data_section_size < size) { DEBUG_MSGF("Data end (%d) past data section (%d)", offset + size, mmdb->data_section_size); return MMDB_INVALID_DATA_ERROR; diff --git a/include/maxminddb.h b/include/maxminddb.h index 2aaa4634..a6f0e93c 100644 --- a/include/maxminddb.h +++ b/include/maxminddb.h @@ -20,7 +20,7 @@ extern "C" { #include #include /* libmaxminddb package version from configure */ -#define PACKAGE_VERSION "1.2.0" +#define PACKAGE_VERSION "1.2.1" typedef ADDRESS_FAMILY sa_family_t;