chromium-browser-stable/b2fbcdbe30cb84cd2f0b63e453f3782c49213264.patch

71 lines
3.1 KiB
Diff
Raw Normal View History

From b2fbcdbe30cb84cd2f0b63e453f3782c49213264 Mon Sep 17 00:00:00 2001
From: Matthew Denton <mpdenton@chromium.org>
Date: Wed, 21 Jul 2021 17:12:27 +0000
Subject: [PATCH] Linux sandbox: ENOSYS for some statx syscalls
On some platforms, glibc will default to statx for normal stat-family
calls. Unfortunately there's no way to rewrite statx to something safe
using a signal handler. Returning ENOSYS will cause glibc to fallback
to old stat paths.
Change-Id: Ieaddc8020b6555f2dfdc443197d13cb3fccc6bf1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2823150
Commit-Queue: Matthew Denton <mpdenton@chromium.org>
Reviewed-by: Robert Sesek <rsesek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#903952}
---
sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc | 11 +++++++++++
sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc | 1 +
sandbox/linux/system_headers/linux_stat.h | 4 ++++
3 files changed, 16 insertions(+)
diff --git a/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc b/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc
index 9df0d2dbd3b5f..049e921694eda 100644
--- a/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc
+++ b/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc
@@ -312,6 +312,17 @@ ResultExpr EvaluateSyscallImpl(int fs_denied_errno,
return RewriteFstatatSIGSYS(fs_denied_errno);
}
+ // The statx syscall is a filesystem syscall, which will be denied below with
+ // fs_denied_errno. However, on some platforms, glibc will default to statx
+ // for normal stat-family calls. Unfortunately there's no way to rewrite statx
+ // to something safe using a signal handler. Returning ENOSYS will cause glibc
+ // to fallback to old stat paths.
+ if (sysno == __NR_statx) {
+ const Arg<int> mask(3);
+ return If(mask == STATX_BASIC_STATS, Error(ENOSYS))
+ .Else(Error(fs_denied_errno));
+ }
+
if (SyscallSets::IsFileSystem(sysno) ||
SyscallSets::IsCurrentDirectory(sysno)) {
return Error(fs_denied_errno);
diff --git a/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc b/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc
index 96c9f490e28cd..8227dc1854643 100644
--- a/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc
+++ b/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc
@@ -171,6 +171,7 @@ bool SyscallSets::IsFileSystem(int sysno) {
(defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_32_BITS))
case __NR_statfs64:
#endif
+ case __NR_statx: // EPERM not a valid errno.
case __NR_symlinkat:
case __NR_truncate:
#if defined(__i386__) || defined(__arm__) || \
diff --git a/sandbox/linux/system_headers/linux_stat.h b/sandbox/linux/system_headers/linux_stat.h
index 83b89efc75e5e..e697dd6777ef5 100644
--- a/sandbox/linux/system_headers/linux_stat.h
+++ b/sandbox/linux/system_headers/linux_stat.h
@@ -161,6 +161,10 @@ struct kernel_stat {
#define AT_EMPTY_PATH 0x1000
#endif
+#if !defined(STATX_BASIC_STATS)
+#define STATX_BASIC_STATS 0x000007ffU
+#endif
+
// On 32-bit systems, we default to the 64-bit stat struct like libc
// implementations do. Otherwise we default to the normal stat struct which is
// already 64-bit.