Merge "profiling: override dumpability while opening /proc/self/mem,maps"
diff --git a/libc/bionic/android_profiling_dynamic.cpp b/libc/bionic/android_profiling_dynamic.cpp
index 4fafd67..3460a6d 100644
--- a/libc/bionic/android_profiling_dynamic.cpp
+++ b/libc/bionic/android_profiling_dynamic.cpp
@@ -33,6 +33,7 @@
#include <fcntl.h>
#include <signal.h>
#include <string.h>
+#include <sys/prctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -137,13 +138,25 @@
return;
}
+ // If the process is undumpable, /proc/self/mem will be owned by root:root, and therefore
+ // inaccessible to the process itself (see man 5 proc). We temporarily mark the process as
+ // dumpable to allow for the open. Note: prctl is not async signal safe per posix, but bionic's
+ // implementation is. Error checking on prctls is omitted due to them being trivial.
+ int orig_dumpable = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0);
+ if (!orig_dumpable) {
+ prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
+ }
ScopedFd maps_fd{ open("/proc/self/maps", O_RDONLY | O_CLOEXEC) };
+ ScopedFd mem_fd{ open("/proc/self/mem", O_RDONLY | O_CLOEXEC) };
+ if (!orig_dumpable) {
+ prctl(PR_SET_DUMPABLE, orig_dumpable, 0, 0, 0);
+ }
+
if (maps_fd.get() == -1) {
async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to open /proc/self/maps: %s",
strerror(errno));
return;
}
- ScopedFd mem_fd{ open("/proc/self/mem", O_RDONLY | O_CLOEXEC) };
if (mem_fd.get() == -1) {
async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to open /proc/self/mem: %s",
strerror(errno));