Index: content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.cc |
diff --git a/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.cc b/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.cc |
index c3b1605fc7dc6f091ae5456aad0371bcf2ee7c1a..dd7d1c58c6d8174c455dfcded219de3954fe97ae 100644 |
--- a/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.cc |
+++ b/content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.cc |
@@ -4,17 +4,51 @@ |
#include "content/common/sandbox_linux/android/sandbox_bpf_base_policy_android.h" |
+#include <errno.h> |
+#include <fcntl.h> |
+#include <linux/net.h> |
+#include <sys/socket.h> |
#include <sys/syscall.h> |
#include <sys/types.h> |
#include "build/build_config.h" |
#include "sandbox/linux/bpf_dsl/bpf_dsl.h" |
+using sandbox::bpf_dsl::AllOf; |
using sandbox::bpf_dsl::Allow; |
+using sandbox::bpf_dsl::AnyOf; |
+using sandbox::bpf_dsl::Arg; |
+using sandbox::bpf_dsl::BoolExpr; |
+using sandbox::bpf_dsl::If; |
+using sandbox::bpf_dsl::Error; |
using sandbox::bpf_dsl::ResultExpr; |
namespace content { |
+#ifndef SOCK_CLOEXEC |
+#define SOCK_CLOEXEC O_CLOEXEC |
+#endif |
+ |
+#ifndef SOCK_NONBLOCK |
+#define SOCK_NONBLOCK O_NONBLOCK |
+#endif |
+ |
+namespace { |
+ |
+// Restricts the arguments to sys_socket() to AF_UNIX. Returns a BoolExpr that |
+// evaluates to true if the syscall should be allowed. |
+BoolExpr RestrictSocketArguments(const Arg<int>& domain, |
+ const Arg<int>& type, |
+ const Arg<int>& protocol) { |
+ const int kSockFlags = SOCK_CLOEXEC | SOCK_NONBLOCK; |
+ return AllOf(domain == AF_UNIX, |
+ AnyOf((type & ~kSockFlags) == SOCK_DGRAM, |
+ (type & ~kSockFlags) == SOCK_STREAM), |
+ protocol == 0); |
+} |
+ |
+} // namespace |
+ |
SandboxBPFBasePolicyAndroid::SandboxBPFBasePolicyAndroid() |
: SandboxBPFBasePolicy() {} |
@@ -30,8 +64,10 @@ ResultExpr SandboxBPFBasePolicyAndroid::EvaluateSyscall(int sysno) const { |
case __NR_flock: |
#if defined(__x86_64__) || defined(__aarch64__) |
case __NR_newfstatat: |
+ case __NR_getdents64: |
#elif defined(__i386__) || defined(__arm__) || defined(__mips__) |
case __NR_fstatat64: |
+ case __NR_getdents: |
#endif |
case __NR_getpriority: |
case __NR_ioctl: |
@@ -56,10 +92,47 @@ ResultExpr SandboxBPFBasePolicyAndroid::EvaluateSyscall(int sysno) const { |
case __NR_getrlimit: |
#endif |
case __NR_uname: |
+ |
+ // Permit socket operations so that renderers can connect to logd and |
+ // debuggerd. The arguments to socket() are further restricted below. |
+ // Note that on i386, both of these calls map to __NR_socketcall, which |
+ // is demultiplexed below. |
+#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || \ |
+ defined(__mips__) |
+ case __NR_socket: |
+ case __NR_connect: |
+#endif |
+ |
+ // Ptrace is allowed so the Breakpad Microdumper can fork in a renderer |
+ // and then ptrace the parent. |
+ case __NR_ptrace: |
override_and_allow = true; |
break; |
} |
+#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || \ |
+ defined(__mips__) |
+ if (sysno == __NR_socket) { |
+ const Arg<int> domain(0); |
+ const Arg<int> type(1); |
+ const Arg<int> protocol(2); |
+ return If(RestrictSocketArguments(domain, type, protocol), Allow()) |
+ .Else(Error(EPERM)); |
+ } |
+#elif defined(__i386__) |
+ if (sysno == __NR_socketcall) { |
+ const Arg<int> socketcall(0); |
+ const Arg<int> domain(1); |
+ const Arg<int> type(2); |
+ const Arg<int> protocol(3); |
+ return If(socketcall == SYS_CONNECT, Allow()) |
+ .ElseIf(AllOf(socketcall == SYS_SOCKET, |
+ RestrictSocketArguments(domain, type, protocol)), |
+ Allow()) |
+ .Else(Error(EPERM)); |
+ } |
+#endif |
+ |
if (override_and_allow) |
return Allow(); |