commit e378f44562245e675730580d935069112efe6864
parent 046ec69f081a6b24948dd8c48bc1030bb1194e23
Author: Jed Davis <jld@mozilla.com>
Date: Thu, 20 Nov 2025 16:13:58 +0000
Bug 1995035 - Allow `F_DUPFD_QUERY` in the Linux sandboxes. r=gcp
Differential Revision: https://phabricator.services.mozilla.com/D270797
Diffstat:
2 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/security/sandbox/common/test/SandboxTestingChildTests.h b/security/sandbox/common/test/SandboxTestingChildTests.h
@@ -88,6 +88,16 @@ extern "C" int sandbox_check(pid_t pid, const char* operation, int type, ...);
# define MFD_HUGE_2MB (21U << 26)
# endif
// (MAP_HUGE_* is from 3.8. MAP_HUGETLB is 2.6.32.)
+//
+// This constant is ancient, but the kernel header for it conflicts
+// with glibc's fcntl.h:
+# ifndef F_LINUX_SPECIFIC_BASE
+# define F_LINUX_SPECIFIC_BASE 1024
+# endif
+// Added in 6.10:
+# ifndef F_DUPFD_QUERY
+# define F_DUPFD_QUERY (F_LINUX_SPECIFIC_BASE + 3)
+# endif
#endif
constexpr bool kIsDebug =
@@ -157,6 +167,23 @@ static void RunGenericTests(SandboxTestingChild* child, bool aIsGMP = false) {
MOZ_RELEASE_ASSERT(flags & O_NONBLOCK);
}
}
+
+ if (!aIsGMP) {
+ constexpr auto name = "fcntl_dupfd_query"_ns;
+ int rv = fcntl(0, F_DUPFD_QUERY, 0);
+ // Expected:
+ // * success with rv == 1 (new kernel)
+ // * failure with EINVAL (old kernel)
+ // Rejected:
+ // * failure with ENOSYS or any other error
+ // * success with rv == 0 (shouldn't be possible)
+ MOZ_RELEASE_ASSERT(rv != 0);
+ if (rv > 0) {
+ child->PosixTest(name, true, 0);
+ } else { // (rv < 0), errno unchanged since fcntl
+ child->PosixTest(name, false, errno, Some(EINVAL));
+ }
+ }
#endif // XP_LINUX
}
diff --git a/security/sandbox/linux/SandboxFilter.cpp b/security/sandbox/linux/SandboxFilter.cpp
@@ -129,6 +129,13 @@ static_assert(MFD_HUGE_MASK == MAP_HUGE_MASK);
static_assert(MFD_HUGE_SHIFT == MAP_HUGE_SHIFT);
#endif
+// Added in 6.10
+#ifndef F_DUPFD_QUERY
+# define F_DUPFD_QUERY (F_LINUX_SPECIFIC_BASE + 3)
+#else
+static_assert(F_DUPFD_QUERY == (F_LINUX_SPECIFIC_BASE + 3));
+#endif
+
// To avoid visual confusion between "ifdef ANDROID" and "ifndef ANDROID":
#ifndef ANDROID
# define DESKTOP
@@ -1111,6 +1118,9 @@ class SandboxPolicyCommon : public SandboxPolicyBase {
#endif
// Not much different from other forms of dup(), and commonly used.
.Case(F_DUPFD_CLOEXEC, Allow())
+ // Used by Mesa, generally useful, and harmless: tests if
+ // two file descriptors refer to the same file description.
+ .Case(F_DUPFD_QUERY, Allow())
.Default(SandboxPolicyBase::EvaluateSyscall(sysno));
}