On Sat, 07 Jun 2025 22:44:40 +0000 Witold Baryluk <[email protected]>
wrote:
Package: moreutils
Version: 0.69-1
Severity: normal
File: /usr/bin/ifdata
X-Debbugs-Cc: [email protected]
All statistics related commands from ifdata has some bug resulting in
program termination.
$ ifdata -si enp65s0f0np0
*** stack smashing detected ***: terminated
Aborted (core dumped)
Hello,
I tried to track this down, and it originates from a fscanf in get_stats,
which tries to put the interface name into the "char name[10]" variable.
I was able to reproduce it inside a VM by attaching a virtual usb network
adapter,
which gets a 15 bytes interface name ((qemu) device_add usb-net,id=usb-net1).
A package built with attached patch no longer shows the stack smashing.
Kind regards,
Bernhard
(rr) bt
#0 0x00007fd71a387f25 in __vfscanf_internal (s=<optimized out>, format=<optimized
out>, argptr=argptr@entry=0x7ffde7e7a7d0, mode_flags=mode_flags@entry=2) at
./stdio-common/vfscanf-internal.c:3020
#1 0x00007fd71a3785e9 in __isoc99_fscanf (stream=stream@entry=0x562293989350,
format=format@entry=0x562255d75078 " %20[^:]:%llu %llu %llu %llu %llu %llu %llu %llu
%llu %llu %llu %llu %llu %llu %llu %llu") at ./stdio-common/isoc99_fscanf.c:30
#2 0x0000562255d73d78 in get_stats (iface=iface@entry=0x7ffde7e7bdc9
"enx405400123457") at ./ifdata.c:291
#3 0x0000562255d732e5 in main (argc=3, argv=0x7ffde7e7ab68) at ./ifdata.c:576
From ba05f7e0f7e5a1037ee2ad692dae59c47e86e42a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= <[email protected]>
Date: Tue, 16 Sep 2025 15:05:48 +0200
Subject: [PATCH] ifdata: Fix stack smashing by fscanf in get_stats. (Closes:
#1107470)
Debian-Bug: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1107470
---
ifdata.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ifdata.c b/ifdata.c
index 6e0bd0b..4f5d801 100644
--- a/ifdata.c
+++ b/ifdata.c
@@ -270,7 +270,7 @@ static void skipline(FILE *fd) {
struct if_stat *get_stats(const char *iface) {
FILE *fd;
struct if_stat *ifstat;
- char name[10];
+ char name[20];
if (!(ifstat = malloc(sizeof(struct if_stat)))) {
perror("malloc");
--
2.47.3
# minimal Trixie/stable amd64 qemu VM 2025-09-16
(qemu) device_add usb-net,id=usb-net1
apt install moreutils moreutils-dbgsym valgrind gdb rr mc git
apt build-dep moreutils
mkdir /home/benutzer/source/moreutils/orig -p
cd /home/benutzer/source/moreutils/orig
apt source moreutils
root@debian:~# ifdata -si enx405400123457
*** stack smashing detected ***: terminated
Abgebrochen
root@debian:~#
root@debian:~# rr record ifdata -si enx405400123457
rr: Saving execution to trace directory `/root/.local/share/rr/ifdata-0'.
*** stack smashing detected ***: terminated
Abgebrochen
root@debian:~#
root@debian:~# rr replay -a ifdata-0
*** stack smashing detected ***: terminated
root@debian:~#
rr replay --debugger-option=-q ifdata-0
directory /home/benutzer/source/moreutils/orig/moreutils-0.69
set width 0
set pagination off
display/i $pc
cont
bt
root@debian:~# rr replay --debugger-option=-q ifdata-0
Reading symbols from /root/.local/share/rr/ifdata-0/mmap_hardlink_4_ifdata...
Reading symbols from
/usr/lib/debug/.build-id/7f/8a0189b2e434757dfab0a88e0a371c575dc2c5.debug...
Remote debugging using 127.0.0.1:2805
Reading symbols from /lib64/ld-linux-x86-64.so.2...
Reading symbols from
/usr/lib/debug/.build-id/da/08404553b441511cbee6b34bc78fe29fd5d14c.debug...
warning: BFD: warning: system-supplied DSO at 0x6fffd000 has a section
extending past end of file
warning: Discarding section .replay.text which has an invalid size (27) [in
module system-supplied DSO at 0x6fffd000]
0x00007fd71a555440 in _start () from /lib64/ld-linux-x86-64.so.2
(rr) directory /home/benutzer/source/moreutils/orig/moreutils-0.69
Source directories searched:
/home/benutzer/source/moreutils/orig/moreutils-0.69:$cdir:$cwd
(rr) set width 0
(rr) set pagination off
(rr) display/i $pc
1: x/i $pc
=> 0x7fd71a555440 <_start>: mov %rsp,%rdi
(rr) cont
Continuing.
*** stack smashing detected ***: terminated
Program received signal SIGABRT, Aborted.
__pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6,
no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
warning: 44 ./nptl/pthread_kill.c: Datei oder Verzeichnis nicht gefunden
1: x/i $pc
=> 0x7fd71a3b395c <__pthread_kill_implementation+268>: mov %eax,%ebx
(rr) bt
#0 __pthread_kill_implementation (threadid=<optimized out>,
signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
#1 0x00007fd71a3b39ff in __pthread_kill_internal (threadid=<optimized out>,
signo=6) at ./nptl/pthread_kill.c:89
#2 0x00007fd71a35ecc2 in __GI_raise (sig=sig@entry=6) at
../sysdeps/posix/raise.c:26
#3 0x00007fd71a3474ac in __GI_abort () at ./stdlib/abort.c:73
#4 0x00007fd71a348291 in __libc_message_impl (fmt=fmt@entry=0x7fd71a4ca1a4
"*** %s ***: terminated\n") at ../sysdeps/posix/libc_fatal.c:134
#5 0x00007fd71a43a995 in __GI___fortify_fail (msg=msg@entry=0x7fd71a4ca1bc
"stack smashing detected") at ./debug/fortify_fail.c:24
#6 0x00007fd71a43bbb0 in __stack_chk_fail () at ./debug/stack_chk_fail.c:24
#7 0x0000562255d73e0c in get_stats (iface=iface@entry=0x7ffde7e7bdc9
"enx405400123457") at ./ifdata.c:321
#8 0x0000562255d732e5 in main (argc=3, argv=0x7ffde7e7ab68) at ./ifdata.c:576
(rr) b get_stats
Breakpoint 1 at 0x562255d73bd0: file ./ifdata.c, line 270.
(rr) reverse-cont
Continuing.
Program received signal SIGABRT, Aborted.
__pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6,
no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
44 in ./nptl/pthread_kill.c
1: x/i $pc
=> 0x7fd71a3b395c <__pthread_kill_implementation+268>: mov %eax,%ebx
(rr) reverse-cont
Continuing.
Breakpoint 1, get_stats (iface=iface@entry=0x7ffde7e7bdc9 "enx405400123457") at
./ifdata.c:270
270 struct if_stat *get_stats(const char *iface) {
1: x/i $pc
=> 0x562255d73bd0 <get_stats>: endbr64
(rr) stepi
0x0000562255d73bd4 270 struct if_stat *get_stats(const char *iface) {
1: x/i $pc
=> 0x562255d73bd4 <get_stats+4>: push %r15
(rr)
0x0000562255d73bd6 270 struct if_stat *get_stats(const char *iface) {
1: x/i $pc
=> 0x562255d73bd6 <get_stats+6>: push %r14
(rr)
0x0000562255d73bd8 270 struct if_stat *get_stats(const char *iface) {
1: x/i $pc
=> 0x562255d73bd8 <get_stats+8>: push %r13
(rr)
0x0000562255d73bda 270 struct if_stat *get_stats(const char *iface) {
1: x/i $pc
=> 0x562255d73bda <get_stats+10>: push %r12
(rr)
0x0000562255d73bdc 270 struct if_stat *get_stats(const char *iface) {
1: x/i $pc
=> 0x562255d73bdc <get_stats+12>: push %rbp
(rr)
0x0000562255d73bdd 270 struct if_stat *get_stats(const char *iface) {
1: x/i $pc
=> 0x562255d73bdd <get_stats+13>: push %rbx
(rr)
0x0000562255d73bde 270 struct if_stat *get_stats(const char *iface) {
1: x/i $pc
=> 0x562255d73bde <get_stats+14>: sub $0x98,%rsp
(rr)
0x0000562255d73be5 270 struct if_stat *get_stats(const char *iface) {
1: x/i $pc
=> 0x562255d73be5 <get_stats+21>: mov %rdi,0x60(%rsp)
(rr)
0x0000562255d73bea 275 if (!(ifstat = malloc(sizeof(struct
if_stat)))) {
1: x/i $pc
=> 0x562255d73bea <get_stats+26>: mov $0x80,%edi
(rr)
0x0000562255d73bef 270 struct if_stat *get_stats(const char *iface) {
1: x/i $pc
=> 0x562255d73bef <get_stats+31>: mov %fs:0x28,%rax
(rr)
0x0000562255d73bf8 270 struct if_stat *get_stats(const char *iface) {
1: x/i $pc
=> 0x562255d73bf8 <get_stats+40>: mov %rax,0x88(%rsp)
(rr) x/1xg $rsp + 0x88
0x7ffde7e7a9a8: 0x000000000000000d
(rr) watch *0x7ffde7e7a9a8
Hardware watchpoint 2: *0x7ffde7e7a9a8
(rr) stepi
Hardware watchpoint 2: *0x7ffde7e7a9a8
Old value = 13
New value = -763956224
0x0000562255d73c00 in get_stats (iface=iface@entry=0x7ffde7e7bdc9
"enx405400123457") at ./ifdata.c:270
270 struct if_stat *get_stats(const char *iface) {
1: x/i $pc
=> 0x562255d73c00 <get_stats+48>: xor %eax,%eax
(rr) cont
Continuing.
Hardware watchpoint 2: *0x7ffde7e7a9a8
Old value = -763956224
New value = -763956174
0x00007fd71a387f25 in __vfscanf_internal (s=<optimized out>, format=<optimized
out>, argptr=argptr@entry=0x7ffde7e7a7d0, mode_flags=mode_flags@entry=2) at
./stdio-common/vfscanf-internal.c:3020
warning: 3020 ./stdio-common/vfscanf-internal.c: Datei oder Verzeichnis nicht
gefunden
1: x/i $pc
=> 0x7fd71a387f25 <__vfscanf_internal+16053>: lea 0x1(%rbx),%rax
(rr) bt
#0 0x00007fd71a387f25 in __vfscanf_internal (s=<optimized out>,
format=<optimized out>, argptr=argptr@entry=0x7ffde7e7a7d0,
mode_flags=mode_flags@entry=2) at ./stdio-common/vfscanf-internal.c:3020
#1 0x00007fd71a3785e9 in __isoc99_fscanf (stream=stream@entry=0x562293989350,
format=format@entry=0x562255d75078 " %20[^:]:%llu %llu %llu %llu %llu %llu %llu
%llu %llu %llu %llu %llu %llu %llu %llu %llu") at
./stdio-common/isoc99_fscanf.c:30
#2 0x0000562255d73d78 in get_stats (iface=iface@entry=0x7ffde7e7bdc9
"enx405400123457") at ./ifdata.c:291
#3 0x0000562255d732e5 in main (argc=3, argv=0x7ffde7e7ab68) at ./ifdata.c:576
(rr) frame 2
#2 0x0000562255d73d78 in get_stats (iface=iface@entry=0x7ffde7e7bdc9
"enx405400123457") at ./ifdata.c:291
291 int items = fscanf(fd,
(rr) list
286 /* Skip header */
287 skipline(fd);
288 skipline(fd);
289
290 do {
291 int items = fscanf(fd,
292 " %20[^:]:%llu %llu %llu %llu %llu %llu %llu
%llu "
293 "%llu %llu %llu %llu %llu %llu %llu %llu",
294 name,
295 &ifstat->in_bytes, &ifstat->in_packets,
(rr) print sizeof(name)
$1 = 10
(rr)
https://git.kitenet.net/index.cgi/moreutils.git/tree/ifdata.c#n273
https://git.kitenet.net/index.cgi/moreutils.git/tree/ifdata.c#n291