summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Denton <mpdenton@chromium.org>2021-07-21 17:12:27 +0000
committerMichal Klocek <michal.klocek@qt.io>2022-06-02 17:42:08 +0000
commita7a23ccc69e6756e02583e6871cc37151d89a7c2 (patch)
tree07372a20028d37f4f6f756ef0641b11c278dcaef
parent7857ff290ab254a5a1fe2e85e146680448b4d46e (diff)
[Backport] 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. Backport review link: https://chromium-review.googlesource.com/c/chromium/src/+/2823150 Task-number: QTBUG-103969 Change-Id: I75c5a52fa9cc142102d38ddbeb38019961ec6b22 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc11
-rw-r--r--chromium/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc1
-rw-r--r--chromium/sandbox/linux/system_headers/linux_stat.h4
3 files changed, 16 insertions, 0 deletions
diff --git a/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc b/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc
index 009197eefbe..5e650d93c4b 100644
--- a/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc
+++ b/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc
@@ -271,6 +271,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/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc b/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc
index 2c7a9e8351b..d1ea8e99a1c 100644
--- a/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc
+++ b/chromium/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc
@@ -154,6 +154,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/chromium/sandbox/linux/system_headers/linux_stat.h b/chromium/sandbox/linux/system_headers/linux_stat.h
index 83b89efc75e..e697dd6777e 100644
--- a/chromium/sandbox/linux/system_headers/linux_stat.h
+++ b/chromium/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.