Dear Maintainer,
I just tried to get some more information.
Following backtrace, little after the stack smashing happend, I could
reproduce with a amd64 qemu VM crossgraded from Buster amd64 to x32. :-)
That "struct rusage" has some elements of type "long" [1].
In gdb sizeof shows 4 bytes for such an element.
(gdb) print sizeof(ru1.ru_maxrss)
$6 = 4
Now I wonder if a x32 binary doing a syscall getrusage to a 64bit
kernel is supposed to supply memory like "long" would be 8 bytes?
Kind regards,
Bernhard
[1] http://man7.org/linux/man-pages/man2/getrusage.2.html
Watchpoint 2: *0xffb35cac
Old value = -658158982
New value = 0
0x004253e0 in __unified_syscall ()
1: x/i $pc
=> 0x4253e0 <__unified_syscall+15>: cmp $0xffffffffffffff7c,%rax
(gdb) bt
#0 0x004253e0 in __unified_syscall ()
#1 0x004138aa in j_sigchld (sig=<optimized out>) at ../../jobs.c:1369
#2 0x00411883 in trapsig (i=<optimized out>) at ../../histrap.c:1239
#3 <signal handler called>
#4 0x00000033 in ?? ()
0x004253db <__unified_syscall+10>: mov %rcx,%r10
0x004253de <__unified_syscall+13>: syscall
=> 0x004253e0 <__unified_syscall+15>: cmp $0xffffffffffffff7c,%rax
0x004138a5 <j_sigchld+151>: callq 0x42546a <getrusage>
=> 0x004138aa <j_sigchld+156>: mov 0x1ab50(%rip),%ebx # 0x42e400
<job_list>
(gdb) list jobs.c:1314,1370
...
1320 static void
1321 j_sigchld(int sig MKSH_A_UNUSED)
1322 {
...
1328 struct rusage ru0, ru1;
...
1369 getrusage(RUSAGE_CHILDREN, &ru1);
(gdb) print sizeof(ru1.ru_maxrss)
$6 = 4
# Install amd64 Buster
nano /etc/inputrc
apt install debian-ports-archive-keyring
nano /etc/apt/sources.list.d/buster-approx.list
deb [ arch=amd64 ]
http://192.168.178.25:9999/debian-10-buster-deb.debian.org/ unstable main
deb-src
http://192.168.178.25:9999/debian-10-buster-deb.debian.org/ unstable main
deb [ arch=x32 ]
http://192.168.178.25:9999/debian-10-buster-otherarch-ftp.ports.debian.org/
unstable main
rm /var/lib/apt/lists/192*
apt update
apt dist-upgrade
# https://wiki.debian.org/CrossGrading
# https://wiki.debian.org/X32Port
nano /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="syscall.x32=y quiet"
GRUB_CMDLINE_LINUX="syscall.x32=y"
update-grub2
dpkg --add-architecture x32
apt update
apt-get --download-only install dpkg:x32 tar:x32 apt:x32 libseccomp2:x32
cd /var/cache/apt/archives
wget
https://snapshot.debian.org/archive/debian/20161117T153728Z/pool/main/libs/libseccomp/libseccomp2_2.3.1-2.1_amd64.deb
dpkg -i libseccomp2_2.3.1-2.1_amd64.deb
dpkg -i gcc-8-base_8.3.0-3_x32.deb zlib1g_1%3a1.2.11.dfsg-1_x32.deb lib*_x32.deb
dpkg --install /var/cache/apt/archives/*_x32.deb
dpkg --get-selections | grep :amd64 | sed -e s/:amd64/:x32/ | dpkg
--set-selections
apt-get -f install
apt autoremove --purge
dpkg -l | grep -i :amd64 | awk '{ print $2 }' | grep -v -E "linux-image" | sed
's/:amd64/:x32/g' | xargs echo apt install
apt install apparmor:x32 aspell:x32 base-files:x32 base-passwd:x32 bash:x32
bind9-host:x32 bsdmainutils:x32 bsdutils:x32 busybox:x32 bzip2:x32
coreutils:x32 cpio:x32 cron:x32 dash:x32 dbus:x32 debianutils:x32 diffutils:x32
discover:x32 dmeventd:x32 dmidecode:x32 dmsetup:x32 e2fsprogs:x32 eject:x32
fdisk:x32 file:x32 findutils:x32 gcc-8-base:x32 gettext-base:x32 gpgv:x32
grep:x32 groff-base:x32 grub-common:x32 grub-pc:x32 grub-pc-bin:x32
grub2-common:x32 gzip:x32 hdparm:x32 hostname:x32 ifupdown:x32 init:x32
iproute2:x32 iptables:x32 iputils-ping:x32 irqbalance:x32 isc-dhcp-client:x32
isc-dhcp-common:x32 ispell:x32 klibc-utils:x32 kmod:x32 less:x32 libacl1:x32
libaio1:x32 libapparmor1:x32 libapt-inst2.0:x32 libapt-pkg5.0:x32
libargon2-1:x32 libaspell15:x32 libattr1:x32 libaudit1:x32 libbind9-161:x32
libblkid1:x32 libbsd0:x32 libbz2-1.0:x32 libc6:x32 libcap-ng0:x32 libcap2:x32
libcap2-bin:x32 libcom-err2:x32 libcryptsetup12:x32 libdb5.3:x32
libdbus-1-3:x32 libdebconfclient0:x32 libdevmapper-event1.02.1:x32
libdevmapper1.02.1:x32 libdiscover2:x32 libdns-export1104:x32 libdns1104:x32
libedit2:x32 libefiboot1:x32 libefivar1:x32 libelf1:x32 libestr0:x32
libexpat1:x32 libext2fs2:x32 libfastjson4:x32 libfdisk1:x32 libffi6:x32
libfreetype6:x32 libfstrm0:x32 libfuse2:x32 libgcc1:x32 libgcrypt20:x32
libgdbm6:x32 libgeoip1:x32 libglib2.0-0:x32 libgmp10:x32 libgnutls30:x32
libgpg-error0:x32 libgssapi-krb5-2:x32 libhogweed4:x32 libicu63:x32
libidn11:x32 libidn2-0:x32 libip4tc0:x32 libip6tc0:x32 libiptc0:x32
libisc-export1100:x32 libisc1100:x32 libisccc161:x32 libisccfg163:x32
libjson-c3:x32 libk5crypto3:x32 libkeyutils1:x32 libklibc:x32 libkmod2:x32
libkrb5-3:x32 libkrb5support0:x32 liblmdb0:x32 liblockfile-bin:x32
liblognorm5:x32 liblvm2cmd2.03:x32 liblwres161:x32 liblz4-1:x32 liblzma5:x32
libmagic-mgc:x32 libmagic1:x32 libmnl0:x32 libmount1:x32 libncurses6:x32
libncursesw6:x32 libnetfilter-conntrack3:x32 libnettle6:x32 libnewt0.52:x32
libnfnetlink0:x32 libnftnl11:x32 libnss-systemd:x32 libnuma1:x32
libp11-kit0:x32 libpam-modules:x32 libpam-modules-bin:x32 libpam-systemd:x32
libpam0g:x32 libpci3:x32 libpcre2-8-0:x32 libpcre3:x32 libpipeline1:x32
libpng16-16:x32 libpopt0:x32 libprocps7:x32 libprotobuf-c1:x32 libpsl5:x32
libpython-stdlib:x32 libpython2-stdlib:x32 libpython2.7-minimal:x32
libpython2.7-stdlib:x32 libreadline5:x32 libreadline7:x32 libseccomp2:x32
libselinux1:x32 libsemanage1:x32 libsepol1:x32 libslang2:x32 libsmartcols1:x32
libsqlite3-0:x32 libss2:x32 libssl1.1:x32 libstdc++6:x32 libsystemd0:x32
libtasn1-6:x32 libtinfo6:x32 libuchardet0:x32 libudev1:x32 libunistring2:x32
libusb-1.0-0:x32 libuuid1:x32 libwrap0:x32 libx11-6:x32 libxau6:x32 libxcb1:x32
libxdmcp6:x32 libxext6:x32 libxml2:x32 libxmuu1:x32 libxtables12:x32
libzstd1:x32 login:x32 logrotate:x32 lsof:x32 man-db:x32 mawk:x32 mount:x32
nano:x32 ncurses-bin:x32 netcat-traditional:x32 openssh-client:x32
openssh-server:x32 openssh-sftp-server:x32 openssl:x32 os-prober:x32 passwd:x32
pciutils:x32 perl:x32 procps:x32 python:x32 python-minimal:x32 python2:x32
python2-minimal:x32 python2.7:x32 python2.7-minimal:x32 rsyslog:x32 sed:x32
shared-mime-info:x32 systemd:x32 systemd-sysv:x32 sysvinit-utils:x32 telnet:x32
thin-provisioning-tools:x32 traceroute:x32 udev:x32 usbutils:x32 util-linux:x32
vim-tiny:x32 wget:x32 whiptail:x32 xauth:x32 xdg-user-dirs:x32 xxd:x32
xz-utils:x32 zlib1g:x32
Ja, tue was ich sage!
apt install -f
nano /etc/apt/sources.list.d/buster-approx.list
# disable deb amd64
apt update
apt-show-versions | grep No | awk '{print $1}' | grep -v -E "linux-image" |
xargs dpkg --purge
nano /etc/apt/sources.list.d/buster-approx.list
# enable deb amd64
#############
apt install dpkg-dev devscripts
# from
https://buildd.debian.org/status/fetch.php?pkg=mksh&arch=x32&ver=57-1&stamp=1551461619&raw=0
apt install autoconf automake autopoint autotools-dev bsdmainutils debhelper
dh-autoreconf dh-strip-nondeterminism dietlibc-dev dwz ed file gettext
gettext-base groff-base intltool-debian libarchive-zip-perl libbsd0 libc-l10n
libcroco3 libelf1 libfile-stripnondeterminism-perl libglib2.0-0 libicu63
libklibc libklibc-dev libmagic-mgc libmagic1 libncurses6 libpipeline1
libsigsegv2 libtool libuchardet0 libxml2 locales m4 man-db po-debconf
sensible-utils
mkdir /tmp/source/dietlibc/orig -p
cd /tmp/source/dietlibc/orig
apt source dietlibc
cd
mkdir /tmp/source/mksh/orig -p
cd /tmp/source/mksh/orig
apt source mksh
cd
cd /tmp/source/mksh
cp orig try1 -a
cd try1/mksh-57
dpkg-buildpackage -b
dpkg -i /tmp/source/mksh/try1/*.deb
benutzer@debian:/tmp/source/mksh/try1$ LANG=C /usr/lib/diet/bin/mksh
$ ls notexisting
ls: cannot access 'notexisting': No such file or directory
smashed stack detected, program terminated.
apt install systemd-coredump gdb
##################
benutzer@debian:/tmp/source/mksh/try1$ LANG=C /usr/lib/diet/bin/mksh
$
benutzer@debian:~$ gdb -q --pid $(pidof mksh)
Attaching to process 26325
Reading symbols from /usr/lib/diet/bin/mksh...Reading symbols from
/usr/lib/debug/.build-id/fc/c29d2d80c071be01063254db1a2ee14ae20fa4.debug...done.
done.
0x004253e0 in __unified_syscall ()
(gdb) b exit
Breakpoint 1 at 0x4253cf
(gdb) cont
Continuing.
[Detaching after fork from child process 26332]
Breakpoint 1, 0x004253cf in exit ()
(gdb) bt
#0 0x004253cf in exit ()
#1 0x00425e98 in __stack_chk_fail ()
#2 0x004138fc in j_sigchld (sig=<optimized out>) at ../../jobs.c:1422
#3 0x00411883 in trapsig (i=<optimized out>) at ../../histrap.c:1239
#4 <signal handler called>
#5 0x00000033 in ?? ()
Backtrace stopped: Cannot access memory at address 0x206
###################
benutzer@debian:/tmp/source/mksh/try1$ LANG=C /usr/lib/diet/bin/mksh
$
benutzer@debian:~$ gdb -q --pid $(pidof mksh)
Attaching to process 26344
Reading symbols from /usr/lib/diet/bin/mksh...Reading symbols from
/usr/lib/debug/.build-id/fc/c29d2d80c071be01063254db1a2ee14ae20fa4.debug...done.
done.
0x004253e0 in __unified_syscall ()
(gdb) b j_sigchld
Breakpoint 1 at 0x41380e: file ../../jobs.c, line 1322.
(gdb) display/i $pc
1: x/i $pc
=> 0x4253e0 <__unified_syscall+15>: cmp $0xffffffffffffff7c,%rax
(gdb) cont
Continuing.
[Detaching after fork from child process 26351]
Breakpoint 1, j_sigchld (sig=17) at ../../jobs.c:1322
1322 ../../jobs.c: Datei oder Verzeichnis nicht gefunden.
1: x/i $pc
=> 0x41380e <j_sigchld>: push %r15
(gdb) nexti
0x00413810 1322 in ../../jobs.c
1: x/i $pc
=> 0x413810 <j_sigchld+2>: push %r14
(gdb)
0x00413812 1322 in ../../jobs.c
1: x/i $pc
=> 0x413812 <j_sigchld+4>: push %r13
(gdb)
0x00413814 1322 in ../../jobs.c
1: x/i $pc
=> 0x413814 <j_sigchld+6>: push %r12
(gdb)
0x00413816 1322 in ../../jobs.c
1: x/i $pc
=> 0x413816 <j_sigchld+8>: push %rbp
(gdb)
0x00413817 1322 in ../../jobs.c
1: x/i $pc
=> 0x413817 <j_sigchld+9>: push %rbx
(gdb)
0x00413818 1322 in ../../jobs.c
1: x/i $pc
=> 0x413818 <j_sigchld+10>: sub $0xd8,%esp
(gdb)
0x0041381e 1322 in ../../jobs.c
1: x/i $pc
=> 0x41381e <j_sigchld+16>: mov 0x1ba40(%rip),%edx # 0x42f264
<procpid>
(gdb)
0x00413824 1322 in ../../jobs.c
1: x/i $pc
=> 0x413824 <j_sigchld+22>: mov %fs:0x18,%eax
(gdb)
0x0041382c 1322 in ../../jobs.c
1: x/i $pc
=> 0x41382c <j_sigchld+30>: mov %eax,0xcc(%rsp)
(gdb)
0x00413833 1322 in ../../jobs.c
1: x/i $pc
=> 0x413833 <j_sigchld+37>: xor %eax,%eax
(gdb) print/x $eax
$1 = 0xd8c54a7a
(gdb) print/x $rsp
$2 = 0xffb35be0
(gdb) print/x $rsp + 0xcc
$3 = 0xffb35cac
(gdb) x/1xd 0xffb35cac
0xffb35cac: -658158982
(gdb) x/1xx 0xffb35cac
0xffb35cac: 0xd8c54a7a
(gdb) set can-use-hw-watchpoints false
No symbol "false" in current context.
(gdb) set can-use-hw-watchpoints 0
(gdb) watch *0xffb35cac
Watchpoint 2: *0xffb35cac
(gdb) cont
Continuing.
Watchpoint 2: *0xffb35cac
Old value = -658158982
New value = 0
0x004253e0 in __unified_syscall ()
1: x/i $pc
=> 0x4253e0 <__unified_syscall+15>: cmp $0xffffffffffffff7c,%rax
(gdb) bt
#0 0x004253e0 in __unified_syscall ()
#1 0x004138aa in j_sigchld (sig=<optimized out>) at ../../jobs.c:1369
#2 0x00411883 in trapsig (i=<optimized out>) at ../../histrap.c:1239
#3 <signal handler called>
#4 0x00000033 in ?? ()
Backtrace stopped: Cannot access memory at address 0x206
(gdb) disassemble $pc-0x20,$pc+x020
No symbol "x020" in current context.
(gdb) disassemble $pc-0x20,$pc+0x20
Dump of assembler code from 0x4253c0 to 0x425400:
0x004253c0 <c_typeset+1518>: add %al,0x5d5b38c4(%rbx)
0x004253c6 <c_typeset+1524>: pop %r12
0x004253c8 <c_typeset+1526>: pop %r13
0x004253ca <c_typeset+1528>: pop %r14
0x004253cc <c_typeset+1530>: pop %r15
0x004253ce <c_typeset+1532>: retq
0x004253cf <exit+0>: mov $0x3c,%al
0x004253d1 <__unified_syscall+0>: mov $0x0,%ah
0x004253d3 <__unified_syscall+2>: movzwl %ax,%eax
0x004253d6 <__unified_syscall+5>: or $0x40000000,%eax
0x004253db <__unified_syscall+10>: mov %rcx,%r10
0x004253de <__unified_syscall+13>: syscall
=> 0x004253e0 <__unified_syscall+15>: cmp $0xffffffffffffff7c,%rax
0x004253e6 <__unified_syscall+21>: jbe 0x4253f7 <__unified_syscall+38>
0x004253e8 <__unified_syscall+23>: neg %eax
0x004253ea <__unified_syscall+25>: push %rax
0x004253eb <__unified_syscall+26>: callq 0x425834 <__errno_location>
0x004253f0 <__unified_syscall+31>: pop %rcx
0x004253f1 <__unified_syscall+32>: mov %ecx,(%rax)
0x004253f3 <__unified_syscall+34>: or $0xffffffffffffffff,%rax
0x004253f7 <__unified_syscall+38>: retq
0x004253f8 <access+0>: mov $0x15,%al
0x004253fa <access+2>: jmpq 0x4253d1 <__unified_syscall>
0x004253ff <alarm+0>: mov $0x25,%al
End of assembler dump.
(gdb) directory /tmp/source/mksh/try1/mksh-57/debian/upstream
Source directories searched:
/tmp/source/mksh/try1/mksh-57/debian/upstream:$cdir:$cwd
(gdb) up
#1 0x004138aa in j_sigchld (sig=<optimized out>) at ../../jobs.c:1369
1369 getrusage(RUSAGE_CHILDREN, &ru1);
(gdb) list jobs.c:1314,1370
1314 /*
1315 * SIGCHLD handler to reap children and update job states
1316 *
1317 * If jobs are compiled in then this routine expects sigchld to be
blocked.
1318 */
1319 /* ARGSUSED */
1320 static void
1321 j_sigchld(int sig MKSH_A_UNUSED)
1322 {
1323 int saved_errno = errno;
1324 Job *j;
1325 Proc *p = NULL;
1326 pid_t pid;
1327 int status;
1328 struct rusage ru0, ru1;
1329 #ifdef MKSH_NO_SIGSUSPEND
1330 sigset_t omask;
1331
1332 /* this handler can run while SIGCHLD is not blocked, so block
it now */
1333 sigprocmask(SIG_BLOCK, &sm_sigchld, &omask);
1334 #endif
1335
1336 #ifndef MKSH_NOPROSPECTOFWORK
1337 /*
1338 * Don't wait for any processes if a job is partially started.
1339 * This is so we don't do away with the process group leader
1340 * before all the processes in a pipe line are started (so the
1341 * setpgid() won't fail)
1342 */
1343 for (j = job_list; j; j = j->next)
1344 if (j->ppid == procpid && !(j->flags & JF_STARTED)) {
1345 held_sigchld = 1;
1346 goto j_sigchld_out;
1347 }
1348 #endif
1349
1350 getrusage(RUSAGE_CHILDREN, &ru0);
1351 do {
1352 #ifndef MKSH_NOPROSPECTOFWORK
1353 pid = waitpid(-1, &status, (WNOHANG |
1354 #if defined(WCONTINUED) && defined(WIFCONTINUED)
1355 WCONTINUED |
1356 #endif
1357 WUNTRACED));
1358 #else
1359 pid = wait(&status);
1360 #endif
1361
1362 /*
1363 * return if this would block (0) or no children
1364 * or interrupted (-1)
1365 */
1366 if (pid <= 0)
1367 goto j_sigchld_out;
1368
1369 getrusage(RUSAGE_CHILDREN, &ru1);
1370
(gdb) disassemble $pc-0x20,$pc+0x20
Dump of assembler code from 0x41388a to 0x4138ca:
0x0041388a <j_sigchld+124>: mov %esi,%esi
0x0041388c <j_sigchld+126>: or $0xffffffff,%edi
0x0041388f <j_sigchld+129>: callq 0x425542 <waitpid>
0x00413894 <j_sigchld+134>: mov %eax,%r13d
0x00413897 <j_sigchld+137>: test %eax,%eax
0x00413899 <j_sigchld+139>: jle 0x4138cd <j_sigchld+191>
0x0041389b <j_sigchld+141>: lea 0x70(%rsp),%esi
0x0041389f <j_sigchld+145>: or $0xffffffff,%edi
0x004138a2 <j_sigchld+148>: mov %rsi,%rbp
0x004138a5 <j_sigchld+151>: callq 0x42546a <getrusage>
=> 0x004138aa <j_sigchld+156>: mov 0x1ab50(%rip),%ebx # 0x42e400
<job_list>
0x004138b0 <j_sigchld+162>: test %ebx,%ebx
0x004138b2 <j_sigchld+164>: je 0x4138fc <j_sigchld+238>
0x004138b4 <j_sigchld+166>: mov 0x4(%ebx),%eax
0x004138b8 <j_sigchld+170>: test %eax,%eax
0x004138ba <j_sigchld+172>: je 0x4138c8 <j_sigchld+186>
0x004138bc <j_sigchld+174>: cmp %r13d,0x4(%eax)
0x004138c1 <j_sigchld+179>: je 0x41390e <j_sigchld+256>
0x004138c3 <j_sigchld+181>: mov (%eax),%eax
0x004138c6 <j_sigchld+184>: jmp 0x4138b8 <j_sigchld+170>
0x004138c8 <j_sigchld+186>: mov (%ebx),%ebx
End of assembler dump.
(gdb) print sizeof(ru0)
$4 = 88
(gdb) print sizeof(ru1)
$5 = 88
(gdb) print sizeof(ru1.ru_maxrss)
$6 = 4
(gdb) disassemble getrusage
Dump of assembler code for function getrusage:
0x0042546a <+0>: mov $0x62,%al
0x0042546c <+2>: jmpq 0x4253d1 <__unified_syscall>
End of assembler dump.
http://www.fefe.de/dietlibc/
http://man7.org/linux/man-pages/man2/getrusage.2.html