Skip to content

Commit

Permalink
Merge pull request #98 from maxmind/greg/fix-memory-corruption
Browse files Browse the repository at this point in the history
Fix possible memory corruption with getWithPrefixLen
  • Loading branch information
horgh authored Dec 19, 2019
2 parents f096bbe + 2824e6d commit 66b3351
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 15 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
CHANGELOG
=========

1.6.0
------------------

* 1.5.0 and 1.5.1 contained a possible memory corruptions when using
`getWithPrefixLen`. This has been fixed. Reported by proton-ab.
GitHub #96.
* The `composer.json` file now conflicts with all versions of the
`maxminddb` C extension less than the Composer version. This is to
reduce the chance of having an older, conflicting version of the
extension installed. You will need to upgrade the extension before
running `composer update`. Pull request by Benoît Burnichon. GitHub
#97.

1.5.1 (2019-12-12)
------------------

Expand Down
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
"ext-gmp": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder",
"ext-maxminddb": "A C-based database decoder that provides significantly faster lookups"
},
"conflict": {
"ext-maxminddb": "<1.5.1,>=2.0.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "2.*",
"phpunit/phpunit": "5.*",
Expand Down
14 changes: 11 additions & 3 deletions dev-bin/release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,19 @@ tag="v$version"
rm -fr vendor

perl -pi -e "s/(?<=#define PHP_MAXMINDDB_VERSION \")\d+\.\d+\.\d+(?=\")/$version/" ext/php_maxminddb.h
perl -pi -e "s/(?<=\"ext-maxminddb\": \"<)\d+.\d+.\d+(?=,)/$version/" composer.json

php composer.phar self-update
php composer.phar update
pushd ext
phpize
./configure
make
popd

./vendor/bin/phpunit
php -n -dextension=ext/modules/maxminddb.so composer.phar self-update
php -n -dextension=ext/modules/maxminddb.so composer.phar update

php -n -dextension=ext/modules/maxminddb.so ./vendor/bin/phpunit
php -n ./vendor/bin/phpunit

echo $'\nDiff:'
git diff
Expand Down
27 changes: 15 additions & 12 deletions ext/maxminddb.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ typedef struct _maxminddb_obj {

PHP_FUNCTION(maxminddb);

static void
static int
get_record(INTERNAL_FUNCTION_PARAMETERS, zval *record, int *prefix_len);
static const MMDB_entry_data_list_s *
handle_entry_data_list(const MMDB_entry_data_list_s *entry_data_list,
Expand Down Expand Up @@ -163,7 +163,7 @@ PHP_METHOD(MaxMind_Db_Reader, __construct) {
return;
}

MMDB_s *mmdb = (MMDB_s *)emalloc(sizeof(MMDB_s));
MMDB_s *mmdb = (MMDB_s *)ecalloc(1, sizeof(MMDB_s));
uint16_t status = MMDB_open(db_file, MMDB_MODE_MMAP, mmdb);

if (MMDB_SUCCESS != status) {
Expand Down Expand Up @@ -200,7 +200,9 @@ PHP_METHOD(MaxMind_Db_Reader, getWithPrefixLen) {
#endif

int prefix_len = 0;
get_record(INTERNAL_FUNCTION_PARAM_PASSTHRU, record, &prefix_len);
if (get_record(INTERNAL_FUNCTION_PARAM_PASSTHRU, record, &prefix_len)) {
return;
}

array_init(return_value);
add_next_index_zval(return_value, record);
Expand All @@ -209,7 +211,7 @@ PHP_METHOD(MaxMind_Db_Reader, getWithPrefixLen) {
add_next_index_zval(return_value, z_prefix_len);
}

static void
static int
get_record(INTERNAL_FUNCTION_PARAMETERS, zval *record, int *prefix_len) {
char *ip_address = NULL;
strsize_t name_len;
Expand All @@ -224,7 +226,7 @@ get_record(INTERNAL_FUNCTION_PARAMETERS, zval *record, int *prefix_len) {
&name_len) == FAILURE) {
THROW_EXCEPTION("InvalidArgumentException",
"Method takes exactly one argument.");
return;
return 1;
}

const maxminddb_obj *mmdb_obj = (maxminddb_obj *)Z_MAXMINDDB_P(getThis());
Expand All @@ -234,7 +236,7 @@ get_record(INTERNAL_FUNCTION_PARAMETERS, zval *record, int *prefix_len) {
if (NULL == mmdb) {
THROW_EXCEPTION("BadMethodCallException",
"Attempt to read from a closed MaxMind DB.");
return;
return 1;
}

struct addrinfo hints = {
Expand All @@ -249,13 +251,13 @@ get_record(INTERNAL_FUNCTION_PARAMETERS, zval *record, int *prefix_len) {
THROW_EXCEPTION("InvalidArgumentException",
"The value \"%s\" is not a valid IP address.",
ip_address);
return;
return 1;
}
if (!addresses || !addresses->ai_addr) {
THROW_EXCEPTION(
"InvalidArgumentException",
"getaddrinfo was successful but failed to set the addrinfo");
return;
return 1;
}

int sa_family = addresses->ai_addr->sa_family;
Expand All @@ -277,7 +279,7 @@ get_record(INTERNAL_FUNCTION_PARAMETERS, zval *record, int *prefix_len) {
"Error looking up %s. %s",
ip_address,
MMDB_strerror(mmdb_error));
return;
return 1;
}

*prefix_len = result.netmask;
Expand All @@ -290,7 +292,7 @@ get_record(INTERNAL_FUNCTION_PARAMETERS, zval *record, int *prefix_len) {

if (!result.found_entry) {
ZVAL_NULL(record);
return;
return 0;
}

MMDB_entry_data_list_s *entry_data_list = NULL;
Expand All @@ -302,17 +304,18 @@ get_record(INTERNAL_FUNCTION_PARAMETERS, zval *record, int *prefix_len) {
ip_address,
MMDB_strerror(status));
MMDB_free_entry_data_list(entry_data_list);
return;
return 1;
} else if (NULL == entry_data_list) {
THROW_EXCEPTION(PHP_MAXMINDDB_READER_EX_NS,
"Error while looking up data for %s. Your database may "
"be corrupt or you have found a bug in libmaxminddb.",
ip_address);
return;
return 1;
}

handle_entry_data_list(entry_data_list, record TSRMLS_CC);
MMDB_free_entry_data_list(entry_data_list);
return 0;
}

ZEND_BEGIN_ARG_INFO_EX(arginfo_maxmindbreader_void, 0, 0, 0)
Expand Down

0 comments on commit 66b3351

Please sign in to comment.