selftests/bpf: Add re-attach test to lsm test
[linux-2.6-microblaze.git] / tools / testing / selftests / bpf / prog_tests / test_lsm.c
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 static int duration = 0;
22
23 int stack_mprotect(void)
24 {
25         void *buf;
26         long sz;
27         int ret;
28
29         sz = sysconf(_SC_PAGESIZE);
30         if (sz < 0)
31                 return sz;
32
33         buf = alloca(sz * 3);
34         ret = mprotect(GET_PAGE_ADDR(buf, sz), sz,
35                        PROT_READ | PROT_WRITE | PROT_EXEC);
36         return ret;
37 }
38
39 int exec_cmd(int *monitored_pid)
40 {
41         int child_pid, child_status;
42
43         child_pid = fork();
44         if (child_pid == 0) {
45                 *monitored_pid = getpid();
46                 execvp(CMD_ARGS[0], CMD_ARGS);
47                 return -EINVAL;
48         } else if (child_pid > 0) {
49                 waitpid(child_pid, &child_status, 0);
50                 return child_status;
51         }
52
53         return -EINVAL;
54 }
55
56 static int test_lsm(struct lsm *skel)
57 {
58         struct bpf_link *link;
59         int buf = 1234;
60         int err;
61
62         err = lsm__attach(skel);
63         if (CHECK(err, "attach", "lsm attach failed: %d\n", err))
64                 return err;
65
66         /* Check that already linked program can't be attached again. */
67         link = bpf_program__attach(skel->progs.test_int_hook);
68         if (CHECK(!IS_ERR(link), "attach_link",
69                   "re-attach without detach should not succeed"))
70                 return -1;
71
72         err = exec_cmd(&skel->bss->monitored_pid);
73         if (CHECK(err < 0, "exec_cmd", "err %d errno %d\n", err, errno))
74                 return err;
75
76         CHECK(skel->bss->bprm_count != 1, "bprm_count", "bprm_count = %d\n",
77               skel->bss->bprm_count);
78
79         skel->bss->monitored_pid = getpid();
80
81         err = stack_mprotect();
82         if (CHECK(errno != EPERM, "stack_mprotect", "want err=EPERM, got %d\n",
83                   errno))
84                 return err;
85
86         CHECK(skel->bss->mprotect_count != 1, "mprotect_count",
87               "mprotect_count = %d\n", skel->bss->mprotect_count);
88
89         syscall(__NR_setdomainname, &buf, -2L);
90         syscall(__NR_setdomainname, 0, -3L);
91         syscall(__NR_setdomainname, ~0L, -4L);
92
93         CHECK(skel->bss->copy_test != 3, "copy_test",
94               "copy_test = %d\n", skel->bss->copy_test);
95
96         lsm__detach(skel);
97
98         skel->bss->copy_test = 0;
99         skel->bss->bprm_count = 0;
100         skel->bss->mprotect_count = 0;
101         return 0;
102 }
103
104 void test_test_lsm(void)
105 {
106         struct lsm *skel = NULL;
107         int err;
108
109         skel = lsm__open_and_load();
110         if (CHECK(!skel, "lsm_skel_load", "lsm skeleton failed\n"))
111                 goto close_prog;
112
113         err = test_lsm(skel);
114         if (CHECK(err, "test_lsm", "first attach failed\n"))
115                 goto close_prog;
116
117         err = test_lsm(skel);
118         CHECK(err, "test_lsm", "second attach failed\n");
119
120 close_prog:
121         lsm__destroy(skel);
122 }