Merge "Make 'app' users/groups more accurate"
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 32dce38..7bc3529 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -393,16 +393,23 @@
 }
 
 static bool realpath_fd(int fd, std::string* realpath) {
-  std::vector<char> buf(PATH_MAX), proc_self_fd(PATH_MAX);
-  async_safe_format_buffer(&proc_self_fd[0], proc_self_fd.size(), "/proc/self/fd/%d", fd);
-  if (readlink(&proc_self_fd[0], &buf[0], buf.size()) == -1) {
+  // proc_self_fd needs to be large enough to hold "/proc/self/fd/" plus an
+  // integer, plus the NULL terminator.
+  char proc_self_fd[32];
+  // We want to statically allocate this large buffer so that we don't grow
+  // the stack by too much.
+  static char buf[PATH_MAX];
+
+  async_safe_format_buffer(proc_self_fd, sizeof(proc_self_fd), "/proc/self/fd/%d", fd);
+  auto length = readlink(proc_self_fd, buf, sizeof(buf));
+  if (length == -1) {
     if (!is_first_stage_init()) {
-      PRINT("readlink(\"%s\") failed: %s [fd=%d]", &proc_self_fd[0], strerror(errno), fd);
+      PRINT("readlink(\"%s\") failed: %s [fd=%d]", proc_self_fd, strerror(errno), fd);
     }
     return false;
   }
 
-  *realpath = &buf[0];
+  realpath->assign(buf, length);
   return true;
 }