Bug 1673202 - Call fstat directly in Linux sandbox fstatat interception. r=gcp, a=RyanVM
authorJed Davis <jld@mozilla.com>
Tue, 27 Oct 2020 21:05:09 +0000
changeset 600199 13d5867b039948a79fa80fc2081a17b8089f1ed7
parent 600198 0322427df80a91fdeace25c1508105074dc8adad
child 600200 8a302b9b4d330625ed3d6740266e8b4c588e8885
push id127
push userryanvm@gmail.com
push dateMon, 16 Nov 2020 17:22:54 +0000
treeherdermozilla-esr78@13d5867b0399 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgcp, RyanVM
bugs1673202
milestone78.6.0
Bug 1673202 - Call fstat directly in Linux sandbox fstatat interception. r=gcp, a=RyanVM Sandbox policies handle the case of `fstatat(fd, "", AT_EMPTY_PATH|...)` by invoking the SIGSYS handler (because seccomp-bpf can't tell if the string will be empty when the syscall would use it), which makes the equivalent call to `fstat`. Unfortunately, recent development versions of glibc implement `fstat` by calling `fstatat`, which causes unbounded recursion and stack overflow. (This depends on the headers present at build time; see the bug for more details.) This patch switches it to use the `fstat` (or `fstat64` on 32-bit) syscall directly. Differential Revision: https://phabricator.services.mozilla.com/D94798
security/sandbox/linux/SandboxFilter.cpp
--- a/security/sandbox/linux/SandboxFilter.cpp
+++ b/security/sandbox/linux/SandboxFilter.cpp
@@ -241,17 +241,21 @@ class SandboxPolicyCommon : public Sandb
     auto broker = static_cast<SandboxBrokerClient*>(aux);
     auto fd = static_cast<int>(aArgs.args[0]);
     auto path = reinterpret_cast<const char*>(aArgs.args[1]);
     auto buf = reinterpret_cast<statstruct*>(aArgs.args[2]);
     auto flags = static_cast<int>(aArgs.args[3]);
 
     if (fd != AT_FDCWD && (flags & AT_EMPTY_PATH) != 0 &&
         strcmp(path, "") == 0) {
-      return ConvertError(fstatsyscall(fd, buf));
+#ifdef __NR_fstat64
+      return DoSyscall(__NR_fstat64, fd, buf);
+#else
+      return DoSyscall(__NR_fstat, fd, buf);
+#endif
     }
 
     if (fd != AT_FDCWD && path[0] != '/') {
       SANDBOX_LOG_ERROR("unsupported fd-relative fstatat(%d, \"%s\", %p, %d)",
                         fd, path, buf, flags);
       return BlockedSyscallTrap(aArgs, nullptr);
     }
     if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT)) != 0) {