xref: /openbmc/linux/kernel/bpf/net_namespace.c (revision 34facb04)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <linux/bpf.h>
4 #include <linux/filter.h>
5 #include <net/net_namespace.h>
6 
7 /*
8  * Functions to manage BPF programs attached to netns
9  */
10 
11 struct bpf_netns_link {
12 	struct bpf_link	link;
13 	enum bpf_attach_type type;
14 	enum netns_bpf_attach_type netns_type;
15 
16 	/* We don't hold a ref to net in order to auto-detach the link
17 	 * when netns is going away. Instead we rely on pernet
18 	 * pre_exit callback to clear this pointer. Must be accessed
19 	 * with netns_bpf_mutex held.
20 	 */
21 	struct net *net;
22 };
23 
24 /* Protects updates to netns_bpf */
25 DEFINE_MUTEX(netns_bpf_mutex);
26 
27 /* Must be called with netns_bpf_mutex held. */
28 static void __net_exit bpf_netns_link_auto_detach(struct bpf_link *link)
29 {
30 	struct bpf_netns_link *net_link =
31 		container_of(link, struct bpf_netns_link, link);
32 
33 	net_link->net = NULL;
34 }
35 
36 static void bpf_netns_link_release(struct bpf_link *link)
37 {
38 	struct bpf_netns_link *net_link =
39 		container_of(link, struct bpf_netns_link, link);
40 	enum netns_bpf_attach_type type = net_link->netns_type;
41 	struct net *net;
42 
43 	/* Link auto-detached by dying netns. */
44 	if (!net_link->net)
45 		return;
46 
47 	mutex_lock(&netns_bpf_mutex);
48 
49 	/* Recheck after potential sleep. We can race with cleanup_net
50 	 * here, but if we see a non-NULL struct net pointer pre_exit
51 	 * has not happened yet and will block on netns_bpf_mutex.
52 	 */
53 	net = net_link->net;
54 	if (!net)
55 		goto out_unlock;
56 
57 	net->bpf.links[type] = NULL;
58 	RCU_INIT_POINTER(net->bpf.progs[type], NULL);
59 
60 out_unlock:
61 	mutex_unlock(&netns_bpf_mutex);
62 }
63 
64 static void bpf_netns_link_dealloc(struct bpf_link *link)
65 {
66 	struct bpf_netns_link *net_link =
67 		container_of(link, struct bpf_netns_link, link);
68 
69 	kfree(net_link);
70 }
71 
72 static int bpf_netns_link_update_prog(struct bpf_link *link,
73 				      struct bpf_prog *new_prog,
74 				      struct bpf_prog *old_prog)
75 {
76 	struct bpf_netns_link *net_link =
77 		container_of(link, struct bpf_netns_link, link);
78 	enum netns_bpf_attach_type type = net_link->netns_type;
79 	struct net *net;
80 	int ret = 0;
81 
82 	if (old_prog && old_prog != link->prog)
83 		return -EPERM;
84 	if (new_prog->type != link->prog->type)
85 		return -EINVAL;
86 
87 	mutex_lock(&netns_bpf_mutex);
88 
89 	net = net_link->net;
90 	if (!net || !check_net(net)) {
91 		/* Link auto-detached or netns dying */
92 		ret = -ENOLINK;
93 		goto out_unlock;
94 	}
95 
96 	old_prog = xchg(&link->prog, new_prog);
97 	rcu_assign_pointer(net->bpf.progs[type], new_prog);
98 	bpf_prog_put(old_prog);
99 
100 out_unlock:
101 	mutex_unlock(&netns_bpf_mutex);
102 	return ret;
103 }
104 
105 static int bpf_netns_link_fill_info(const struct bpf_link *link,
106 				    struct bpf_link_info *info)
107 {
108 	const struct bpf_netns_link *net_link =
109 		container_of(link, struct bpf_netns_link, link);
110 	unsigned int inum = 0;
111 	struct net *net;
112 
113 	mutex_lock(&netns_bpf_mutex);
114 	net = net_link->net;
115 	if (net && check_net(net))
116 		inum = net->ns.inum;
117 	mutex_unlock(&netns_bpf_mutex);
118 
119 	info->netns.netns_ino = inum;
120 	info->netns.attach_type = net_link->type;
121 	return 0;
122 }
123 
124 static void bpf_netns_link_show_fdinfo(const struct bpf_link *link,
125 				       struct seq_file *seq)
126 {
127 	struct bpf_link_info info = {};
128 
129 	bpf_netns_link_fill_info(link, &info);
130 	seq_printf(seq,
131 		   "netns_ino:\t%u\n"
132 		   "attach_type:\t%u\n",
133 		   info.netns.netns_ino,
134 		   info.netns.attach_type);
135 }
136 
137 static const struct bpf_link_ops bpf_netns_link_ops = {
138 	.release = bpf_netns_link_release,
139 	.dealloc = bpf_netns_link_dealloc,
140 	.update_prog = bpf_netns_link_update_prog,
141 	.fill_link_info = bpf_netns_link_fill_info,
142 	.show_fdinfo = bpf_netns_link_show_fdinfo,
143 };
144 
145 int netns_bpf_prog_query(const union bpf_attr *attr,
146 			 union bpf_attr __user *uattr)
147 {
148 	__u32 __user *prog_ids = u64_to_user_ptr(attr->query.prog_ids);
149 	u32 prog_id, prog_cnt = 0, flags = 0;
150 	enum netns_bpf_attach_type type;
151 	struct bpf_prog *attached;
152 	struct net *net;
153 
154 	if (attr->query.query_flags)
155 		return -EINVAL;
156 
157 	type = to_netns_bpf_attach_type(attr->query.attach_type);
158 	if (type < 0)
159 		return -EINVAL;
160 
161 	net = get_net_ns_by_fd(attr->query.target_fd);
162 	if (IS_ERR(net))
163 		return PTR_ERR(net);
164 
165 	rcu_read_lock();
166 	attached = rcu_dereference(net->bpf.progs[type]);
167 	if (attached) {
168 		prog_cnt = 1;
169 		prog_id = attached->aux->id;
170 	}
171 	rcu_read_unlock();
172 
173 	put_net(net);
174 
175 	if (copy_to_user(&uattr->query.attach_flags, &flags, sizeof(flags)))
176 		return -EFAULT;
177 	if (copy_to_user(&uattr->query.prog_cnt, &prog_cnt, sizeof(prog_cnt)))
178 		return -EFAULT;
179 
180 	if (!attr->query.prog_cnt || !prog_ids || !prog_cnt)
181 		return 0;
182 
183 	if (copy_to_user(prog_ids, &prog_id, sizeof(u32)))
184 		return -EFAULT;
185 
186 	return 0;
187 }
188 
189 int netns_bpf_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog)
190 {
191 	enum netns_bpf_attach_type type;
192 	struct net *net;
193 	int ret;
194 
195 	type = to_netns_bpf_attach_type(attr->attach_type);
196 	if (type < 0)
197 		return -EINVAL;
198 
199 	net = current->nsproxy->net_ns;
200 	mutex_lock(&netns_bpf_mutex);
201 
202 	/* Attaching prog directly is not compatible with links */
203 	if (net->bpf.links[type]) {
204 		ret = -EEXIST;
205 		goto out_unlock;
206 	}
207 
208 	switch (type) {
209 	case NETNS_BPF_FLOW_DISSECTOR:
210 		ret = flow_dissector_bpf_prog_attach(net, prog);
211 		break;
212 	default:
213 		ret = -EINVAL;
214 		break;
215 	}
216 out_unlock:
217 	mutex_unlock(&netns_bpf_mutex);
218 
219 	return ret;
220 }
221 
222 /* Must be called with netns_bpf_mutex held. */
223 static int __netns_bpf_prog_detach(struct net *net,
224 				   enum netns_bpf_attach_type type)
225 {
226 	struct bpf_prog *attached;
227 
228 	/* Progs attached via links cannot be detached */
229 	if (net->bpf.links[type])
230 		return -EINVAL;
231 
232 	attached = rcu_dereference_protected(net->bpf.progs[type],
233 					     lockdep_is_held(&netns_bpf_mutex));
234 	if (!attached)
235 		return -ENOENT;
236 	RCU_INIT_POINTER(net->bpf.progs[type], NULL);
237 	bpf_prog_put(attached);
238 	return 0;
239 }
240 
241 int netns_bpf_prog_detach(const union bpf_attr *attr)
242 {
243 	enum netns_bpf_attach_type type;
244 	int ret;
245 
246 	type = to_netns_bpf_attach_type(attr->attach_type);
247 	if (type < 0)
248 		return -EINVAL;
249 
250 	mutex_lock(&netns_bpf_mutex);
251 	ret = __netns_bpf_prog_detach(current->nsproxy->net_ns, type);
252 	mutex_unlock(&netns_bpf_mutex);
253 
254 	return ret;
255 }
256 
257 static int netns_bpf_link_attach(struct net *net, struct bpf_link *link,
258 				 enum netns_bpf_attach_type type)
259 {
260 	struct bpf_prog *prog;
261 	int err;
262 
263 	mutex_lock(&netns_bpf_mutex);
264 
265 	/* Allow attaching only one prog or link for now */
266 	if (net->bpf.links[type]) {
267 		err = -E2BIG;
268 		goto out_unlock;
269 	}
270 	/* Links are not compatible with attaching prog directly */
271 	prog = rcu_dereference_protected(net->bpf.progs[type],
272 					 lockdep_is_held(&netns_bpf_mutex));
273 	if (prog) {
274 		err = -EEXIST;
275 		goto out_unlock;
276 	}
277 
278 	switch (type) {
279 	case NETNS_BPF_FLOW_DISSECTOR:
280 		err = flow_dissector_bpf_prog_attach(net, link->prog);
281 		break;
282 	default:
283 		err = -EINVAL;
284 		break;
285 	}
286 	if (err)
287 		goto out_unlock;
288 
289 	net->bpf.links[type] = link;
290 
291 out_unlock:
292 	mutex_unlock(&netns_bpf_mutex);
293 	return err;
294 }
295 
296 int netns_bpf_link_create(const union bpf_attr *attr, struct bpf_prog *prog)
297 {
298 	enum netns_bpf_attach_type netns_type;
299 	struct bpf_link_primer link_primer;
300 	struct bpf_netns_link *net_link;
301 	enum bpf_attach_type type;
302 	struct net *net;
303 	int err;
304 
305 	if (attr->link_create.flags)
306 		return -EINVAL;
307 
308 	type = attr->link_create.attach_type;
309 	netns_type = to_netns_bpf_attach_type(type);
310 	if (netns_type < 0)
311 		return -EINVAL;
312 
313 	net = get_net_ns_by_fd(attr->link_create.target_fd);
314 	if (IS_ERR(net))
315 		return PTR_ERR(net);
316 
317 	net_link = kzalloc(sizeof(*net_link), GFP_USER);
318 	if (!net_link) {
319 		err = -ENOMEM;
320 		goto out_put_net;
321 	}
322 	bpf_link_init(&net_link->link, BPF_LINK_TYPE_NETNS,
323 		      &bpf_netns_link_ops, prog);
324 	net_link->net = net;
325 	net_link->type = type;
326 	net_link->netns_type = netns_type;
327 
328 	err = bpf_link_prime(&net_link->link, &link_primer);
329 	if (err) {
330 		kfree(net_link);
331 		goto out_put_net;
332 	}
333 
334 	err = netns_bpf_link_attach(net, &net_link->link, netns_type);
335 	if (err) {
336 		bpf_link_cleanup(&link_primer);
337 		goto out_put_net;
338 	}
339 
340 	put_net(net);
341 	return bpf_link_settle(&link_primer);
342 
343 out_put_net:
344 	put_net(net);
345 	return err;
346 }
347 
348 static void __net_exit netns_bpf_pernet_pre_exit(struct net *net)
349 {
350 	enum netns_bpf_attach_type type;
351 	struct bpf_link *link;
352 
353 	mutex_lock(&netns_bpf_mutex);
354 	for (type = 0; type < MAX_NETNS_BPF_ATTACH_TYPE; type++) {
355 		link = net->bpf.links[type];
356 		if (link)
357 			bpf_netns_link_auto_detach(link);
358 		else
359 			__netns_bpf_prog_detach(net, type);
360 	}
361 	mutex_unlock(&netns_bpf_mutex);
362 }
363 
364 static struct pernet_operations netns_bpf_pernet_ops __net_initdata = {
365 	.pre_exit = netns_bpf_pernet_pre_exit,
366 };
367 
368 static int __init netns_bpf_init(void)
369 {
370 	return register_pernet_subsys(&netns_bpf_pernet_ops);
371 }
372 
373 subsys_initcall(netns_bpf_init);
374