Potential Out-of-Memory Risk in coreutils od Due to Inadequate Argument Validation for -w Option
*Description* ``` $ src/od -w0 /bin/ls Aborted ``` ``` 1835 if (s_err != LONGINT_OK || w_tmp <= 0) 1836 xstrtol_fatal (s_err, oi, c, long_options, optarg); ``` We confirmed that when the argument for -w is set to 0, the program correctly handles the case by checking whether w_tmp is less than or equal to zero and raises an appropriate exception. ``` $ src/od -w4294967299223422228333 /bin/ls od: -w argument '4294967299223422228333' too large ``` ``` 1837 if (ckd_add (&desired_width, w_tmp, 0)) 1838 error (EXIT_FAILURE, 0, _("%s is too large"), quote (optarg)); ``` We also observed that when the -w argument is extremely large, the program handles the case properly through the use of ckd_add to prevent unsafe allocation. *ASAN Log* ``` $ src/od -w429496729922348 /bin/ls ================================================================= ==1151683==ERROR: AddressSanitizer: requested allocation size 0x30d400009d658 (0x30d400009e658 after adjustments for alignment, red zones etc.) exceeds maximum supported size of 0x10000000000 (thread T0) #0 0x49c843 in __interceptor_realloc (coreutils/src/od+0x49c843) #1 0x4dd99d in xreallocarray coreutils/lib/xmalloc.c:84:13 #2 0x4dd99d in xnmalloc coreutils/lib/xmalloc.c:102:10 #3 0x7f30f39c7d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16 ==1151683==HINT: if you don't care about these errors you may set allocator_may_return_null=1 SUMMARY: AddressSanitizer: allocation-size-too-big (coreutils/src/od+0x49c843) in __interceptor_realloc ==1151683==ABORTING ``` However, for certain specific values of -w, these two checks can be bypassed, resulting in the program attempting to allocate an excessively large amount of memory. ``` 1427 dump (void) 1428 { 1429 char *block[2]; 1430 uintmax_t current_offset; 1431 bool idx = false; 1432 bool ok = true; 1433 size_t n_bytes_read; 1434 1435 block[0] = xnmalloc (2, bytes_per_block); ``` This happens because the parsed -w value is passed to bytes_per_block, which is then used in a call to xnmalloc, leading to potentially dangerous memory allocation. To mitigate this issue, we suggest adding a proper argument validation check to handle such edge cases safely. *Build options*``` git clone https://github.com/coreutils/coreutils export GNULIB_SRCDIR=./gnulib export FORCE_UNSAFE_CONFIGURE=1 ./bootstrap CC="clang -g -fsanitize=address" CXX="clang -g -fsanitize=address" ./configure $CONFIG_OPTIONS make -j ``` *Program version*``` $ src/od --version od (GNU coreutils) 9.7.52-b7db77 Copyright (C) 2025 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later < https://gnu.org/licenses/gpl.html>. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Written by Jim Meyering. ```