Squashed 'src/deps/src/libmaxminddb/' changes from 24df335085..0ff5a5bfb3

0ff5a5bfb3 Bumped version to 1.12.1
97c286380f Include cmake_uninstall.cmake.in in dist
a2894be9d2 Bumped version to 1.12.0
d29b1fe01e Update copyright years
9122681c69 Set release date
36e7226b11 Merge pull request #364 from maxmind/greg/changelog
6b7404117a Add Changes.md entry for #362
98bde9e8b0 Merge pull request #362 from gmou3/main
39336f099e Merge pull request #361 from maxmind/greg/core-only-man-page-generation
20cc7ad7fa Include status code rather than errno for system calls
cbe22dc4f9 Add more error checking
92a04003de Add CMake uninstall target
a09fa4b22e Do not depend on non-core Perl modules
fff8dae215 Merge pull request #360 from maxmind/greg/fix-warnings
3a0ab7edef Do not use autodie in script
cbcec4fc83 Set cmake_minimum_required version range
cab57f3598 Merge pull request #358 from maxmind/horgh/changelog
80aebfa7b6 Add changelog entries for #356 and #357
70abedbefe Merge pull request #356 from pkillarjun/memory-leak
d308c75c0a Merge pull request #357 from pkillarjun/fuzzing
69af4e01a5 Fix: double free in bad_pointers_t
77e547eba2 fix: memory leak in MMDB_open()
82be59cff6 Add: fuzz_mmdb to support OSS-Fuzz
51347129b3 add: build directory in .gitignore
0fd88980ce Merge pull request #355 from maxmind/greg/1.11.0

git-subtree-dir: src/deps/src/libmaxminddb
git-subtree-split: 0ff5a5bfb3bc8f7da1e1d1a7c3398b9d3fcf7493
This commit is contained in:
Théophile Diot 2025-01-09 16:31:04 +01:00
parent d4b681bb5a
commit f8452b8f50
17 changed files with 238 additions and 48 deletions

View file

@ -34,7 +34,7 @@ jobs:
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
- run: sudo apt install libipc-run3-perl libipc-system-simple-perl libfile-slurp-perl libfile-which-perl pandoc
- run: sudo apt install libipc-run3-perl pandoc
- run: |
./bootstrap
./configure

1
.gitignore vendored
View file

@ -44,3 +44,4 @@ Makefile
Makefile.in
Testing/
install_manifest.txt
build/

View file

@ -1,8 +1,8 @@
cmake_minimum_required (VERSION 3.9)
cmake_minimum_required (VERSION 3.9...3.30)
project(maxminddb
LANGUAGES C
VERSION 1.11.0
VERSION 1.12.1
)
set(MAXMINDDB_SOVERSION 0.0.7)
set(CMAKE_C_STANDARD 99)
@ -13,6 +13,7 @@ if (WIN32)
endif()
option(BUILD_SHARED_LIBS "Build shared libraries (.dll/.so) instead of static ones (.lib/.a)" OFF)
option(BUILD_TESTING "Build test programs" ON)
option(BUILD_FUZZING "Build with fuzzer" OFF)
option(MAXMINDDB_BUILD_BINARIES "Build binaries" ON)
option(MAXMINDDB_INSTALL "Generate the install target" ON)
@ -154,3 +155,14 @@ if (MAXMINDDB_INSTALL)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/src/libmaxminddb.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
endif()
# uninstall target
if(NOT TARGET uninstall)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif()

View file

@ -1,3 +1,26 @@
## 1.12.1 - 2025-01-08
* Added missing `cmake_uninstall.cmake.in` to the source distribution. This
was missing from 1.12.0, causing CMake builds to fail. Reported by Marcel
Raad. GitHub #367.
## 1.12.0 - 2025-01-07
* Fixed memory leaks in `MMDB_open()`. These could happen with invalid
databases or in error situations such as failing to allocate memory. As
part of the fix, `MMDB_get_entry_data_list()` now frees memory it
allocates on additional errors. Previously it failed to clean up when
certain errors occurred. Pull request by pkillarjun. GitHub #356.
* There is now a build target to fuzz the library. Pull request by
pkillarjun. GitHub #357.
* Updated `cmake_minimum_required` to a version range to quiet deprecation
warnings on new CMake versions. Reported by gmou3. GitHub #359.
* The script for generating man pages no longer uses `autodie`. This
eliminates the dependency on `IPC::System::Simple`. Reported by gmou3.
GitHub #359.
* An uninstall target is now included for CMake. Pull request by gmou3.
GitHub #362.
## 1.11.0 - 2024-08-21
* When building with CMake, the man pages will now be generated and

