1
1
#include <dlfcn.h>
2
+ #include <errno.h>
2
3
#include <fcntl.h>
3
4
#include <libgen.h>
5
+ #include <limits.h>
6
+ #include <stdbool.h>
4
7
#include <stdio.h>
5
8
#include <stdlib.h>
6
9
#include <string.h>
@@ -21,6 +24,16 @@ static const char* termux_rewrite_executable(const char* filename, char* buffer,
21
24
22
25
int execve (const char * filename , char * const * argv , char * const envp [])
23
26
{
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
+
24
37
int fd = -1 ;
25
38
const char * * new_argv = NULL ;
26
39
@@ -92,6 +105,64 @@ int execve(const char* filename, char* const* argv, char *const envp[])
92
105
final :
93
106
if (fd != -1 ) close (fd );
94
107
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
+
95
166
int ret = real_execve (filename , argv , envp );
96
167
free (new_argv );
97
168
return ret ;
0 commit comments