Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion vanadium_patches/0012-Checkout-PGO-profiles.patch
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Subject: [PATCH] Checkout PGO profiles
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/DEPS b/DEPS
index 76ea649d79e24..8ce0c6fd25774 100644
index f975c66c1d9ed..fd207091cb1b2 100644
--- a/DEPS
+++ b/DEPS
@@ -149,7 +149,7 @@ vars = {
Expand Down
2 changes: 1 addition & 1 deletion vanadium_patches/0013-disable-checkout_nacl.patch
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Subject: [PATCH] disable checkout_nacl
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/DEPS b/DEPS
index 8ce0c6fd25774..10f8c4dea1d90 100644
index fd207091cb1b2..373091d2151ab 100644
--- a/DEPS
+++ b/DEPS
@@ -118,7 +118,7 @@ vars = {
Expand Down
150 changes: 150 additions & 0 deletions vanadium_patches/0192-Support-restriction-of-dynamic-code.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: qua3k <qua3kr@gmail.com>
Date: Thu, 4 Nov 2021 00:00:00 +0000
Subject: [PATCH] Support restriction of dynamic code

This patchset is ported from Hexavalent Browser, authored by qua3k,
intended to restrict dynamic code generation on Android.

Original description from Hexavalent:

This commit has three parts, utilizing seccomp-bpf to prevent:

1. the creation of executable anonymous mappings
2. the creation of writable and executable file mappings
3. making a non-executable mapping executable

It's inspired by PaX MPROTECT restrictions.
---
.../syscall_parameters_restrictions.cc | 55 +++++++++++++++++++
.../syscall_parameters_restrictions.h | 18 ++++++
2 files changed, 73 insertions(+)

diff --git a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc
index bb0e13f4d2d9c..318eb4d55f3b2 100644
--- a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc
+++ b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.cc
@@ -15,6 +15,7 @@
#include <sys/prctl.h>
#include <sys/ptrace.h>
#include <sys/resource.h>
+#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
@@ -244,6 +245,31 @@ ResultExpr RestrictMmapFlags() {
return If((flags & ~kAllowedMask) == 0, Allow()).Else(CrashSIGSYS());
}

+ResultExpr RestrictMmapFlagsNoWX() {
+ // The flags you see are actually the allowed ones, and the variable is a
+ // "denied" mask because of the negation operator.
+ // Significantly, we don't permit MAP_HUGETLB, or the newer flags such as
+ // MAP_POPULATE.
+ // TODO(davidung), remove MAP_DENYWRITE with updated Tegra libraries.
+
+ const Arg<int> prot(2);
+ const Arg<int> flags(3);
+
+ const BoolExpr is_mapping_w_x = (prot & (PROT_WRITE | PROT_EXEC)) != (PROT_WRITE | PROT_EXEC);
+
+ const BoolExpr is_anon_mapping_nx =
+ AllOf((prot & PROT_EXEC) == 0,
+ (flags & MAP_ANONYMOUS) == MAP_ANONYMOUS);
+
+ const uint64_t kAllowedMask = MAP_SHARED | MAP_PRIVATE | MAP_STACK |
+ MAP_NORESERVE | MAP_FIXED | MAP_DENYWRITE |
+ MAP_LOCKED;
+
+ return If(is_anon_mapping_nx, Allow())
+ .ElseIf(AllOf(is_mapping_w_x, (flags & ~kAllowedMask) == 0), Allow())
+ .Else(CrashSIGSYS());
+}
+
ResultExpr RestrictMprotectFlags() {
// The flags you see are actually the allowed ones, and the variable is a
// "denied" mask because of the negation operator.
@@ -262,6 +288,24 @@ ResultExpr RestrictMprotectFlags() {
return If((prot & ~kAllowedMask) == 0, Allow()).Else(CrashSIGSYS());
}

+ResultExpr RestrictMprotectFlagsNoWX() {
+ // The flags you see are actually the allowed ones, and the variable is a
+ // "denied" mask because of the negation operator.
+ // Significantly, we don't permit making non-executable pages executable,
+ // as well as weird undocumented flags such as PROT_GROWSDOWN.
+#if defined(ARCH_CPU_ARM64)
+ // Allows PROT_MTE and PROT_BTI (as explained higher up) on only Arm
+ // platforms.
+ const uint64_t kArchSpecificFlags = PROT_MTE | PROT_BTI;
+#else
+ const uint64_t kArchSpecificFlags = 0;
+#endif
+ const uint64_t kAllowedMask =
+ PROT_READ | PROT_WRITE | kArchSpecificFlags;
+ const Arg<int> prot(2);
+ return If((prot & ~kAllowedMask) == 0, Allow()).Else(CrashSIGSYS());
+}
+
ResultExpr RestrictFcntlCommands() {
// We also restrict the flags in F_SETFL. We don't want to permit flags with
// a history of trouble such as O_DIRECT. The flags you see are actually the
@@ -304,6 +348,17 @@ ResultExpr RestrictFcntlCommands() {
// clang-format on
}

+ResultExpr RestrictShmatFlags() {
+ // The flags you see are actually the allowed ones, and the variable is a
+ // "denied" mask because of the negation operator.
+ // Significantly, we don't permit flags that allow for dynamic code
+ // generation such as SHM_EXEC.
+ const uint64_t kAllowedMask =
+ 0 | SHM_RND | SHM_RDONLY | SHM_REMAP;
+ const Arg<int> shmflg(2);
+ return If((shmflg & ~kAllowedMask) == 0, Allow()).Else(CrashSIGSYS());
+}
+
#if defined(__i386__) || defined(__mips__)
ResultExpr RestrictSocketcallCommand() {
// Unfortunately, we are unable to restrict the first parameter to
diff --git a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h
index 171191ec518b5..4ea27bff6d563 100644
--- a/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h
+++ b/sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h
@@ -40,11 +40,25 @@ SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictIoctl();
// Crash if any other flag is used.
SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictMmapFlags();

+// Restrict mmap(2) arguments to:
+// Allow: MAP_SHARED | MAP_PRIVATE | MAP_ANONYMOUS |
+// MAP_STACK | MAP_NORESERVE | MAP_FIXED | MAP_DENYWRITE.
+// Crash if any other flag is used.
+// Also, in prots, restrict the allowed protections to:
+// PROT_READ | PROT_WRITE ^ PROT_EXEC.
+// PROT_BTI | PROT_MTE is additionally allowed on 64-bit Arm.
+SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictMmapFlagsNoWX();
+
// Restrict the prot argument in mprotect(2).
// Only allow: PROT_READ | PROT_WRITE | PROT_EXEC.
// PROT_BTI | PROT_MTE is additionally allowed on 64-bit Arm.
SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictMprotectFlags();

+// Restrict the prot argument in mprotect(2).
+// Only allow: PROT_READ | PROT_WRITE.
+// PROT_BTI | PROT_MTE is additionally allowed on 64-bit Arm.
+SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictMprotectFlagsNoWX();
+
// Restrict fcntl(2) cmd argument to:
// We allow F_GETFL, F_SETFL, F_GETFD, F_SETFD, F_DUPFD, F_DUPFD_CLOEXEC,
// F_SETLK, F_SETLKW and F_GETLK.
@@ -52,6 +66,10 @@ SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictMprotectFlags();
// O_NONBLOCK | O_SYNC | O_LARGEFILE | O_CLOEXEC | O_NOATIME.
SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictFcntlCommands();

+// Restrict the shmflg argument in shmat(2).
+// Only allow: SHM_RND | SHM_RDONLY | SHM_REMAP.
+SANDBOX_EXPORT bpf_dsl::ResultExpr RestrictShmatFlags();
+
#if defined(__i386__) || defined(__mips__)
// Restrict socketcall(2) to only allow socketpair(2), send(2), recv(2),
// sendto(2), recvfrom(2), shutdown(2), sendmsg(2) and recvmsg(2).
Loading