| Título | mapnik Mapnik v4.2.0 and master-branch Heap-based Buffer Overflow |
|---|
| Descripción | ### Description
We discovered a Heap Buffer Overflow (Read) vulnerability in Mapnik. The crash occurs within the dbf_file::string_value function in the Shapefile input plugin.
When parsing a malformed input, the application attempts to read memory beyond the allocated heap buffer when constructing a std::string. This leads to a SIGABRT/Crash.
### Environment
- OS: Linux x86_64
- Complier: Clang/GCC with AddressSanitizer (-fsanitize=address)
- Build Configuration: Release Mode (-O3, -DNDEBUG),Static Plugins Linking
- Affected Version: `master branch`
### Vulnerability Details
- Crash Type: Heap-buffer-overflow (READ of size 112)
- Source File: plugins/input/shape/dbfile.cpp
- Function: mapnik::dbf_file::string_value
- Root Cause Analysis: The ASAN report indicates a read violation of 112 bytes at plugins/input/shape/dbfile.cpp:92. The memory region was originally allocated in dbf_file::read_header (size 362 bytes). It appears that string_value attempts to read a field value or descriptor using an offset or length derived from the file header without sufficient bounds checking against the actual size of the allocated buffer. This allows the read operation (via std::string constructor) to access invalid memory.
### Reproduce
1. Build Mapnik with Release optimization (-O3) and ASAN enabled. Input plugins should be linked statically.
2. Compile the Mapnik [harness](https://github.com/oneafter/1218/blob/main/harness.cpp) with AddressSanitizer enabled (-fsanitize=address -g)
3. Run with the crashing file [repro](https://github.com/oneafter/1218/blob/main/repro):
```
./harness repro
```
ASAN report
```
==78629==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x51300000116a at pc 0x55834e530b8f bp 0x7fff59dcb440 sp 0x7fff59dcac00
READ of size 112 at 0x51300000116a thread T0
#0 0x55834e530b8e in __asan_memcpy (/src/mapnik/harness+0x153b8e) (BuildId: cd92e1fb8850896b0ef72db2a841bdcbc5d565bc)
#1 0x55834f07b633 in std::char_traits<char>::copy(char*, char const*, unsigned long) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/char_traits.h:435:33
#2 0x55834f07b633 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>::_S_copy(char*, char const*, unsigned long) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/basic_string.h:430:4
#3 0x55834f07b633 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>::_S_copy_chars(char*, char const*, char const*) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/basic_string.h:484:9
#4 0x55834f07b633 in void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/basic_string.tcc:247:2
#5 0x55834f07b633 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>::basic_string(char const*, unsigned long, std::allocator<char> const&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/basic_string.h:627:2
#6 0x55834f07b633 in dbf_file::string_value[abi:cxx11](int) const /src/mapnik/plugins/input/shape/dbfile.cpp:92:16
#7 0x55834e9517da in main /src/mapnik/plugins/input/shape/dbf_test.cpp:50:30
#8 0x7f67c65451c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#9 0x7f67c654528a in __libc_start_main csu/../csu/libc-start.c:360:3
#10 0x55834e493034 in _start (/src/mapnik/harness+0xb6034) (BuildId: cd92e1fb8850896b0ef72db2a841bdcbc5d565bc)
0x51300000116a is located 0 bytes after 362-byte region [0x513000001000,0x51300000116a)
allocated by thread T0 here:
#0 0x55834e5744e1 in operator new(unsigned long) (/src/mapnik/harness+0x1974e1) (BuildId: cd92e1fb8850896b0ef72db2a841bdcbc5d565bc)
#1 0x55834f07a11b in dbf_file::read_header() /src/mapnik/plugins/input/shape/dbfile.cpp:212:42
#2 0x55834f0798ba in dbf_file::dbf_file(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&) /src/mapnik/plugins/input/shape/dbfile.cpp:59:9
#3 0x55834e95122b in main /src/mapnik/plugins/input/shape/dbf_test.cpp:38:14
#4 0x7f67c65451c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#5 0x7f67c654528a in __libc_start_main csu/../csu/libc-start.c:360:3
#6 0x55834e493034 in _start (/src/mapnik/harness+0xb6034) (BuildId: cd92e1fb8850896b0ef72db2a841bdcbc5d565bc)
SUMMARY: AddressSanitizer: heap-buffer-overflow (/src/mapnik/harness+0x153b8e) (BuildId: cd92e1fb8850896b0ef72db2a841bdcbc5d565bc) in __asan_memcpy
Shadow bytes around the buggy address:
0x513000000e80: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x513000000f00: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x513000000f80: fd fd fd fa fa fa fa fa fa fa fa fa fa fa fa fa
0x513000001000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x513000001080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x513000001100: 00 00 00 00 00 00 00 00 00 00 00 00 00[02]fa fa
0x513000001180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x513000001200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x513000001280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x513000001300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x513000001380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==78629==ABORTING
EXIT CODE: 1
``` |
|---|
| Fuente | ⚠️ https://github.com/mapnik/mapnik/issues/4543 |
|---|
| Usuario | Oneafter (UID 92781) |
|---|
| Sumisión | 2026-01-07 07:32 (hace 5 meses) |
|---|
| Moderación | 2026-01-17 17:29 (10 days later) |
|---|
| Estado | Aceptado |
|---|
| Entrada de VulDB | 341709 [Mapnik hasta 4.2.0 dbfile.cpp string_value desbordamiento de búfer] |
|---|
| Puntos | 20 |
|---|