On Tue, Sep 16, 2025 at 03:18:46PM +0200, Bernhard Übelacker wrote:
> 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.

Thanks a lot!

According to Linux's kernels netif_set_alias() [1,2], it would make 
sense to increase it even to IFALIASZ (currently: 256).

I am planning to forward a patch to upstream within this week; or do 
you want to do it yourself?

Kind regards,
Nicolas


[1]: net/core/dev.c (Linux v6.17-rc6)
     
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/core/dev.c?h=v6.17-rc6#n1512

[2]: include/uapi/linux/if.h (Linux v6.17-rc6)
     
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if.h?h=v6.17-rc6#n35

> 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


-- 
Nicolas

Attachment: signature.asc
Description: PGP signature

Reply via email to