bug#78879: Potential Out-of-Memory in coreutils od

Jaehoon Jang <[email protected]>
Newsgroups gmane.comp.gnu.core-utils.bugs
Message-ID <CACPYndryDQ-Zqq1c2o533iYejUTD9dmp5whOj7vmRni-K78Prg@mail.gmail.com>
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.
```
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.