summaryrefslogtreecommitdiff
path: root/libsanitizer/sanitizer_common/sanitizer_linux.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libsanitizer/sanitizer_common/sanitizer_linux.cc')
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_linux.cc36
1 files changed, 32 insertions, 4 deletions
diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.cc b/libsanitizer/sanitizer_common/sanitizer_linux.cc
index 3d3aa0b00bd..06e5a0a6441 100644
--- a/libsanitizer/sanitizer_common/sanitizer_linux.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_linux.cc
@@ -138,6 +138,11 @@ int internal_sched_yield() {
return syscall(__NR_sched_yield);
}
+void internal__exit(int exitcode) {
+ syscall(__NR_exit_group, exitcode);
+ Die(); // Unreachable.
+}
+
// ----------------- sanitizer_common.h
bool FileExists(const char *filename) {
#if SANITIZER_LINUX_USES_64BIT_SYSCALLS
@@ -232,6 +237,21 @@ const char *GetEnv(const char *name) {
return 0; // Not found.
}
+#ifdef __GLIBC__
+
+extern "C" {
+ extern void *__libc_stack_end;
+}
+
+static void GetArgsAndEnv(char ***argv, char ***envp) {
+ uptr *stack_end = (uptr *)__libc_stack_end;
+ int argc = *stack_end;
+ *argv = (char**)(stack_end + 1);
+ *envp = (char**)(stack_end + argc + 2);
+}
+
+#else // __GLIBC__
+
static void ReadNullSepFileToArray(const char *path, char ***arr,
int arr_size) {
char *buff;
@@ -251,12 +271,20 @@ static void ReadNullSepFileToArray(const char *path, char ***arr,
(*arr)[count] = 0;
}
+static void GetArgsAndEnv(char ***argv, char ***envp) {
+ static const int kMaxArgv = 2000, kMaxEnvp = 2000;
+ ReadNullSepFileToArray("/proc/self/cmdline", argv, kMaxArgv);
+ ReadNullSepFileToArray("/proc/self/environ", envp, kMaxEnvp);
+}
+
+#endif // __GLIBC__
+
void ReExec() {
- static const int kMaxArgv = 100, kMaxEnvp = 1000;
char **argv, **envp;
- ReadNullSepFileToArray("/proc/self/cmdline", &argv, kMaxArgv);
- ReadNullSepFileToArray("/proc/self/environ", &envp, kMaxEnvp);
- execve(argv[0], argv, envp);
+ GetArgsAndEnv(&argv, &envp);
+ execve("/proc/self/exe", argv, envp);
+ Printf("execve failed, errno %d\n", errno);
+ Die();
}
void PrepareForSandboxing() {