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));