Package: coreutils;
Reported by: Jaehoon Jang <jaehoon.jang <at> prosys.kaist.ac.kr>
Date: Mon, 23 Jun 2025 19:13:05 UTC
Severity: normal
Done: Pádraig Brady <P <at> draigBrady.com>
Bug is archived. No further changes may be made.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
From: Jaehoon Jang <jaehoon.jang <at> prosys.kaist.ac.kr> To: bug-coreutils <at> gnu.org Subject: od Heap-buffer overflow Date: Mon, 23 Jun 2025 17:24:53 +0900
[Message part 1 (text/plain, inline)]
*###### 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 ``` *###### od 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. ``` *###### reproduce script*```c // gcc -o replay_od replay_od.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #define MAX_CMDLINE_LEN 100000 #define MAX_CMDLINE_PAR 1000 int main() { static char in_buf[MAX_CMDLINE_LEN]; static char *argv[MAX_CMDLINE_PAR]; char *ptr = in_buf; int rc = 0; int n = read(0, in_buf, MAX_CMDLINE_LEN - 2); if (n <= 0) { perror("read"); exit(1); } while (*ptr) { argv[rc] = ptr; if (argv[rc][0] == 0x02 && !argv[rc][1]) { argv[rc]++; } rc++; while (*ptr) ptr++; ptr++; } argv[0] = "od"; // exec od with parsed argv execvp("src/od", argv); perror("execvp failed"); return 1; } ``` This is a C wrapper program that automatically sets argv to reproduce the vulnerability. It is a simple wrapper around the od program and does not modify the original od binary. ###### ASAN log ``` $ ./replay_od < /root/250623/od-poc od: 'u'$'\353''d'$'\001''4 '\'''$'\350\003\346\346\346\346\027\027\027\027\027\027\027\027''!'$'\027\027\027\027\027\027\027\027\027\027\027\027\027\027\027\027''{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{'$'\024''{{{{'$'\200\016\377\377''{{{{{{{{{{{s{{'$'\220''{{{{'$'\213\207\213\213\213\213\213\213\213\213\213\213\213\213''}'$'\213\213\213\213\213\213\213\213\213\213''E': No such file or directory ================================================================= ==1151699==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6150000004f9 at pc 0x0000004d153f bp 0x7fff937f0410 sp 0x7fff937f0408 WRITE of size 1 at 0x6150000004f9 thread T0 #0 0x4d153e in dump_strings coreutils/src/od.c:1570:14 #1 0x4d153e in main coreutils/src/od.c:2037:30 #2 0x7fc132ca6d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16 #3 0x7fc132ca6e3f in __libc_start_main csu/../csu/libc-start.c:392:3 #4 0x41f664 in _start (coreutils/src/od+0x41f664) 0x6150000004f9 is located 0 bytes to the right of 505-byte region [0x615000000300,0x6150000004f9) allocated by thread T0 here: #0 0x49c843 in __interceptor_realloc (coreutils/src/od+0x49c843) #1 0x4ddcea in rpl_realloc coreutils/./lib/stdlib.h:2095:10 #2 0x4ddcea in xrealloc coreutils/lib/xmalloc.c:66:13 #3 0x4ddcea in xpalloc coreutils/lib/xmalloc.c:271:8 #4 0x7fc132ca6d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16 SUMMARY: AddressSanitizer: heap-buffer-overflow coreutils/src/od.c:1570:14 in dump_strings Shadow bytes around the buggy address: 0x0c2a7fff8040: fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa 0x0c2a7fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c2a7fff8060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c2a7fff8070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c2a7fff8080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0c2a7fff8090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00[01] 0x0c2a7fff80a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c2a7fff80b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c2a7fff80c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c2a7fff80d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c2a7fff80e0: 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 ==1151699==ABORTING ``` *###### Description* ``` 1513 static bool 1514 dump_strings (void) 1515 { 1516 idx_t bufsize = MAX (100, string_min); 1517 char *buf = xmalloc (bufsize); ... 1550 while (!limit_bytes_to_format || address < end_offset) 1551 { 1552 if (i == bufsize) 1553 buf = xpalloc (buf, &bufsize, 1, -1, sizeof *buf); 1554 ok &= read_char (&c); 1555 address++; 1556 if (c < 0) 1557 { 1558 free (buf); 1559 return ok; 1560 } 1561 if (c == '\0') 1562 break; /* It is; print this string. */ 1563 if (! isprint (c)) 1564 goto tryline; /* It isn't; give up on this string. */ 1565 buf[i++] = c; /* String continues; store it all. */ 1566 } ... 1570 buf[i] = 0; 1571 format_address (address - i - 1, ' '); ``` The vulnerability occurs in the dump_strings function. The variable buf is allocated with a size of bufsize, which is limited to a maximum of 100 bytes. However, inside the while loop, the variable i is incremented by 1 on each iteration. When the attached PoC file is passed as arguments to the od program, the value of i can exceed 100. This leads to a heap buffer overflow vulnerability. An attacker could potentially exploit this by manipulating both the i and c values, resulting in dangerous modifications to the buf chunk on the heap. Therefore, we recommend adding proper bounds checking for the i variable to prevent this issue.
[Message part 2 (text/html, inline)]
[od-poc (application/octet-stream, attachment)]
[replay_od.c (application/octet-stream, attachment)]
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.