Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.7-rc4 159 lines 4.0 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* Copyright (c) 2020 Carlos Neira cneirabustos@gmail.com */ 3#define _GNU_SOURCE 4#include <sys/stat.h> 5#include <sys/types.h> 6#include <unistd.h> 7#include <sys/syscall.h> 8#include <sched.h> 9#include <sys/wait.h> 10#include <sys/mount.h> 11#include "test_progs.h" 12 13#define CHECK_NEWNS(condition, tag, format...) ({ \ 14 int __ret = !!(condition); \ 15 if (__ret) { \ 16 printf("%s:FAIL:%s ", __func__, tag); \ 17 printf(format); \ 18 } else { \ 19 printf("%s:PASS:%s\n", __func__, tag); \ 20 } \ 21 __ret; \ 22}) 23 24struct bss { 25 __u64 dev; 26 __u64 ino; 27 __u64 pid_tgid; 28 __u64 user_pid_tgid; 29}; 30 31int main(int argc, char **argv) 32{ 33 pid_t pid; 34 int exit_code = 1; 35 struct stat st; 36 37 printf("Testing bpf_get_ns_current_pid_tgid helper in new ns\n"); 38 39 if (stat("/proc/self/ns/pid", &st)) { 40 perror("stat failed on /proc/self/ns/pid ns\n"); 41 printf("%s:FAILED\n", argv[0]); 42 return exit_code; 43 } 44 45 if (CHECK_NEWNS(unshare(CLONE_NEWPID | CLONE_NEWNS), 46 "unshare CLONE_NEWPID | CLONE_NEWNS", "error errno=%d\n", errno)) 47 return exit_code; 48 49 pid = fork(); 50 if (pid == -1) { 51 perror("Fork() failed\n"); 52 printf("%s:FAILED\n", argv[0]); 53 return exit_code; 54 } 55 56 if (pid > 0) { 57 int status; 58 59 usleep(5); 60 waitpid(pid, &status, 0); 61 return 0; 62 } else { 63 64 pid = fork(); 65 if (pid == -1) { 66 perror("Fork() failed\n"); 67 printf("%s:FAILED\n", argv[0]); 68 return exit_code; 69 } 70 71 if (pid > 0) { 72 int status; 73 waitpid(pid, &status, 0); 74 return 0; 75 } else { 76 if (CHECK_NEWNS(mount("none", "/proc", NULL, MS_PRIVATE|MS_REC, NULL), 77 "Unmounting proc", "Cannot umount proc! errno=%d\n", errno)) 78 return exit_code; 79 80 if (CHECK_NEWNS(mount("proc", "/proc", "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL), 81 "Mounting proc", "Cannot mount proc! errno=%d\n", errno)) 82 return exit_code; 83 84 const char *probe_name = "raw_tracepoint/sys_enter"; 85 const char *file = "test_ns_current_pid_tgid.o"; 86 struct bpf_link *link = NULL; 87 struct bpf_program *prog; 88 struct bpf_map *bss_map; 89 struct bpf_object *obj; 90 int exit_code = 1; 91 int err, key = 0; 92 struct bss bss; 93 struct stat st; 94 __u64 id; 95 96 obj = bpf_object__open_file(file, NULL); 97 if (CHECK_NEWNS(IS_ERR(obj), "obj_open", "err %ld\n", PTR_ERR(obj))) 98 return exit_code; 99 100 err = bpf_object__load(obj); 101 if (CHECK_NEWNS(err, "obj_load", "err %d errno %d\n", err, errno)) 102 goto cleanup; 103 104 bss_map = bpf_object__find_map_by_name(obj, "test_ns_.bss"); 105 if (CHECK_NEWNS(!bss_map, "find_bss_map", "failed\n")) 106 goto cleanup; 107 108 prog = bpf_object__find_program_by_title(obj, probe_name); 109 if (CHECK_NEWNS(!prog, "find_prog", "prog '%s' not found\n", 110 probe_name)) 111 goto cleanup; 112 113 memset(&bss, 0, sizeof(bss)); 114 pid_t tid = syscall(SYS_gettid); 115 pid_t pid = getpid(); 116 117 id = (__u64) tid << 32 | pid; 118 bss.user_pid_tgid = id; 119 120 if (CHECK_NEWNS(stat("/proc/self/ns/pid", &st), 121 "stat new ns", "Failed to stat /proc/self/ns/pid errno=%d\n", errno)) 122 goto cleanup; 123 124 bss.dev = st.st_dev; 125 bss.ino = st.st_ino; 126 127 err = bpf_map_update_elem(bpf_map__fd(bss_map), &key, &bss, 0); 128 if (CHECK_NEWNS(err, "setting_bss", "failed to set bss : %d\n", err)) 129 goto cleanup; 130 131 link = bpf_program__attach_raw_tracepoint(prog, "sys_enter"); 132 if (CHECK_NEWNS(IS_ERR(link), "attach_raw_tp", "err %ld\n", 133 PTR_ERR(link))) { 134 link = NULL; 135 goto cleanup; 136 } 137 138 /* trigger some syscalls */ 139 usleep(1); 140 141 err = bpf_map_lookup_elem(bpf_map__fd(bss_map), &key, &bss); 142 if (CHECK_NEWNS(err, "set_bss", "failed to get bss : %d\n", err)) 143 goto cleanup; 144 145 if (CHECK_NEWNS(id != bss.pid_tgid, "Compare user pid/tgid vs. bpf pid/tgid", 146 "User pid/tgid %llu BPF pid/tgid %llu\n", id, bss.pid_tgid)) 147 goto cleanup; 148 149 exit_code = 0; 150 printf("%s:PASS\n", argv[0]); 151cleanup: 152 if (!link) { 153 bpf_link__destroy(link); 154 link = NULL; 155 } 156 bpf_object__close(obj); 157 } 158 } 159}