View file

@ -18,7 +18,7 @@ endif
EXTRA_DIST = doc Changes.md LICENSE NOTICE README.md \
CMakeLists.txt t/CMakeLists.txt bin/CMakeLists.txt \
include/maxminddb_config.h.cmake.in
cmake_uninstall.cmake.in include/maxminddb_config.h.cmake.in
dist-hook:
dev-bin/make-man-pages.pl $(distdir)

2
NOTICE
View file

@ -1,4 +1,4 @@
Copyright 2013-2024 MaxMind, Inc.
Copyright 2013-2025 MaxMind, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

41
README.fuzzing.md Normal file
View file

@ -0,0 +1,41 @@
# Fuzzing libmaxminddb
These tests are only meant to be run on GNU/Linux.
## Build maxminddb fuzzer using libFuzzer.
### Export flags for fuzzing.
Note that in `CFLAGS` and `CXXFLAGS`, any type of sanitizers can be added.
- [AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html),
[ThreadSanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html),
[MemorySanitizer](https://clang.llvm.org/docs/MemorySanitizer.html),
[UndefinedBehaviorSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html),
[LeakSanitizer](https://clang.llvm.org/docs/LeakSanitizer.html).
```shell
$ export CC=clang
$ export CXX=clang++
$ export CFLAGS="-g -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address,undefined -fsanitize=fuzzer-no-link"
$ export CXXFLAGS="-g -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address,undefined -fsanitize=fuzzer-no-link"
$ export LIB_FUZZING_ENGINE="-fsanitize=fuzzer"
```
### Build maxminddb for fuzzing.
```shell
$ mkdir -p build && cd build
$ cmake -DBUILD_FUZZING=ON ../.
$ cmake --build . -j$(nproc)
```
### Running fuzzer.
```shell
$ mkdir -p fuzz_mmdb_seed fuzz_mmdb_seed_corpus
$ find ../t/maxmind-db/test-data/ -type f -size -4k -exec cp {} ./fuzz_mmdb_seed_corpus/ \;
$ ./t/fuzz_mmdb fuzz_mmdb_seed/ fuzz_mmdb_seed_corpus/
```
Here is more information about [LibFuzzer](https://llvm.org/docs/LibFuzzer.html).

View file

@ -30,11 +30,13 @@ structure.
To install this code, run the following commands:
$ ./configure
$ make
$ make check
$ sudo make install
$ sudo ldconfig
```bash
./configure
make
make check
sudo make install
sudo ldconfig
```
You can skip the `make check` step but it's always good to know that tests are
passing on your platform.
@ -47,8 +49,10 @@ you may need to add the `lib` directory in your `prefix` to your library path.
On most Linux distributions when using the default prefix (`/usr/local`), you
can do this by running the following commands:
$ sudo sh -c "echo /usr/local/lib >> /etc/ld.so.conf.d/local.conf"
$ ldconfig
```bash
sudo sh -c "echo /usr/local/lib >> /etc/ld.so.conf.d/local.conf"
ldconfig
```
## From a GitHub "Source Code" Archive / Git Repo Clone (Achtung!)
@ -65,7 +69,9 @@ in addition to `make` and a compiler.
You can clone this repository and build it by running:
$ git clone --recursive https://github.com/maxmind/libmaxminddb
```bash
git clone --recursive https://github.com/maxmind/libmaxminddb
```
After cloning, run `./bootstrap` from the `libmaxminddb` directory and then
follow the instructions for installing from a named release tarball as
@ -76,39 +82,57 @@ described above.
We provide a CMake build script. This is primarily targeted at Windows users,
but it can be used in other circumstances where the Autotools script does not
work.
$ mkdir build && cd build
$ cmake ..
$ cmake --build .
$ ctest -V .
$ cmake --build . --target install
```bash
cmake -B build
cd build/
cmake --build .
ctest -V .
cmake --build . --target install
```
When building with Visual Studio, you may build a multithreaded (MT/MTd)
runtime library, using the `MSVC_STATIC_RUNTIME` setting:
$ cmake -DMSVC_STATIC_RUNTIME=ON -DBUILD_SHARED_LIBS=OFF ..
```bash
cmake -DMSVC_STATIC_RUNTIME=ON -DBUILD_SHARED_LIBS=OFF ..
```
We also include a CMake `uninstall` target:
```bash
cmake --build . --target uninstall
```
## On Ubuntu via PPA
MaxMind provides a PPA for recent version of Ubuntu. To add the PPA to your
APT sources, run:
$ sudo add-apt-repository ppa:maxmind/ppa
```bash
sudo add-apt-repository ppa:maxmind/ppa
```
Then install the packages by running:
$ sudo apt update
$ sudo apt install libmaxminddb0 libmaxminddb-dev mmdb-bin
```bash
sudo apt update
sudo apt install libmaxminddb0 libmaxminddb-dev mmdb-bin
```
## On macOS via Homebrew or MacPorts
You can install libmaxminddb on macOS using [Homebrew](https://brew.sh):
$ brew install libmaxminddb
```bash
brew install libmaxminddb
```
Or with [MacPorts](https://ports.macports.org/port/libmaxminddb):
$ sudo port install libmaxminddb
```bash
sudo port install libmaxminddb
```
# Requirements
@ -126,7 +150,7 @@ Use `make safedist` to check the resulting tarball.
# Copyright and License
Copyright 2013-2024 MaxMind, Inc.
Copyright 2013-2025 MaxMind, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

21
cmake_uninstall.cmake.in Normal file
View file

@ -0,0 +1,21 @@
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
endif()
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach(file ${files})
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
execute_process(
COMMAND "@CMAKE_COMMAND@" -E remove "$ENV{DESTDIR}${file}"
OUTPUT_VARIABLE rm_out
RESULT_VARIABLE rm_retval
)
if(NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
endif()
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
endif()
endforeach()

View file

@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.63])
AC_INIT([libmaxminddb], [1.11.0], [support@maxmind.com])
AC_INIT([libmaxminddb], [1.12.1], [support@maxmind.com])
AC_CONFIG_SRCDIR([include/maxminddb.h])
AC_CONFIG_HEADERS([config.h include/maxminddb_config.h])

View file

@ -2,13 +2,10 @@
use strict;
use warnings;
use autodie qw( :all );
use FindBin qw( $Bin );
use File::Path qw( mkpath );
use File::Slurp qw( edit_file read_file );
use File::Which qw( which );
sub main {
my $target = shift || "$Bin/..";
@ -16,7 +13,7 @@ sub main {
my @translators = qw ( lowdown pandoc );
my $translator;
foreach my $p (@translators) {
if ( defined which($p) ) {
if ( _which($p) ) {
$translator = $p;
last;
}
@ -33,6 +30,14 @@ sub main {
_make_man( $translator, $target, 'mmdblookup', 1 );
}
sub _which {
my $program = shift;
for my $path ( split /:/, $ENV{PATH} ) {
return 1 if -x "$path/$program";
}
return 0;
}
sub _make_man {
my $translator = shift;
my $target = shift;
@ -54,7 +59,7 @@ sub _make_man {
'-M', "section:$section",
$input,
'-o', $output,
);
) == 0 or die "Failed to run pandoc: $?";
_pandoc_postprocess($output);
}
elsif ( $translator eq 'lowdown' ) {
@ -67,18 +72,27 @@ sub _make_man {
'-M', "section:$section",
$input,
'-o', $output,
);
) == 0 or die "Failed to run lowdown: $?";
}
}
sub _make_lib_man_links {
my $target = shift;
my $header = read_file("$Bin/../include/maxminddb.h");
open my $header_fh, '<', "$Bin/../include/maxminddb.h"
or die "Failed to open header file: $!";
my $header = do { local $/; <$header_fh> };
die "Error reading file header file: $!" unless defined $header;
close $header_fh or die "Failed to close header file: $!";
for my $proto ( $header =~ /^ *extern.+?(MMDB_\w+)\(/gsm ) {
open my $fh, '>', "$target/man/man3/$proto.3";
print {$fh} ".so man3/libmaxminddb.3\n";
close $fh;
open my $fh, '>', "$target/man/man3/$proto.3"
or die "Failed to open file: $!";
print {$fh} ".so man3/libmaxminddb.3\n"
or die "Failed to write to file: $!";
close $fh or die "Failed to close file: $!";
}
}
@ -87,13 +101,20 @@ sub _make_lib_man_links {
sub _pandoc_postprocess {
my $file = shift;
edit_file(
sub {
s/^\.IP\n\.nf/.IP "" 4\n.nf/gm;
s/(Automatically generated by Pandoc)(.+)$/$1/m;
},
$file
);
open my $fh, '<', $file or die "Failed to open man file for reading: $!";
my @lines = <$fh>;
die "Error when reading man page: $!" if $!;
close $fh or die "Failed to close file: $!";
for my $line (@lines) {
$line =~ s/^\.IP\n\.nf/.IP "" 4\n.nf/gm;
$line =~ s/(Automatically generated by Pandoc)(.+)$/$1/m;
}
open $fh, '>', $file or die "Failed to open file for writing: $!";
print $fh @lines or die "Failed to write to file: $!";
close $fh or die "Failed to close file: $!";
}
main(shift);

View file

@ -883,7 +883,7 @@ Rolsky (drolsky@maxmind.com).
# COPYRIGHT AND LICENSE
Copyright 2013-2024 MaxMind, Inc.
Copyright 2013-2025 MaxMind, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View file

@ -86,7 +86,7 @@ Rolsky (drolsky@maxmind.com).
# COPYRIGHT AND LICENSE
Copyright 2013-2024 MaxMind, Inc.
Copyright 2013-2025 MaxMind, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View file

@ -744,12 +744,14 @@ static int populate_languages_metadata(MMDB_s *mmdb,
mmdb->metadata.languages.count = 0;
mmdb->metadata.languages.names = calloc(array_size, sizeof(char *));
if (NULL == mmdb->metadata.languages.names) {
MMDB_free_entry_data_list(first_member);
return MMDB_OUT_OF_MEMORY_ERROR;
}
for (uint32_t i = 0; i < array_size; i++) {
member = member->next;
if (MMDB_DATA_TYPE_UTF8_STRING != member->entry_data.type) {
MMDB_free_entry_data_list(first_member);
return MMDB_INVALID_METADATA_ERROR;
}
@ -757,6 +759,7 @@ static int populate_languages_metadata(MMDB_s *mmdb,
member->entry_data.utf8_string, member->entry_data.data_size);
if (NULL == mmdb->metadata.languages.names[i]) {
MMDB_free_entry_data_list(first_member);
return MMDB_OUT_OF_MEMORY_ERROR;
}
// We assign this as we go so that if we fail a calloc and need to
@ -1646,6 +1649,10 @@ int MMDB_get_entry_data_list(MMDB_entry_s *start,
int const status =
get_entry_data_list(start->mmdb, start->offset, list, pool, 0);
if (MMDB_SUCCESS != status) {
data_pool_destroy(pool);
return status;
}
*entry_data_list = data_pool_to_list(pool);
if (!*entry_data_list) {

View file

@ -52,3 +52,9 @@ foreach(TEST_TARGET_NAME ${TEST_TARGET_NAMES})
add_test( NAME ${TEST_TARGET_NAME} COMMAND ${TEST_TARGET_NAME} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/t)
endforeach()
if(BUILD_FUZZING)
add_executable(fuzz_mmdb fuzz_mmdb.c)
target_include_directories(fuzz_mmdb PRIVATE ../src)
target_link_libraries(fuzz_mmdb maxminddb $ENV{LIB_FUZZING_ENGINE})
endif()

View file

@ -28,8 +28,6 @@ void run_tests(int mode, const char *mode_desc) {
MMDB_INVALID_DATA_ERROR,
"MMDB_get_entry_data_list returns MMDB_INVALID_DATA_ERROR for "
"bad pointer in data section");
MMDB_free_entry_data_list(entry_data_list);
}
{

36
t/fuzz_mmdb.c Normal file
View file

@ -0,0 +1,36 @@
#include "maxminddb-compat-util.h"
#include "maxminddb.h"
#include <unistd.h>
#define kMinInputLength 2
#define kMaxInputLength 4048
extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
int status;
FILE *fp;
MMDB_s mmdb;
char filename[256];
if (size < kMinInputLength || size > kMaxInputLength)
return 0;
sprintf(filename, "/tmp/libfuzzer.%d", getpid());
fp = fopen(filename, "wb");
if (!fp)
return 0;
fwrite(data, size, sizeof(uint8_t), fp);
fclose(fp);
status = MMDB_open(filename, MMDB_MODE_MMAP, &mmdb);
if (status == MMDB_SUCCESS)
MMDB_close(&mmdb);
unlink(filename);
return 0;
}