Skip to content

Commit

Permalink
Apply realpath(3) when hooking readlink("/proc/self/exe")
Browse files Browse the repository at this point in the history
  • Loading branch information
fornwall committed Sep 18, 2024
1 parent 9f701ad commit df8a21c
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 7 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ test-binary
tests/fexecve
tests/popen
tests/system-uname
tests/readlink-proc-self-exe
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ tests/popen: tests/popen.c
tests/system-uname: tests/system-uname.c
$(CC) $(CFLAGS) -DTERMUX_BASE_DIR=\"$(TERMUX_BASE_DIR)\" $< -o $@

tests/readlink-proc-self-exe: tests/readlink-proc-self-exe.c
$(CC) $(CFLAGS) -DTERMUX_BASE_DIR=\"$(TERMUX_BASE_DIR)\" $< -o $@

$(TERMUX_BASE_DIR)/usr/bin/termux-exec-test-print-argv0: tests/print-argv0.c
$(CC) $(CFLAGS) $< -o $@

Expand All @@ -43,7 +46,7 @@ on-device-tests:
make clean
ASAN_OPTIONS=symbolize=0,detect_leaks=0 make on-device-tests-internal

on-device-tests-internal: libtermux-exec.so tests/fexecve tests/popen tests/system-uname $(TERMUX_BASE_DIR)/usr/bin/termux-exec-test-print-argv0
on-device-tests-internal: libtermux-exec.so tests/fexecve tests/popen tests/system-uname tests/readlink-proc-self-exe $(TERMUX_BASE_DIR)/usr/bin/termux-exec-test-print-argv0
@LD_PRELOAD=${CURDIR}/libtermux-exec.so ./run-tests.sh

format:
Expand Down
5 changes: 5 additions & 0 deletions src/termux-readlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ __attribute__((visibility("default"))) ssize_t readlink(const char *restrict pat
if (strcmp(pathname, "/proc/self/exe") == 0) {
const char *termux_self_exe = getenv("TERMUX_EXEC__PROC_SELF_EXE");
if (termux_self_exe) {
char resolved_path_buf[PATH_MAX];
char *resolved_path = realpath(termux_self_exe, resolved_path_buf);
if (resolved_path) {
termux_self_exe = resolved_path_buf;
}
size_t termux_self_exe_len = strlen(termux_self_exe);
size_t bytes_to_copy = (termux_self_exe_len < bufsiz) ? termux_self_exe_len : bufsiz;
memcpy(buf, termux_self_exe, bytes_to_copy);
Expand Down
12 changes: 6 additions & 6 deletions tests/popen.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#include <stdio.h>

int main() {
FILE* file = popen("uname", "r");
char buffer[101];
fscanf(file, "%100s", buffer);
pclose(file);
printf("%s\n", buffer);
return 0;
FILE *file = popen("uname", "r");
char buffer[101];
fscanf(file, "%100s", buffer);
pclose(file);
printf("%s\n", buffer);
return 0;
}
18 changes: 18 additions & 0 deletions tests/readlink-proc-self-exe.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#define _DEFAULT_SOURCE
#include <linux/limits.h>
#include <stdio.h>
#include <unistd.h>

int main() {
char buf[PATH_MAX + 1];

ssize_t res = readlink("/proc/self/exe", buf, PATH_MAX);
if (res < 0) {
perror("readlink()");
return 1;
}
buf[res] = 0;
printf("%s\n", buf);
return 0;
}

33 changes: 33 additions & 0 deletions tests/readlink-proc-self-exe.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
TMPDIR=$(mktemp -d)

cp tests/readlink-proc-self-exe $TMPDIR

cd $TMPDIR

ACTUAL_PATH_TO_SELF=$(./readlink-proc-self-exe)
EXPECTED_PATH_TO_SELF=$TMPDIR/readlink-proc-self-exe

if [ "$ACTUAL_PATH_TO_SELF" != "$EXPECTED_PATH_TO_SELF" ]; then
echo "ERROR(1): Expected '$EXPECTED_PATH_TO_SELF', was '$ACTUAL_PATH_TO_SELF'"
exit 1
fi

ln -s readlink-proc-self-exe symlinked-binary
ACTUAL_PATH_TO_SELF=$(./symlinked-binary)
if [ "$ACTUAL_PATH_TO_SELF" != "$EXPECTED_PATH_TO_SELF" ]; then
echo "ERROR(2): Expected '$EXPECTED_PATH_TO_SELF', was '$ACTUAL_PATH_TO_SELF'"
exit 1
fi

ln -s symlinked-binary nested-symlinked-binary
ACTUAL_PATH_TO_SELF=$(./nested-symlinked-binary)
if [ "$ACTUAL_PATH_TO_SELF" != "$EXPECTED_PATH_TO_SELF" ]; then
echo "ERROR(3): Expected '$EXPECTED_PATH_TO_SELF', was '$ACTUAL_PATH_TO_SELF'"
exit 1
fi

cd - > /dev/null

rm -rf $TMPDIR

echo ok
1 change: 1 addition & 0 deletions tests/readlink-proc-self-exe.sh-expected
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ok

0 comments on commit df8a21c

Please sign in to comment.