1 // SPDX-License-Identifier: GPL-2.0 2 3 /* 4 * Copyright (C) 2020 Google LLC. 5 */ 6 7 #include <test_progs.h> 8 #include <sys/mman.h> 9 #include <sys/wait.h> 10 #include <unistd.h> 11 #include <malloc.h> 12 #include <stdlib.h> 13 14 #include "lsm.skel.h" 15 16 char *CMD_ARGS[] = {"true", NULL}; 17 18 #define GET_PAGE_ADDR(ADDR, PAGE_SIZE) \ 19 (char *)(((unsigned long) (ADDR + PAGE_SIZE)) & ~(PAGE_SIZE-1)) 20 21 int stack_mprotect(void) 22 { 23 void *buf; 24 long sz; 25 int ret; 26 27 sz = sysconf(_SC_PAGESIZE); 28 if (sz < 0) 29 return sz; 30 31 buf = alloca(sz * 3); 32 ret = mprotect(GET_PAGE_ADDR(buf, sz), sz, 33 PROT_READ | PROT_WRITE | PROT_EXEC); 34 return ret; 35 } 36 37 int exec_cmd(int *monitored_pid) 38 { 39 int child_pid, child_status; 40 41 child_pid = fork(); 42 if (child_pid == 0) { 43 *monitored_pid = getpid(); 44 execvp(CMD_ARGS[0], CMD_ARGS); 45 return -EINVAL; 46 } else if (child_pid > 0) { 47 waitpid(child_pid, &child_status, 0); 48 return child_status; 49 } 50 51 return -EINVAL; 52 } 53 54 static int test_lsm(struct lsm *skel) 55 { 56 struct bpf_link *link; 57 int buf = 1234; 58 int err; 59 60 err = lsm__attach(skel); 61 if (!ASSERT_OK(err, "attach")) 62 return err; 63 64 /* Check that already linked program can't be attached again. */ 65 link = bpf_program__attach(skel->progs.test_int_hook); 66 if (!ASSERT_ERR_PTR(link, "attach_link")) 67 return -1; 68 69 err = exec_cmd(&skel->bss->monitored_pid); 70 if (!ASSERT_OK(err, "exec_cmd")) 71 return err; 72 73 ASSERT_EQ(skel->bss->bprm_count, 1, "bprm_count"); 74 75 skel->bss->monitored_pid = getpid(); 76 77 err = stack_mprotect(); 78 if (!ASSERT_EQ(errno, EPERM, "stack_mprotect")) 79 return err; 80 81 ASSERT_EQ(skel->bss->mprotect_count, 1, "mprotect_count"); 82 83 syscall(__NR_setdomainname, &buf, -2L); 84 syscall(__NR_setdomainname, 0, -3L); 85 syscall(__NR_setdomainname, ~0L, -4L); 86 87 ASSERT_EQ(skel->bss->copy_test, 3, "copy_test"); 88 89 lsm__detach(skel); 90 91 skel->bss->copy_test = 0; 92 skel->bss->bprm_count = 0; 93 skel->bss->mprotect_count = 0; 94 return 0; 95 } 96 97 void test_test_lsm(void) 98 { 99 struct lsm *skel = NULL; 100 int err; 101 102 skel = lsm__open_and_load(); 103 if (!ASSERT_OK_PTR(skel, "lsm_skel_load")) 104 goto close_prog; 105 106 err = test_lsm(skel); 107 if (!ASSERT_OK(err, "test_lsm_first_attach")) 108 goto close_prog; 109 110 err = test_lsm(skel); 111 ASSERT_OK(err, "test_lsm_second_attach"); 112 113 close_prog: 114 lsm__destroy(skel); 115 } 116