baseline_policy_android.cc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "sandbox/linux/seccomp-bpf-helpers/baseline_policy_android.h"
  5. #include <errno.h>
  6. #include <fcntl.h>
  7. #include <linux/android/binder.h>
  8. #include <linux/ashmem.h>
  9. #include <linux/nbd.h>
  10. #include <linux/net.h>
  11. #include <linux/userfaultfd.h>
  12. #include <sys/socket.h>
  13. #include <sys/syscall.h>
  14. #include <sys/types.h>
  15. #include "build/build_config.h"
  16. #include "sandbox/linux/bpf_dsl/bpf_dsl.h"
  17. #include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h"
  18. #include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h"
  19. #include "sandbox/linux/system_headers/linux_syscalls.h"
  20. #if defined(__x86_64__)
  21. #include <asm/prctl.h>
  22. #endif
  23. using sandbox::bpf_dsl::AllOf;
  24. using sandbox::bpf_dsl::Allow;
  25. using sandbox::bpf_dsl::AnyOf;
  26. using sandbox::bpf_dsl::Arg;
  27. using sandbox::bpf_dsl::BoolConst;
  28. using sandbox::bpf_dsl::BoolExpr;
  29. using sandbox::bpf_dsl::Error;
  30. using sandbox::bpf_dsl::If;
  31. using sandbox::bpf_dsl::ResultExpr;
  32. namespace sandbox {
  33. #ifndef SOCK_CLOEXEC
  34. #define SOCK_CLOEXEC O_CLOEXEC
  35. #endif
  36. #ifndef SOCK_NONBLOCK
  37. #define SOCK_NONBLOCK O_NONBLOCK
  38. #endif
  39. #define CASES SANDBOX_BPF_DSL_CASES
  40. namespace {
  41. #if !defined(__i386__)
  42. // Restricts the arguments to sys_socket() to AF_UNIX. Returns a BoolExpr that
  43. // evaluates to true if the syscall should be allowed.
  44. BoolExpr RestrictSocketArguments(const Arg<int>& domain,
  45. const Arg<int>& type,
  46. const Arg<int>& protocol) {
  47. const int kSockFlags = SOCK_CLOEXEC | SOCK_NONBLOCK;
  48. return AllOf(domain == AF_UNIX,
  49. AnyOf((type & ~kSockFlags) == SOCK_DGRAM,
  50. (type & ~kSockFlags) == SOCK_STREAM),
  51. protocol == 0);
  52. }
  53. #endif // !defined(__i386__)
  54. ResultExpr RestrictAndroidIoctl(bool allow_userfaultfd_ioctls) {
  55. const Arg<int> request(1);
  56. // There is no way at runtime to test if the system is running with
  57. // BINDER_IPC_32BIT. Instead, compute the corresponding bitness' ioctl
  58. // request number, so that either are allowed in the case of mixed-bitness
  59. // systems.
  60. #ifdef BINDER_IPC_32BIT
  61. const int kBinderWriteRead32 = BINDER_WRITE_READ;
  62. const int kBinderWriteRead64 =
  63. (BINDER_WRITE_READ & ~IOCSIZE_MASK) |
  64. ((sizeof(binder_write_read) * 2) << _IOC_SIZESHIFT);
  65. #else
  66. const int kBinderWriteRead64 = BINDER_WRITE_READ;
  67. const int kBinderWriteRead32 =
  68. (BINDER_WRITE_READ & ~IOCSIZE_MASK) |
  69. ((sizeof(binder_write_read) / 2) << _IOC_SIZESHIFT);
  70. #endif
  71. // ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), a legacy interface
  72. // for getting clock information from /dev/alarm. It was removed in Android O
  73. // (https://android-review.googlesource.com/c/221812), and it can be safely
  74. // blocked in earlier releases because there is a fallback. Constant expanded
  75. // from
  76. // https://cs.android.com/android/platform/superproject/+/android-7.0.0_r1:external/kernel-headers/original/uapi/linux/android_alarm.h;l=57.
  77. // The size is a `struct timespec`, which has a different width on 32- and
  78. // 64-bit systems, so handle both.
  79. const int kAndroidAlarmGetTimeElapsedRealtime32 = 0x40086134;
  80. const int kAndroidAlarmGetTimeElapsedRealtime64 = 0x40106134;
  81. return Switch(request)
  82. .CASES((
  83. // Android shared memory.
  84. ASHMEM_SET_NAME, ASHMEM_GET_NAME, ASHMEM_SET_SIZE,
  85. ASHMEM_GET_SIZE, ASHMEM_SET_PROT_MASK, ASHMEM_GET_PROT_MASK,
  86. ASHMEM_PIN, ASHMEM_UNPIN, ASHMEM_GET_PIN_STATUS,
  87. // Binder.
  88. kBinderWriteRead32, kBinderWriteRead64, BINDER_SET_MAX_THREADS,
  89. BINDER_THREAD_EXIT, BINDER_VERSION,
  90. BINDER_ENABLE_ONEWAY_SPAM_DETECTION),
  91. Allow())
  92. .CASES((
  93. // userfaultfd ART GC (https://crbug.com/1300653).
  94. UFFDIO_REGISTER, UFFDIO_UNREGISTER, UFFDIO_WAKE, UFFDIO_COPY,
  95. UFFDIO_ZEROPAGE, UFFDIO_CONTINUE),
  96. If(BoolConst(allow_userfaultfd_ioctls), Allow())
  97. .Else(RestrictIoctl()))
  98. .CASES((
  99. // Deprecated Android /dev/alarm interface.
  100. kAndroidAlarmGetTimeElapsedRealtime32,
  101. kAndroidAlarmGetTimeElapsedRealtime64,
  102. // Linux Network Block Device requests observed in the field
  103. // https://crbug.com/1314105.
  104. NBD_CLEAR_SOCK, NBD_SET_BLKSIZE),
  105. Error(EINVAL))
  106. .Default(RestrictIoctl());
  107. }
  108. } // namespace
  109. BaselinePolicyAndroid::BaselinePolicyAndroid()
  110. : BaselinePolicy() {}
  111. BaselinePolicyAndroid::BaselinePolicyAndroid(const RuntimeOptions& options)
  112. : BaselinePolicy(), options_(options) {}
  113. BaselinePolicyAndroid::~BaselinePolicyAndroid() {}
  114. ResultExpr BaselinePolicyAndroid::EvaluateSyscall(int sysno) const {
  115. bool override_and_allow = false;
  116. switch (sysno) {
  117. // TODO(rsesek): restrict clone parameters.
  118. case __NR_clone:
  119. case __NR_epoll_pwait:
  120. case __NR_fdatasync:
  121. case __NR_flock:
  122. case __NR_fsync:
  123. case __NR_ftruncate:
  124. #if defined(__i386__) || defined(__arm__) || \
  125. (defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_32_BITS))
  126. case __NR_ftruncate64:
  127. #endif
  128. #if defined(__x86_64__) || defined(__aarch64__)
  129. case __NR_newfstatat:
  130. case __NR_fstatfs:
  131. #elif defined(__i386__) || defined(__arm__) || \
  132. (defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_32_BITS))
  133. case __NR_fstatat64:
  134. case __NR_fstatfs64:
  135. #endif
  136. #if defined(__arm__) || defined(__aarch64__)
  137. // getcpu() is allowed on ARM chips because it is used in
  138. // //third_party/cpuinfo/ on those chips.
  139. case __NR_getcpu:
  140. #endif
  141. #if defined(__i386__) || defined(__arm__) || defined(__mips__)
  142. case __NR_getdents:
  143. #endif
  144. case __NR_getdents64:
  145. case __NR_getpriority:
  146. case __NR_membarrier: // https://crbug.com/966433
  147. case __NR_mremap:
  148. #if defined(__i386__)
  149. // Used on pre-N to initialize threads in ART.
  150. case __NR_modify_ldt:
  151. #endif
  152. case __NR_msync:
  153. // File system access cannot be restricted with seccomp-bpf on Android,
  154. // since the JVM classloader and other Framework features require file
  155. // access. It may be possible to restrict the filesystem with SELinux.
  156. // Currently we rely on the app/service UID isolation to create a
  157. // filesystem "sandbox".
  158. #if !defined(ARCH_CPU_ARM64)
  159. case __NR_open:
  160. #endif
  161. case __NR_openat:
  162. case __NR_pwrite64:
  163. case __NR_rt_sigtimedwait:
  164. #if defined(__i386__) || defined(__arm__) || \
  165. (defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_32_BITS))
  166. case __NR_rt_sigtimedwait_time64:
  167. #endif
  168. case __NR_sched_getparam:
  169. case __NR_sched_getscheduler:
  170. case __NR_sched_setscheduler:
  171. case __NR_setpriority:
  172. #if defined(__i386__)
  173. // Used on N+ instead of __NR_modify_ldt to initialize threads in ART.
  174. case __NR_set_thread_area:
  175. #endif
  176. case __NR_set_tid_address:
  177. #if defined(__i386__) || defined(__arm__)
  178. case __NR_ugetrlimit:
  179. #else
  180. case __NR_getrlimit:
  181. #endif
  182. case __NR_sysinfo: // https://crbug.com/655277
  183. // Permit socket operations so that renderers can connect to logd and
  184. // debuggerd. The arguments to socket() are further restricted below.
  185. // Note that on i386, both of these calls map to __NR_socketcall, which
  186. // is demultiplexed below.
  187. #if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || \
  188. defined(__mips__)
  189. case __NR_getsockopt:
  190. case __NR_connect:
  191. case __NR_socket:
  192. #endif
  193. override_and_allow = true;
  194. break;
  195. }
  196. if (sysno == __NR_sched_setaffinity || sysno == __NR_sched_getaffinity) {
  197. return Error(EPERM);
  198. }
  199. if (sysno == __NR_ioctl) {
  200. return RestrictAndroidIoctl(options_.allow_userfaultfd_ioctls);
  201. }
  202. // Ptrace is allowed so the crash reporter can fork in a renderer
  203. // and then ptrace the parent. https://crbug.com/933418
  204. if (sysno == __NR_ptrace) {
  205. return RestrictPtrace();
  206. }
  207. // https://crbug.com/766245
  208. if (sysno == __NR_process_vm_readv) {
  209. const Arg<pid_t> pid(0);
  210. return If(pid == policy_pid(), Allow())
  211. .Else(Error(EPERM));
  212. }
  213. // https://crbug.com/655299
  214. if (sysno == __NR_clock_getres
  215. #if defined(__i386__) || defined(__arm__) || \
  216. (defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_32_BITS))
  217. || sysno == __NR_clock_getres_time64
  218. #endif
  219. ) {
  220. return RestrictClockID();
  221. }
  222. // https://crbug.com/826289
  223. if (sysno == __NR_getrusage) {
  224. return RestrictGetrusage();
  225. }
  226. #if defined(__x86_64__)
  227. if (sysno == __NR_arch_prctl) {
  228. const Arg<int> code(0);
  229. return If(code == ARCH_SET_GS, Allow()).Else(Error(EPERM));
  230. }
  231. #endif
  232. // Restrict socket-related operations. On non-i386 platforms, these are
  233. // individual syscalls. On i386, the socketcall syscall demultiplexes many
  234. // socket operations.
  235. #if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || \
  236. defined(__mips__)
  237. if (sysno == __NR_socket) {
  238. const Arg<int> domain(0);
  239. const Arg<int> type(1);
  240. const Arg<int> protocol(2);
  241. return If(RestrictSocketArguments(domain, type, protocol), Allow())
  242. .Else(Error(EPERM));
  243. }
  244. // https://crbug.com/655300
  245. if (sysno == __NR_getsockname) {
  246. // Rather than blocking with SIGSYS, just return an error. This is not
  247. // documented to be a valid errno, but we will use it anyways.
  248. return Error(EPERM);
  249. }
  250. // https://crbug.com/682488, https://crbug.com/701137
  251. if (sysno == __NR_setsockopt) {
  252. // The baseline policy applies other restrictions to setsockopt.
  253. const Arg<int> level(1);
  254. const Arg<int> option(2);
  255. return If(AllOf(level == SOL_SOCKET,
  256. AnyOf(option == SO_SNDTIMEO,
  257. option == SO_RCVTIMEO,
  258. option == SO_SNDBUF,
  259. option == SO_REUSEADDR,
  260. option == SO_PASSCRED)),
  261. Allow())
  262. .Else(BaselinePolicy::EvaluateSyscall(sysno));
  263. }
  264. #elif defined(__i386__)
  265. if (sysno == __NR_socketcall) {
  266. // The baseline policy allows other socketcall sub-calls.
  267. const Arg<int> socketcall(0);
  268. return Switch(socketcall)
  269. .CASES((SYS_CONNECT,
  270. SYS_SOCKET,
  271. SYS_SETSOCKOPT,
  272. SYS_GETSOCKOPT),
  273. Allow())
  274. .Default(BaselinePolicy::EvaluateSyscall(sysno));
  275. }
  276. #endif
  277. if (override_and_allow)
  278. return Allow();
  279. return BaselinePolicy::EvaluateSyscall(sysno);
  280. }
  281. } // namespace sandbox