Dear Maintainer,
I tried to debug this issue.
(gdb) bt
#0 tidy_path (path=0x55f0c81ea140 "/../") at symlinks.c:96
#1 0x55f0c7fe6908 in fix_symlink (my_dev=2049, path=0x55f0c81ec1e0
"/tmp/tmp.tlVVwIgOZQ/mylink") at symlinks.c:185
#2 0x55f0c7fe6e81 in dirwalk (pathlen=, dev=2049,
path=0x55f0c81ec1e0 "/tmp/tmp.tlVVwIgOZQ/mylink") at symlinks.c:290
#3 0x55f0c7fe5f1d in main (argc=, argv=0x7ffd5d3596f0)
at symlinks.c:376
I guess I found a buffer underrun in following lines:
76 static int tidy_path (char *path)
...
91 while ((p = strstr(path,"/../")) != NULL) {
92 s = p+3;
93 for (p--; p != path; p--) if (*p == '/') break;
In line 93 p equals path already but is decremented before the
condition 'p != path' is checked the first time.
Therefore this loop is just ended when the first '/' is found
before the begin of the path variable, which is "luckily" in our
case in the .rodata section of the executable, to that we want
to write in line 96.
This modification makes symlinks not crash and shows plausible output:
- for (p--; p != path; p--) if (*p == '/') break;
+ for (p--; p > path; p--) if (*p == '/') break;
Kind regards,
Bernhard
# Buster/stable amd64 qemu VM 2020-02-16
apt update
apt dist-upgrade
apt install systemd-coredump mc fakeroot symlinks gdb symlinks-dbgsym
apt build-dep symlinks
mkdir /home/benutzer/source/symlinks/orig -p
cd/home/benutzer/source/symlinks/orig
apt source symlinks
cd
cat < reproduce.sh
#! /usr/bin/env sh
MYTMP=\$(mktemp -d)
ln -s /.. \$MYTMP/mylink
symlinks \$MYTMP
EOF
chmod +x reproduce.sh
./reproduce.sh
journalctl --no-pager
coredumpctl list
coredumpctl gdb 1443
set width 0
set pagination off
directory /home/benutzer/source/symlinks/orig/symlinks-1.4
bt
###
###
###
benutzer@debian:~$ ./reproduce.sh
Segmentation fault (core dumped)
root@debian:~# journalctl --no-pager
...
Feb 17 23:49:17 debian kernel: symlinks[1443]: segfault at 55f0c81e70ed ip
55f0c7fe675a sp 7ffd5d359360 error 7 in symlinks[55f0c7fe5000+3000]
Feb 17 23:49:17 debian kernel: Code: 1d 0f 1f 80 00 00 00 00 80 3a 2f 74 11 48
83 ea 01 48 39 d5 75 f2 48 89 ea 80 3a 2f 75 29 31 c9 0f b6 74 08 03 bb 01 00
00 00 <40> 88 34 0a 48 83 c1 01 40 84 f6 75 e9 4c 89 e6 48 89 ef e8 0e f6
Feb 17 23:49:17 debian systemd[1]: Created slice
system-systemd\x2dcoredump.slice.
Feb 17 23:49:17 debian systemd[1]: Started Process Core Dump (PID 1444/UID 0).
Feb 17 23:49:17 debian systemd-coredump[1445]: Process 1443 (symlinks) of user
1000 dumped core.
Stack trace of thread 1443:
#0 0x55f0c7fe675a n/a
(symlinks)
#1 0x55f0c7fe6908 n/a
(symlinks)
#2 0x55f0c7fe6e81 n/a
(symlinks)
#3 0x55f0c7fe5f1d n/a
(symlinks)
#4 0x7fea02a9f09b
__libc_start_main (libc.so.6)
#5 0x55f0c7fe61da n/a
(symlinks)
Feb 17 23:49:17 debian systemd[1]: systemd-coredump@0-1444-0.service: Succeeded.
https://wiki.debian.org/InterpretingKernelOutputAtProcessCrash
error 7 == 0b111
* bit 0 ==1: protection fault
* bit 1 ==1: write access
* bit 2 ==1: user-mode access
root@debian:~# coredumpctl list
TIMEPID UID GID SIG COREFILE EXE
Mon 2020-02-17 23:49:17 CET1443 1000 1000 11 present /usr/bin/symlinks
root@debian:~# coredumpctl gdb 1443
PID: 1443 (symlinks)
UID: 1000 (benutzer)
GID: 1000 (benutzer)
Signal: 11 (SEGV)
Timestamp: Mon 2020-02-17 23:49:17 CET (1min 25s ago)
Command Line: symlinks /tmp/tmp.tlVVwIgOZQ
Executable: /usr/bin/symlinks
Control Group: /user.slice/user-1000.slice/session-3.scope
Unit: session-3.scope
Slice: user-1000.slice
Session: 3
Owner UID: 1000 (benutzer)
Boot ID: 2d5d5576a57947a7aad042da5f907289
Machine ID: 33f18f39d2a9438eb75b0ed52848afcd
Hostname: debian
Storage:
/var/lib/systemd/coredump/core.symlinks.1000.2d5d5576a57947a7aad042da5f907289.1443.158197975700.lz4
Message: Process 1443 (symlinks) of user 1000 dumped core.
Stack trace of thread 1443:
#0 0x55f0c7fe675a n/a (symlinks)
#1 0x55f0c7fe6908 n/a (symlinks)
#2 0x55f0c7fe6e81 n/a (symlinks)
#3 0x55f0c7fe5f1d n/a (symlinks)
#4 0x7fea02a9f09b __libc_start_main (libc.so.6)
#5 0x55f0c7fe61da n/a (symlinks)
GNU gdb