Skip to content

Commit 1720bb2

Browse files
committed
Start android 10 proot wrapping experiment
1 parent d0ab142 commit 1720bb2

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

termux-exec.c

+71
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#include <dlfcn.h>
2+
#include <errno.h>
23
#include <fcntl.h>
34
#include <libgen.h>
5+
#include <limits.h>
6+
#include <stdbool.h>
47
#include <stdio.h>
58
#include <stdlib.h>
69
#include <string.h>
@@ -21,6 +24,16 @@ static const char* termux_rewrite_executable(const char* filename, char* buffer,
2124

2225
int execve(const char* filename, char* const* argv, char *const envp[])
2326
{
27+
bool android_10_debug = getenv("TERMUX_ANDROID10_DEBUG") != NULL;
28+
if (android_10_debug) {
29+
printf("execve(%s):\n", filename);
30+
int tmp_argv_count = 0;
31+
while (argv[tmp_argv_count] != NULL) {
32+
printf(" %s\n", argv[tmp_argv_count]);
33+
tmp_argv_count++;
34+
}
35+
}
36+
2437
int fd = -1;
2538
const char** new_argv = NULL;
2639

@@ -92,6 +105,64 @@ int execve(const char* filename, char* const* argv, char *const envp[])
92105
final:
93106
if (fd != -1) close(fd);
94107
int (*real_execve)(const char*, char *const[], char *const[]) = dlsym(RTLD_NEXT, "execve");
108+
109+
bool android_10_wrapping = getenv("TERMUX_ANDROID10") != NULL;
110+
if (android_10_wrapping) {
111+
char realpath_buffer[PATH_MAX];
112+
bool realpath_ok = realpath(filename, realpath_buffer) != NULL;
113+
if (realpath_ok) {
114+
bool wrap_in_proot = (strstr(realpath_buffer, "/data/data/com.termux/files") != NULL);
115+
if (android_10_debug) {
116+
printf("termux-exec: realpath(\"%s\") = \"%s\", wrapping=%s\n", filename, realpath_buffer, wrap_in_proot ? "yes" : "no");
117+
}
118+
if (wrap_in_proot) {
119+
orig_argv_count = 0;
120+
while (argv[orig_argv_count] != NULL) orig_argv_count++;
121+
122+
new_argv = malloc(sizeof(char*) * (2 + orig_argv_count));
123+
filename = "/data/data/com.termux/files/usr/bin/proot";
124+
new_argv[0] = "proot";
125+
for (int i = 0; i < orig_argv_count; i++) {
126+
new_argv[i + 1] = argv[i];
127+
}
128+
new_argv[orig_argv_count + 1] = NULL;
129+
argv = (char**) new_argv;
130+
131+
// Remove LD_PRELOAD environment variable when wrapping in proot:
132+
for (int i = 0; envp[i] != NULL; i++) {
133+
if (strstr(envp[i], "LD_PRELOAD=") == envp[i]) {
134+
int env_length = 0;
135+
while (envp[env_length] != NULL) env_length++;
136+
137+
char** new_envp = malloc(sizeof(char*) * env_length);
138+
int new_envp_idx = 0;
139+
int old_envp_idx = 0;
140+
while (old_envp_idx < env_length) {
141+
if (old_envp_idx != i) {
142+
new_envp[new_envp_idx++] = envp[old_envp_idx];
143+
}
144+
old_envp_idx++;
145+
}
146+
new_envp[env_length] = NULL;
147+
envp = new_envp;
148+
break;
149+
}
150+
}
151+
}
152+
} else {
153+
errno = 0;
154+
}
155+
156+
if (android_10_debug) {
157+
printf("real_execve(%s):\n", filename);
158+
int tmp_argv_count = 0;
159+
while (argv[tmp_argv_count] != NULL) {
160+
printf(" %s\n", argv[tmp_argv_count]);
161+
tmp_argv_count++;
162+
}
163+
}
164+
}
165+
95166
int ret = real_execve(filename, argv, envp);
96167
free(new_argv);
97168
return ret;

0 commit comments

Comments
 (0)