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 5 // Sanitizers internally use some syscalls which non-SFI NaCl disallows. 6 #if !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER) && \ 7 !defined(MEMORY_SANITIZER) && !defined(LEAK_SANITIZER) 8 9 #include "components/nacl/loader/nonsfi/nonsfi_sandbox.h" 10 11 #include <errno.h> 12 #include <fcntl.h> 13 #include <linux/futex.h> 14 #include <pthread.h> 15 #include <sched.h> 16 #include <signal.h> 17 #include <stdlib.h> 18 #include <string.h> 19 #include <sys/mman.h> 20 #include <sys/prctl.h> 21 #include <sys/ptrace.h> 22 #include <sys/socket.h> 23 #include <sys/syscall.h> 24 #include <sys/types.h> 25 #include <sys/wait.h> 26 #include <time.h> 27 #include <unistd.h> 28 29 #include "base/bind.h" 30 #include "base/callback.h" 31 #include "base/compiler_specific.h" 32 #include "base/files/scoped_file.h" 33 #include "base/logging.h" 34 #include "base/posix/eintr_wrapper.h" 35 #include "base/sys_info.h" 36 #include "base/threading/thread.h" 37 #include "base/time/time.h" 38 #include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" 39 #include "sandbox/linux/seccomp-bpf/bpf_tests.h" 40 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h" 41 #include "sandbox/linux/seccomp-bpf/syscall.h" 42 #include "sandbox/linux/services/linux_syscalls.h" 43 #include "third_party/lss/linux_syscall_support.h" // for MAKE_PROCESS_CPUCLOCK 44 45 namespace { 46 47 void DoPipe(base::ScopedFD* fds) { 48 int tmp_fds[2]; 49 BPF_ASSERT_EQ(0, pipe(tmp_fds)); 50 fds[0].reset(tmp_fds[0]); 51 fds[1].reset(tmp_fds[1]); 52 } 53 54 void DoSocketpair(base::ScopedFD* fds) { 55 int tmp_fds[2]; 56 BPF_ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, tmp_fds)); 57 fds[0].reset(tmp_fds[0]); 58 fds[1].reset(tmp_fds[1]); 59 } 60 61 TEST(NaClNonSfiSandboxTest, BPFIsSupported) { 62 bool seccomp_bpf_supported = ( 63 sandbox::SandboxBPF::SupportsSeccompSandbox(-1) == 64 sandbox::SandboxBPF::STATUS_AVAILABLE); 65 if (!seccomp_bpf_supported) { 66 LOG(ERROR) << "Seccomp BPF is not supported, these tests " 67 << "will pass without running"; 68 } 69 } 70 71 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 72 invalid_sysno, 73 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 74 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 75 syscall(999); 76 } 77 78 const int kExpectedValue = 123; 79 80 void* SetValueInThread(void* test_val_ptr) { 81 *reinterpret_cast<int*>(test_val_ptr) = kExpectedValue; 82 return NULL; 83 } 84 85 // To make this test pass, we need to allow sched_getaffinity and 86 // mmap. We just disable this test not to complicate the sandbox. 87 BPF_TEST_C(NaClNonSfiSandboxTest, 88 clone_by_pthread_create, 89 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 90 // clone call for thread creation is allowed. 91 pthread_t th; 92 int test_val = 42; 93 BPF_ASSERT_EQ(0, pthread_create(&th, NULL, &SetValueInThread, &test_val)); 94 BPF_ASSERT_EQ(0, pthread_join(th, NULL)); 95 BPF_ASSERT_EQ(kExpectedValue, test_val); 96 } 97 98 int DoFork() { 99 // Call clone() to do a fork(). 100 const int pid = syscall(__NR_clone, SIGCHLD, NULL); 101 if (pid == 0) 102 _exit(0); 103 return pid; 104 } 105 106 // The sanity check for DoFork without the sandbox. 107 TEST(NaClNonSfiSandboxTest, DoFork) { 108 const int pid = DoFork(); 109 ASSERT_LT(0, pid); 110 int status; 111 ASSERT_EQ(pid, HANDLE_EINTR(waitpid(pid, &status, 0))); 112 ASSERT_TRUE(WIFEXITED(status)); 113 ASSERT_EQ(0, WEXITSTATUS(status)); 114 } 115 116 // Then, try this in the sandbox. 117 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 118 clone_for_fork, 119 DEATH_MESSAGE(sandbox::GetCloneErrorMessageContentForTests()), 120 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 121 DoFork(); 122 } 123 124 BPF_TEST_C(NaClNonSfiSandboxTest, 125 prctl_SET_NAME, 126 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 127 errno = 0; 128 BPF_ASSERT_EQ(-1, syscall(__NR_prctl, PR_SET_NAME, "foo")); 129 BPF_ASSERT_EQ(EPERM, errno); 130 } 131 132 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 133 prctl_SET_DUMPABLE, 134 DEATH_MESSAGE(sandbox::GetPrctlErrorMessageContentForTests()), 135 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 136 syscall(__NR_prctl, PR_SET_DUMPABLE, 1UL); 137 } 138 139 BPF_TEST_C(NaClNonSfiSandboxTest, 140 socketcall_allowed, 141 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 142 base::ScopedFD fds[2]; 143 struct msghdr msg = {}; 144 struct iovec iov; 145 std::string payload("foo"); 146 iov.iov_base = &payload[0]; 147 iov.iov_len = payload.size(); 148 msg.msg_iov = &iov; 149 msg.msg_iovlen = 1; 150 DoSocketpair(fds); 151 BPF_ASSERT_EQ(static_cast<int>(payload.size()), 152 HANDLE_EINTR(sendmsg(fds[1].get(), &msg, 0))); 153 BPF_ASSERT_EQ(static_cast<int>(payload.size()), 154 HANDLE_EINTR(recvmsg(fds[0].get(), &msg, 0))); 155 BPF_ASSERT_EQ(0, shutdown(fds[0].get(), SHUT_RDWR)); 156 } 157 158 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 159 accept, 160 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 161 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 162 accept(0, NULL, NULL); 163 } 164 165 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 166 bind, 167 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 168 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 169 bind(0, NULL, 0); 170 } 171 172 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 173 connect, 174 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 175 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 176 connect(0, NULL, 0); 177 } 178 179 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 180 getpeername, 181 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 182 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 183 getpeername(0, NULL, NULL); 184 } 185 186 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 187 getsockname, 188 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 189 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 190 struct sockaddr addr; 191 socklen_t addrlen = 0; 192 getsockname(0, &addr, &addrlen); 193 } 194 195 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 196 getsockopt, 197 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 198 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 199 getsockopt(0, 0, 0, NULL, NULL); 200 } 201 202 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 203 listen, 204 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 205 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 206 listen(0, 0); 207 } 208 209 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 210 recv, 211 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 212 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 213 recv(0, NULL, 0, 0); 214 } 215 216 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 217 recvfrom, 218 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 219 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 220 recvfrom(0, NULL, 0, 0, NULL, NULL); 221 } 222 223 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 224 send, 225 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 226 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 227 send(0, NULL, 0, 0); 228 } 229 230 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 231 sendto, 232 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 233 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 234 sendto(0, NULL, 0, 0, NULL, 0); 235 } 236 237 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 238 setsockopt, 239 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 240 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 241 setsockopt(0, 0, 0, NULL, 0); 242 } 243 244 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 245 socket, 246 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 247 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 248 socket(0, 0, 0); 249 } 250 251 #if defined(__x86_64__) || defined(__arm__) 252 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 253 socketpair, 254 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 255 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 256 int fds[2]; 257 socketpair(AF_INET, SOCK_STREAM, 0, fds); 258 } 259 #endif 260 261 BPF_TEST_C(NaClNonSfiSandboxTest, 262 fcntl_SETFD_allowed, 263 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 264 base::ScopedFD fds[2]; 265 DoSocketpair(fds); 266 BPF_ASSERT_EQ(0, fcntl(fds[0].get(), F_SETFD, FD_CLOEXEC)); 267 } 268 269 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 270 fcntl_SETFD, 271 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 272 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 273 base::ScopedFD fds[2]; 274 DoSocketpair(fds); 275 fcntl(fds[0].get(), F_SETFD, 99); 276 } 277 278 BPF_TEST_C(NaClNonSfiSandboxTest, 279 fcntl_GETFL_SETFL_allowed, 280 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 281 base::ScopedFD fds[2]; 282 DoPipe(fds); 283 const int fd = fds[0].get(); 284 BPF_ASSERT_EQ(0, fcntl(fd, F_GETFL)); 285 BPF_ASSERT_EQ(0, fcntl(fd, F_SETFL, O_RDWR | O_NONBLOCK)); 286 BPF_ASSERT_EQ(O_NONBLOCK, fcntl(fd, F_GETFL)); 287 } 288 289 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 290 fcntl_GETFL_SETFL, 291 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 292 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 293 base::ScopedFD fds[2]; 294 DoSocketpair(fds); 295 fcntl(fds[0].get(), F_SETFL, O_APPEND); 296 } 297 298 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 299 fcntl_DUPFD, 300 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 301 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 302 fcntl(0, F_DUPFD); 303 } 304 305 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 306 fcntl_DUPFD_CLOEXEC, 307 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 308 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 309 fcntl(0, F_DUPFD_CLOEXEC); 310 } 311 312 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 313 FutexWithRequeuePriorityInheritence, 314 DEATH_MESSAGE(sandbox::GetFutexErrorMessageContentForTests()), 315 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 316 syscall(__NR_futex, NULL, FUTEX_CMP_REQUEUE_PI, 0, NULL, NULL, 0); 317 _exit(1); 318 } 319 320 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 321 FutexWithRequeuePriorityInheritencePrivate, 322 DEATH_MESSAGE(sandbox::GetFutexErrorMessageContentForTests()), 323 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 324 syscall(__NR_futex, NULL, FUTEX_CMP_REQUEUE_PI_PRIVATE, 0, NULL, NULL, 0); 325 _exit(1); 326 } 327 328 BPF_TEST_C(NaClNonSfiSandboxTest, 329 StartingAndJoiningThreadWorks, 330 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 331 base::Thread thread("sandbox_tests"); 332 BPF_ASSERT(thread.Start()); 333 // |thread|'s destructor will join the thread. 334 } 335 336 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 337 FutexWithUnlockPIPrivate, 338 DEATH_MESSAGE(sandbox::GetFutexErrorMessageContentForTests()), 339 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 340 syscall(__NR_futex, NULL, FUTEX_UNLOCK_PI_PRIVATE, 0, NULL, NULL, 0); 341 _exit(1); 342 } 343 344 void* DoAllowedAnonymousMmap() { 345 return mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, 346 MAP_ANONYMOUS | MAP_SHARED, -1, 0); 347 } 348 349 BPF_TEST_C(NaClNonSfiSandboxTest, 350 mmap_allowed, 351 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 352 void* ptr = DoAllowedAnonymousMmap(); 353 BPF_ASSERT_NE(MAP_FAILED, ptr); 354 BPF_ASSERT_EQ(0, munmap(ptr, getpagesize())); 355 } 356 357 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 358 mmap_unallowed_flag, 359 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 360 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 361 mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, 362 MAP_ANONYMOUS | MAP_POPULATE, -1, 0); 363 } 364 365 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 366 mmap_unallowed_prot, 367 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 368 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 369 mmap(NULL, getpagesize(), PROT_READ | PROT_GROWSDOWN, 370 MAP_ANONYMOUS, -1, 0); 371 } 372 373 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 374 mmap_exec, 375 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 376 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 377 mmap(NULL, getpagesize(), PROT_EXEC, MAP_ANONYMOUS, -1, 0); 378 } 379 380 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 381 mmap_read_exec, 382 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 383 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 384 mmap(NULL, getpagesize(), PROT_READ | PROT_EXEC, MAP_ANONYMOUS, -1, 0); 385 } 386 387 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 388 mmap_write_exec, 389 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 390 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 391 mmap(NULL, getpagesize(), PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS, -1, 0); 392 } 393 394 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 395 mmap_read_write_exec, 396 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 397 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 398 mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC, 399 MAP_ANONYMOUS, -1, 0); 400 } 401 402 BPF_TEST_C(NaClNonSfiSandboxTest, 403 mprotect_allowed, 404 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 405 void* ptr = DoAllowedAnonymousMmap(); 406 BPF_ASSERT_NE(MAP_FAILED, ptr); 407 BPF_ASSERT_EQ(0, mprotect(ptr, getpagesize(), PROT_READ)); 408 BPF_ASSERT_EQ(0, munmap(ptr, getpagesize())); 409 } 410 411 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 412 mprotect_unallowed_prot, 413 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 414 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 415 // We have tested DoAllowedAnonymousMmap is allowed in 416 // mmap_allowed, so we can make sure the following mprotect call 417 // kills the process. 418 void* ptr = DoAllowedAnonymousMmap(); 419 BPF_ASSERT_NE(MAP_FAILED, ptr); 420 mprotect(ptr, getpagesize(), PROT_READ | PROT_GROWSDOWN); 421 } 422 423 BPF_TEST_C(NaClNonSfiSandboxTest, 424 brk, 425 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 426 char* next_brk = static_cast<char*>(sbrk(0)) + getpagesize(); 427 // The kernel interface must return zero for brk. 428 BPF_ASSERT_EQ(0, syscall(__NR_brk, next_brk)); 429 // The libc wrapper translates it to ENOMEM. 430 errno = 0; 431 BPF_ASSERT_EQ(-1, brk(next_brk)); 432 BPF_ASSERT_EQ(ENOMEM, errno); 433 } 434 435 // clockid restrictions are mostly tested in sandbox/ with the 436 // RestrictClockID() unittests. Some basic tests are duplicated here as 437 // a precaution. 438 439 void CheckClock(clockid_t clockid) { 440 struct timespec ts; 441 ts.tv_sec = ts.tv_nsec = -1; 442 BPF_ASSERT_EQ(0, clock_gettime(clockid, &ts)); 443 BPF_ASSERT_LE(0, ts.tv_sec); 444 BPF_ASSERT_LE(0, ts.tv_nsec); 445 } 446 447 BPF_TEST_C(NaClNonSfiSandboxTest, 448 clock_gettime_allowed, 449 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 450 CheckClock(CLOCK_MONOTONIC); 451 CheckClock(CLOCK_PROCESS_CPUTIME_ID); 452 CheckClock(CLOCK_REALTIME); 453 CheckClock(CLOCK_THREAD_CPUTIME_ID); 454 } 455 456 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 457 clock_gettime_crash_monotonic_raw, 458 DEATH_MESSAGE(sandbox::GetErrorMessageContentForTests()), 459 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 460 struct timespec ts; 461 clock_gettime(CLOCK_MONOTONIC_RAW, &ts); 462 } 463 464 BPF_DEATH_TEST_C(NaClNonSfiSandboxTest, 465 invalid_syscall_crash, 466 DEATH_SEGV_MESSAGE(sandbox::GetErrorMessageContentForTests()), 467 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { 468 sandbox::Syscall::InvalidCall(); 469 } 470 471 // The following test cases check if syscalls return EPERM regardless 472 // of arguments. 473 #define RESTRICT_SYSCALL_EPERM_TEST(name) \ 474 BPF_TEST_C(NaClNonSfiSandboxTest, \ 475 name##_EPERM, \ 476 nacl::nonsfi::NaClNonSfiBPFSandboxPolicy) { \ 477 errno = 0; \ 478 BPF_ASSERT_EQ(-1, syscall(__NR_##name, 0, 0, 0, 0, 0, 0)); \ 479 BPF_ASSERT_EQ(EPERM, errno); \ 480 } 481 482 RESTRICT_SYSCALL_EPERM_TEST(epoll_create); 483 #if defined(__i386__) || defined(__arm__) 484 RESTRICT_SYSCALL_EPERM_TEST(getegid32); 485 RESTRICT_SYSCALL_EPERM_TEST(geteuid32); 486 RESTRICT_SYSCALL_EPERM_TEST(getgid32); 487 RESTRICT_SYSCALL_EPERM_TEST(getuid32); 488 #endif 489 RESTRICT_SYSCALL_EPERM_TEST(getegid); 490 RESTRICT_SYSCALL_EPERM_TEST(geteuid); 491 RESTRICT_SYSCALL_EPERM_TEST(getgid); 492 RESTRICT_SYSCALL_EPERM_TEST(getuid); 493 RESTRICT_SYSCALL_EPERM_TEST(madvise); 494 RESTRICT_SYSCALL_EPERM_TEST(open); 495 RESTRICT_SYSCALL_EPERM_TEST(openat); 496 RESTRICT_SYSCALL_EPERM_TEST(ptrace); 497 RESTRICT_SYSCALL_EPERM_TEST(set_robust_list); 498 #if defined(__i386__) || defined(__x86_64__) 499 RESTRICT_SYSCALL_EPERM_TEST(time); 500 #endif 501 502 } // namespace 503 504 #endif // !ADDRESS_SANITIZER && !THREAD_SANITIZER && 505 // !MEMORY_SANITIZER && !LEAK_SANITIZER 506