diff --git a/.gitignore b/.gitignore index 8caebef..f85e6ed 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ test-binary tests/fexecve tests/popen tests/system-uname +tests/readlink-proc-self-exe diff --git a/Makefile b/Makefile index 3fe778b..43f6ca6 100644 --- a/Makefile +++ b/Makefile @@ -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 $@ @@ -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: diff --git a/src/termux-readlink.c b/src/termux-readlink.c index 63a50d2..9edf2db 100644 --- a/src/termux-readlink.c +++ b/src/termux-readlink.c @@ -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); diff --git a/tests/popen.c b/tests/popen.c index 5126ed9..a5cbf20 100644 --- a/tests/popen.c +++ b/tests/popen.c @@ -1,10 +1,10 @@ #include 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; } diff --git a/tests/readlink-proc-self-exe.c b/tests/readlink-proc-self-exe.c new file mode 100644 index 0000000..465c024 --- /dev/null +++ b/tests/readlink-proc-self-exe.c @@ -0,0 +1,18 @@ +#define _DEFAULT_SOURCE +#include +#include +#include + +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; +} + diff --git a/tests/readlink-proc-self-exe.sh b/tests/readlink-proc-self-exe.sh new file mode 100755 index 0000000..18b3af7 --- /dev/null +++ b/tests/readlink-proc-self-exe.sh @@ -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 diff --git a/tests/readlink-proc-self-exe.sh-expected b/tests/readlink-proc-self-exe.sh-expected new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/tests/readlink-proc-self-exe.sh-expected @@ -0,0 +1 @@ +ok