30
30
# error "unknown arch"
31
31
#endif
32
32
33
+ #define starts_with (value , str ) !strncmp(value, str, sizeof(str) - 1)
34
+
33
35
static const char * termux_rewrite_executable (const char * filename , char * buffer , int buffer_len )
34
36
{
37
+ if (starts_with (filename , TERMUX_BASE_DIR ) ||
38
+ starts_with (filename , "/system/" ))
39
+ return filename ;
40
+
35
41
strcpy (buffer , TERMUX_PREFIX "/bin/" );
36
42
char * bin_match = strstr (filename , "/bin/" );
37
43
if (bin_match == filename || bin_match == (filename + 4 )) {
@@ -66,7 +72,7 @@ static char*const * remove_ld_preload(char*const * envp)
66
72
return envp ;
67
73
}
68
74
69
- int execve (const char * filename , char * const * argv , char * const envp [] )
75
+ int execve (const char * filename , char * const * argv , char * const * envp )
70
76
{
71
77
bool android_10_debug = getenv ("TERMUX_ANDROID10_DEBUG" ) != NULL ;
72
78
if (android_10_debug ) {
@@ -80,6 +86,7 @@ int execve(const char* filename, char* const* argv, char *const envp[])
80
86
81
87
int fd = -1 ;
82
88
const char * * new_argv = NULL ;
89
+ const char * * new_envp = NULL ;
83
90
84
91
char filename_buffer [512 ];
85
92
filename = termux_rewrite_executable (filename , filename_buffer , sizeof (filename_buffer ));
@@ -90,6 +97,31 @@ int execve(const char* filename, char* const* argv, char *const envp[])
90
97
fd = open (filename , O_RDONLY );
91
98
if (fd == -1 ) goto final ;
92
99
100
+ // LD_LIBRARY_PATH messes up system programs with CANNOT_LINK_EXECUTABLE errors.
101
+ // If we remove.it, this problem is solved.
102
+ // /system/bin/sh is fine, it only uses libc++, libc, and libdl.
103
+ if (starts_with (filename , "/system/" ) && strcmp (filename , "/system/bin/sh" ) != 0 ) {
104
+
105
+ size_t envp_count = 0 ;
106
+ while (envp [envp_count ] != NULL )
107
+ envp_count ++ ;
108
+
109
+ new_envp = malloc ((envp_count + 1 ) * sizeof (char * ));
110
+
111
+ size_t pos = 0 ;
112
+ for (size_t i = 0 ; i < envp_count ; i ++ ) {
113
+ // Skip it if it is LD_LIBRARY_PATH or LD_PRELOAD
114
+ if (!starts_with (envp [i ], "LD_LIBRARY_PATH=" ) &&
115
+ !starts_with (envp [i ], "LD_PRELOAD=" ))
116
+ new_envp [pos ++ ] = (const char * )envp [i ];
117
+ }
118
+ new_envp [pos ] = NULL ;
119
+
120
+ envp = (char * * )new_envp ;
121
+ // Not.sure if needed.
122
+ environ = (char * * )new_envp ;
123
+ }
124
+
93
125
// execve(2): "A maximum line length of 127 characters is allowed
94
126
// for the first line in a #! executable shell script."
95
127
char header [128 ];
@@ -159,7 +191,7 @@ int execve(const char* filename, char* const* argv, char *const envp[])
159
191
160
192
final :
161
193
if (fd != -1 ) close (fd );
162
- int (* real_execve )(const char * , char * const [], char * const []) = dlsym (RTLD_NEXT , "execve" );
194
+ int (* real_execve )(const char * , char * const [], char * const []) = dlsym (RTLD_NEXT , "execve" );
163
195
164
196
bool android_10_wrapping = getenv ("TERMUX_ANDROID10" ) != NULL ;
165
197
if (android_10_wrapping ) {
@@ -201,5 +233,6 @@ int execve(const char* filename, char* const* argv, char *const envp[])
201
233
202
234
int ret = real_execve (filename , argv , envp );
203
235
free (new_argv );
236
+ free (new_envp );
204
237
return ret ;
205
238
}
0 commit comments