Skip to content

Commit 359b09e

Browse files
committed
fix(dalvikvm): bypass W^X restriction
termux/termux-packages#18557
1 parent 4c9ec4f commit 359b09e

File tree

4 files changed

+49
-0
lines changed

4 files changed

+49
-0
lines changed

configure.ac

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ AM_INIT_AUTOMAKE([foreign])
2929
AC_PROG_MAKE_SET
3030
AC_PROG_CC
3131
AC_LANG(C)
32+
LT_INIT
3233

3334
copyright="Copyright (C) 2022-2024 Termux."
3435
if test "${TERMUX_APP_PACKAGE+set}" = set; then

scripts/dalvikvm.in

+1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ else
1111
fi
1212

1313
unset LD_LIBRARY_PATH LD_PRELOAD
14+
export LD_PRELOAD=@TERMUX_PREFIX@/lib/termux/libtermux-access.so
1415
exec "$DALVIKVM" -Xusejit:true -Xnoimage-dex2oat -Djava.io.tmpdir=@TERMUX_PREFIX@/tmp "$@"

src/Makefile.am

+10
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,13 @@ AM_CFLAGS = -Wall -Wextra -pedantic
2121
bin_PROGRAMS = cmd
2222

2323
cmd_SOURCES = cmd.c
24+
25+
libdir = $(prefix)/lib/termux
26+
27+
lib_LTLIBRARIES = libtermux-access.la
28+
29+
libtermux_access_la_SOURCES = termux_access.c
30+
libtermux_access_la_LDFLAGS = -shared -module -avoid-version -ldl
31+
32+
clean-local:
33+
rm -f libtermux-access.la

src/termux_access.c

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#define _GNU_SOURCE
2+
#include <dlfcn.h>
3+
#include <string.h>
4+
#include <unistd.h>
5+
#include <errno.h>
6+
#include <stdio.h>
7+
8+
// This library is needed to bypass W^X restriction in Dalvik code.
9+
// https://cs.android.com/android/platform/superproject/+/dd6fde63193fda968440fc0a4cd9ccee5d282ab0:art/runtime/native/dalvik_system_DexFile.cc;l=381
10+
11+
static int stub_access(const char* __unused path, int __unused mode) {
12+
return -1;
13+
}
14+
15+
// Function pointer for the original access function
16+
static int (*orig_access)(const char *path, int mode) = stub_access;
17+
18+
// Constructor to load the original access function
19+
__attribute__((constructor, visibility("hidden")))
20+
static void load_orig_access(void) {
21+
orig_access = (int (*)(const char *, int))dlsym(RTLD_NEXT, "access");
22+
if (orig_access == NULL) {
23+
dprintf(2, "Error in `dlsym`: %s\n", dlerror());
24+
orig_access = stub_access;
25+
}
26+
}
27+
28+
int access(const char *path, int mode) {
29+
// Checking if path ends with ".apk", if ".apk" is an extension and if mode is W_OK
30+
const char *apk = path == NULL ? NULL : strstr(path, ".apk");
31+
if (mode == W_OK && apk != NULL && !strcmp(apk, ".apk"))
32+
return 1;
33+
34+
// Call the original access function for other cases
35+
return orig_access(path, mode);
36+
}
37+

0 commit comments

Comments
 (0)