1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <test_progs.h>
4 
5 #include "cgroup_helpers.h"
6 
7 #define FOO		"/foo"
8 #define BAR		"/foo/bar/"
9 #define PING_CMD	"ping -q -c1 -w1 127.0.0.1 > /dev/null"
10 
11 char bpf_log_buf[BPF_LOG_BUF_SIZE];
12 
13 static int prog_load(int verdict)
14 {
15 	struct bpf_insn prog[] = {
16 		BPF_MOV64_IMM(BPF_REG_0, verdict), /* r0 = verdict */
17 		BPF_EXIT_INSN(),
18 	};
19 	size_t insns_cnt = sizeof(prog) / sizeof(struct bpf_insn);
20 
21 	return bpf_load_program(BPF_PROG_TYPE_CGROUP_SKB,
22 			       prog, insns_cnt, "GPL", 0,
23 			       bpf_log_buf, BPF_LOG_BUF_SIZE);
24 }
25 
26 void test_cgroup_attach_override(void)
27 {
28 	int drop_prog = -1, allow_prog = -1, foo = -1, bar = -1;
29 	__u32 duration = 0;
30 
31 	allow_prog = prog_load(1);
32 	if (CHECK(allow_prog < 0, "prog_load_allow",
33 		  "verifier output:\n%s\n-------\n", bpf_log_buf))
34 		goto err;
35 
36 	drop_prog = prog_load(0);
37 	if (CHECK(drop_prog < 0, "prog_load_drop",
38 		  "verifier output:\n%s\n-------\n", bpf_log_buf))
39 		goto err;
40 
41 	foo = test__join_cgroup(FOO);
42 	if (CHECK(foo < 0, "cgroup_join_foo", "cgroup setup failed\n"))
43 		goto err;
44 
45 	if (CHECK(bpf_prog_attach(drop_prog, foo, BPF_CGROUP_INET_EGRESS,
46 				  BPF_F_ALLOW_OVERRIDE),
47 		  "prog_attach_drop_foo_override",
48 		  "attach prog to %s failed, errno=%d\n", FOO, errno))
49 		goto err;
50 
51 	if (CHECK(!system(PING_CMD), "ping_fail",
52 		  "ping unexpectedly succeeded\n"))
53 		goto err;
54 
55 	bar = test__join_cgroup(BAR);
56 	if (CHECK(bar < 0, "cgroup_join_bar", "cgroup setup failed\n"))
57 		goto err;
58 
59 	if (CHECK(!system(PING_CMD), "ping_fail",
60 		  "ping unexpectedly succeeded\n"))
61 		goto err;
62 
63 	if (CHECK(bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS,
64 				  BPF_F_ALLOW_OVERRIDE),
65 		  "prog_attach_allow_bar_override",
66 		  "attach prog to %s failed, errno=%d\n", BAR, errno))
67 		goto err;
68 
69 	if (CHECK(system(PING_CMD), "ping_ok", "ping failed\n"))
70 		goto err;
71 
72 	if (CHECK(bpf_prog_detach(bar, BPF_CGROUP_INET_EGRESS),
73 		  "prog_detach_bar",
74 		  "detach prog from %s failed, errno=%d\n", BAR, errno))
75 		goto err;
76 
77 	if (CHECK(!system(PING_CMD), "ping_fail",
78 		  "ping unexpectedly succeeded\n"))
79 		goto err;
80 
81 	if (CHECK(bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS,
82 				  BPF_F_ALLOW_OVERRIDE),
83 		  "prog_attach_allow_bar_override",
84 		  "attach prog to %s failed, errno=%d\n", BAR, errno))
85 		goto err;
86 
87 	if (CHECK(bpf_prog_detach(foo, BPF_CGROUP_INET_EGRESS),
88 		  "prog_detach_foo",
89 		  "detach prog from %s failed, errno=%d\n", FOO, errno))
90 		goto err;
91 
92 	if (CHECK(system(PING_CMD), "ping_ok", "ping failed\n"))
93 		goto err;
94 
95 	if (CHECK(bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS,
96 				  BPF_F_ALLOW_OVERRIDE),
97 		  "prog_attach_allow_bar_override",
98 		  "attach prog to %s failed, errno=%d\n", BAR, errno))
99 		goto err;
100 
101 	if (CHECK(!bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS, 0),
102 		  "fail_prog_attach_allow_bar_none",
103 		  "attach prog to %s unexpectedly succeeded\n", BAR))
104 		goto err;
105 
106 	if (CHECK(bpf_prog_detach(bar, BPF_CGROUP_INET_EGRESS),
107 		  "prog_detach_bar",
108 		  "detach prog from %s failed, errno=%d\n", BAR, errno))
109 		goto err;
110 
111 	if (CHECK(!bpf_prog_detach(foo, BPF_CGROUP_INET_EGRESS),
112 		  "fail_prog_detach_foo",
113 		  "double detach from %s unexpectedly succeeded\n", FOO))
114 		goto err;
115 
116 	if (CHECK(bpf_prog_attach(allow_prog, foo, BPF_CGROUP_INET_EGRESS, 0),
117 		  "prog_attach_allow_foo_none",
118 		  "attach prog to %s failed, errno=%d\n", FOO, errno))
119 		goto err;
120 
121 	if (CHECK(!bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS, 0),
122 		  "fail_prog_attach_allow_bar_none",
123 		  "attach prog to %s unexpectedly succeeded\n", BAR))
124 		goto err;
125 
126 	if (CHECK(!bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS,
127 				   BPF_F_ALLOW_OVERRIDE),
128 		  "fail_prog_attach_allow_bar_override",
129 		  "attach prog to %s unexpectedly succeeded\n", BAR))
130 		goto err;
131 
132 	if (CHECK(!bpf_prog_attach(allow_prog, foo, BPF_CGROUP_INET_EGRESS,
133 				   BPF_F_ALLOW_OVERRIDE),
134 		  "fail_prog_attach_allow_foo_override",
135 		  "attach prog to %s unexpectedly succeeded\n", FOO))
136 		goto err;
137 
138 	if (CHECK(bpf_prog_attach(drop_prog, foo, BPF_CGROUP_INET_EGRESS, 0),
139 		  "prog_attach_drop_foo_none",
140 		  "attach prog to %s failed, errno=%d\n", FOO, errno))
141 		goto err;
142 
143 err:
144 	close(foo);
145 	close(bar);
146 	close(allow_prog);
147 	close(drop_prog);
148 }
149