Skip to content

Commit 1462085

Browse files
authored
ndpiReader: install custom memory allocators before any nDPI API usage (#3164)
ndpiReader was setting custom memory allocation hooks only inside test_lib(), which is executed after several code paths that already use nDPI APIs (e.g., parseOptions, help/extcap paths, host checks, DoH initialization, etc.). This could lead to inconsistent allocator usage where memory is allocated using the default libc allocator (when hooks are unset) and later freed using custom allocators, resulting in undefined behavior with non-trivial allocators. This partially addresses #1280.
1 parent 315a705 commit 1462085

4 files changed

Lines changed: 55 additions & 10 deletions

File tree

Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ EXTRA_DIST = README.md README.fuzzer.md CHANGELOG.md CONTRIBUTING.md \
4343
lists/README.md \
4444
lists/protocols/README.md \
4545
sonar-project.properties .github .ci-ignore \
46-
src/lib/plugins/README.md
46+
src/lib/plugins/README.md \
47+
example/README.md
4748

4849
doc:
4950
make -C doc html

doc/library_initialization.rst

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,32 @@ A more complex example, with global context and a shared Oookla LRU cache (all t
8282
8383
ndpi_global_deinit(g_ctx);
8484
85+
86+
87+
Another example, with a custom memory allocator
88+
89+
.. code:: c
90+
91+
struct ndpi_detection_module_struct *ndpi_struct;
92+
ndpi_cfg_error rc;
93+
int ret;
94+
95+
/* If you want to set a custom allocator for all memory allocations performed by
96+
the library, you must call `ndpi_set_memory_alloction_functions() ONCE,
97+
BEFORE ANY nDPI functions */
98+
99+
ndpi_set_memory_alloction_functions(malloc_wrapper,
100+
free_wrapper,
101+
calloc_wrapper,
102+
realloc_wrapper,
103+
aligned_malloc_wrapper,
104+
aligned_free_wrapper,
105+
flow_malloc_wrapper,
106+
flow_free_wrapper);
107+
108+
ndpi_struct = ndpi_init_detection_module(NULL);
109+
if(!ndpi_struct) {
110+
ERROR;
111+
}
112+
113+
/* Continue as the previous examples */

example/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# nDPI example tools
2+
3+
This directory contains sample programs that link against libnDPI, mainly **ndpiReader** (CLI over pcaps and live capture) and **ndpiSimpleIntegration**. DPDK-specific notes live in [README.DPDK](README.DPDK).
4+
5+
## Custom memory allocators
6+
7+
nDPI can use application-provided allocators via `ndpi_set_memory_alloction_functions()` (see `ndpi_api.h` / `ndpi_memory.c`). **Every pointer obtained through `ndpi_malloc()`, `ndpi_calloc()`, `ndpi_strdup()`, APIs that allocate internally (e.g. `ndpi_init_bin()`), or memory owned by the library must be released with the matching `ndpi_free()` path that uses the same allocator configuration as at allocation time.**
8+
From a practical point of view, that means that the application code must installs its hooks once, via `ndpi_set_memory_alloction_functions()` **before ANY library functions**.
9+
10+
**IF** your own application wants to use `ndpi_malloc()` and similar functions also for its own allocations, `ndpi_set_memory_alloction_functions()` **must** be called before **ANY** allocations, from the library and from the application, both. All these memory must be freed via `ndpi_free()`.

example/ndpiReader.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5574,15 +5574,6 @@ void test_lib() {
55745574
#endif
55755575
struct ndpi_global_context *g_ctx;
55765576

5577-
ndpi_set_memory_alloction_functions(malloc_wrapper,
5578-
free_wrapper,
5579-
calloc_wrapper,
5580-
realloc_wrapper,
5581-
aligned_malloc_wrapper,
5582-
aligned_free_wrapper,
5583-
flow_malloc_wrapper,
5584-
flow_free_wrapper);
5585-
55865577
#ifndef USE_GLOBAL_CONTEXT
55875578
/* ndpiReader works even if libnDPI has been compiled without global context support,
55885579
but you can't configure any cache with global scope */
@@ -5771,6 +5762,20 @@ int main(int argc, char **argv) {
57715762
return(-1);
57725763
}
57735764

5765+
/* Set a custom allocator for the library.
5766+
**IF** you want to use `ndpi_malloc()` and similar functions to allocate memory ALSO
5767+
from your application code, you must be sure to call `ndpi_set_memory_alloction_functions()`
5768+
BEFORE ANY allocations (from the library and from the application, both)
5769+
*/
5770+
ndpi_set_memory_alloction_functions(malloc_wrapper,
5771+
free_wrapper,
5772+
calloc_wrapper,
5773+
realloc_wrapper,
5774+
aligned_malloc_wrapper,
5775+
aligned_free_wrapper,
5776+
flow_malloc_wrapper,
5777+
flow_free_wrapper);
5778+
57745779
gettimeofday(&startup_time, NULL);
57755780
memset(ndpi_thread_info, 0, sizeof(ndpi_thread_info));
57765781

0 commit comments

Comments
 (0)