Ensure that readlink has access to /proc/self/fd

/proc/self/fd is not available when PR_DUMPABLE is set to 0
which is default for the user builds. It leads to permission
denials on readlink.

This change fixes the problem by setting PR_DUMPABLE flag to 1
for readlink and restoring it's previous value after the call.

Bug: http://b/24912743
Change-Id: I3fd179c5c6b56af96d6a15ee597024ccb15e1a13
diff --git a/linker/linker.cpp b/linker/linker.cpp
index c99042f..d3ac1d0 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -37,6 +37,7 @@
 #include <string.h>
 #include <sys/mman.h>
 #include <sys/param.h>
+#include <sys/prctl.h>
 #include <unistd.h>
 
 #include <new>
@@ -317,6 +318,13 @@
 static bool realpath_fd(int fd, std::string* realpath) {
   std::vector<char> buf(PATH_MAX), proc_self_fd(PATH_MAX);
   snprintf(&proc_self_fd[0], proc_self_fd.size(), "/proc/self/fd/%d", fd);
+  // set DUMPABLE to 1 to access /proc/self/fd
+  int dumpable = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0);
+  prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
+  auto guard = make_scope_guard([&]() {
+    // restore dumpable
+    prctl(PR_SET_DUMPABLE, dumpable, 0, 0, 0);
+  });
   if (readlink(&proc_self_fd[0], &buf[0], buf.size()) == -1) {
     PRINT("readlink('%s') failed: %s [fd=%d]", &proc_self_fd[0], strerror(errno), fd);
     return false;