-
Notifications
You must be signed in to change notification settings - Fork 290
Heap allocation crash in escaped_name() when running ncdump -b f on a NetCDF file #3311
Description
Version of the software
netcdf-c commit: f1d2504c29099cec967756e6357fd3219ca1f415
Environmental information
OS: Ubuntu 22.04.5 LTS
Kernel: Linux 6.8.0-90-generic x86_64
Compiler: GCC 11.4.0
glibc: 2.35
Bug Description
Running ncdump -b f on a NetCDF input file triggers an abort caused by a failed assertion inside sysmalloc. The crash occurs during name processing in the escaped_name() and print_name() functions while recursively dumping dataset metadata.
Steps to Reproduce
The PoC attachment contains the input file that triggers the issue:
COMMAND LINE: ./ncdump -b f Assertion_failure_01
Expected behavior
ncdump should gracefully handle NetCDF files without triggering a memory allocator assertion or crashing.
Stack trace
(gdb) r
Starting program: /root/GraphDissect/benchmarks/netcdf/ncdump/ncdump -b f /root/GraphDissect/benchmarks/netcdf/ncdump/SIGABRT.PC.7d6d3406d9fc.STACK.ca471260e.CODE.-6.ADDR.0.INSTR.mov____%eax,%r13d.fuzz
warning: Error disabling address space randomization: Operation not permitted
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/x86_64-linux-gnu/libthread_db.so.1".
netcdf SIGABRT.PC.7d6d3406d9fc.STACK.ca471260e.CODE.-6.ADDR.0.INSTR.mov____%eax,%r13d {
dimensions:
ncdump: malloc.c:2617: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
Program received signal SIGABRT, Aborted.
__pthread_kill_implementation (no_tid=0, signo=6, threadid=124814488299456) at ./nptl/pthread_kill.c:44
44 ./nptl/pthread_kill.c: No such file or directory.
(gdb) bt
#0 __pthread_kill_implementation (no_tid=0, signo=6, threadid=124814488299456) at ./nptl/pthread_kill.c:44
#1 __pthread_kill_internal (signo=6, threadid=124814488299456) at ./nptl/pthread_kill.c:78
#2 __GI___pthread_kill (threadid=124814488299456, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3 0x00007184a5485476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4 0x00007184a546b7f3 in __GI_abort () at ./stdlib/abort.c:79
#5 0x00007184a54e3eca in __malloc_assert (
assertion=assertion@entry=0x7184a5621988 "(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)", file=file@entry=0x7184a561c68c "malloc.c", line=line@entry=2617, function=function@entry=0x7184a56221f8 <PRETTY_FUNCTION.8> "sysmalloc")
at ./malloc/malloc.c:307
#6 0x00007184a54e6937 in sysmalloc (nb=nb@entry=32, av=av@entry=0x7184a565dc80 <main_arena>) at ./malloc/malloc.c:2617
#7 0x00007184a54e78dd in _int_malloc (av=av@entry=0x7184a565dc80 <main_arena>, bytes=bytes@entry=1) at ./malloc/malloc.c:4407
#8 0x00007184a54e8262 in __GI___libc_malloc (bytes=1) at ./malloc/malloc.c:3321
#9 0x000000000044ee21 in escaped_name ()
#10 0x000000000044f1d0 in print_name ()
#11 0x0000000000439b76 in do_ncdump_rec ()
#12 0x0000000000437ee7 in do_ncdump ()
#13 0x0000000000436ba4 in main ()
(gdb)