| 1 | // RUN: %clangxx %s -o %t && %run %t %p |
| 2 | |
| 3 | // UNSUPPORTED: android |
| 4 | |
| 5 | #include <assert.h> |
| 6 | #include <errno.h> |
| 7 | #include <linux/filter.h> |
| 8 | #include <linux/seccomp.h> |
| 9 | #include <stdint.h> |
| 10 | #include <string.h> |
| 11 | #include <sys/mman.h> |
| 12 | #include <sys/prctl.h> |
| 13 | |
| 14 | #ifndef PR_SCHED_CORE |
| 15 | # define PR_SCHED_CORE 62 |
| 16 | #endif |
| 17 | |
| 18 | #ifndef PR_SCHED_CORE_CREATE |
| 19 | # define PR_SCHED_CORE_CREATE 1 |
| 20 | #endif |
| 21 | |
| 22 | #ifndef PR_SCHED_CORE_GET |
| 23 | # define PR_SCHED_CORE_GET 0 |
| 24 | #endif |
| 25 | |
| 26 | #ifndef PR_SET_VMA |
| 27 | # define PR_SET_VMA 0x53564d41 |
| 28 | # define PR_SET_VMA_ANON_NAME 0 |
| 29 | #endif |
| 30 | |
| 31 | int main() { |
| 32 | int res; |
| 33 | res = prctl(PR_SCHED_CORE, PR_SCHED_CORE_CREATE, 0, 0, 0); |
| 34 | if (res < 0) { |
| 35 | assert(errno == EINVAL || errno == ENODEV); |
| 36 | } else { |
| 37 | uint64_t cookie = 0; |
| 38 | res = prctl(PR_SCHED_CORE, PR_SCHED_CORE_GET, 0, 0, &cookie); |
| 39 | if (res < 0) { |
| 40 | assert(errno == EINVAL); |
| 41 | } else { |
| 42 | assert(cookie != 0); |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | int signum; |
| 47 | res = prctl(PR_GET_PDEATHSIG, reinterpret_cast<unsigned long>(&signum)); |
| 48 | if (res < 0) { |
| 49 | assert(errno == EINVAL); |
| 50 | } else { |
| 51 | assert(signum == 0); |
| 52 | } |
| 53 | |
| 54 | char invname[81], vlname[] = "prctl" ; |
| 55 | for (auto i = 0; i < sizeof(invname); i++) { |
| 56 | invname[i] = 0x1e; |
| 57 | } |
| 58 | invname[80] = 0; |
| 59 | auto p = |
| 60 | mmap(addr: nullptr, len: 128, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, fd: -1, offset: 0); |
| 61 | assert(p != MAP_FAILED); |
| 62 | // regardless of kernel support, the name is invalid |
| 63 | res = prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, (uintptr_t)p, 128, |
| 64 | (uintptr_t)invname); |
| 65 | assert(res == -1); |
| 66 | assert(errno == EINVAL); |
| 67 | res = prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, (uintptr_t)p, 128, |
| 68 | (uintptr_t)vlname); |
| 69 | if (res < 0) { |
| 70 | assert(errno == EINVAL); |
| 71 | } |
| 72 | munmap(addr: p, len: 128); |
| 73 | |
| 74 | res = prctl(PR_SET_NAME, "tname" ); |
| 75 | if (res == 0) { |
| 76 | char name[16]; |
| 77 | res = prctl(PR_GET_NAME, name); |
| 78 | if (res == 0) { |
| 79 | assert(!strcmp(name, "tname" )); |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | sock_filter f[] = {{.code = (BPF_LD | BPF_W | BPF_ABS), |
| 84 | .k = (uint32_t)(SKF_AD_OFF | SKF_AD_CPU)}, |
| 85 | {.code = (BPF_RET | BPF_A), .k = 0}}; |
| 86 | sock_fprog pr = {.len = 2, .filter = f}; |
| 87 | |
| 88 | res = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &pr); |
| 89 | assert(res == -1); |
| 90 | |
| 91 | return 0; |
| 92 | } |
| 93 | |