xref: /linux/security/apparmor/af_inet.c (revision 89ac6aa752ec8b7b43d8d88a3e7719d1868d582a)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * AppArmor security module
4  *
5  * This file contains AppArmor inet fine grained mediation
6  *
7  * Copyright 2024 Canonical Ltd.
8  *
9  */
10 
11 #include <net/tcp_states.h>
12 
13 #include "include/audit.h"
14 #include "include/af_inet.h"
15 #include "include/apparmor.h"
16 #include "include/file.h"
17 #include "include/label.h"
18 #include "include/net.h"
19 #include "include/path.h"
20 #include "include/policy.h"
21 #include "include/cred.h"
22 
23 
24 static inline aa_state_t RULE_MEDIATES_SK(struct aa_ruleset *rules,
25 					  const struct sock *sk)
26 {
27 	return RULE_MEDIATES_NET(rules);
28 }
29 
30 
31 enum addr_type {
32 	ADDR_LOCAL = 0,
33 	ADDR_LOCAL_PRIV	= 1,
34 	ADDR_REMOTE = 2,
35 };
36 
37 struct match_addr {
38 	const char *addrp;
39 	enum addr_type addrtype;
40 	int len;
41 	__be16 port;
42 };
43 
44 struct stored_match_addr {
45 	union {
46 		struct sockaddr addr;
47 		struct sockaddr_in addr4;
48 		struct sockaddr_in6 addr6;
49 	};
50 	int addrlen;
51 	struct match_addr maddr;
52 };
53 
54 static void set_ad_create(struct apparmor_audit_data *ad,
55 			 int family, int type, int protocol)
56 {
57 	ad->common.u.net->family = family;
58 	ad->net.type = type;
59 	ad->net.protocol = protocol;
60 }
61 
62 static int set_ad_addr(struct apparmor_audit_data *ad,
63 		       u16 family, bool source, struct match_addr *maddr)
64 {
65 	ad->common.u.net->family = family;
66 
67 	if (source) {
68 		ad->common.u.net->sport = maddr->port;
69 		if (maddr->addrp) {
70 			if (family == AF_INET)
71 				/* ad.u.net->v4info.saddr = addr4->sin_addr.s_addr; */
72 				ad->common.u.net->v4info.saddr = *(__be32 *)maddr->addrp;
73 			else
74 				/* ad.u.net->v4info.saddr = addr6->sin6_addr.s6_addr; */
75 				ad->common.u.net->v6info.saddr = *(struct in6_addr *)maddr->addrp;
76 		}
77 	} else {
78 		ad->common.u.net->dport = maddr->port;
79 		if (maddr->addrp) {
80 			if (family == AF_INET)
81 				/* ad.u.net->v4info.saddr = addr4->sin_addr.s_addr; */
82 				ad->common.u.net->v4info.daddr = *(__be32 *)maddr->addrp;
83 			else
84 				/* ad.u.net->v4info.saddr = addr6->sin6_addr.s6_addr; */
85 				ad->common.u.net->v6info.daddr = *(struct in6_addr *)maddr->addrp;
86 		}
87 	}
88 	return 0;
89 }
90 
91 /* returns 0 on success
92 * raw_port - if set raw_port (protocol) when SOCK_RAW */
93 static int map_addr(struct sockaddr *addr, int addrlen, u16 raw_port,
94 		    enum addr_type addrtype, struct match_addr *maddr,
95 		    struct apparmor_audit_data *ad)
96 {
97 	struct sockaddr_in *addr4 = NULL;
98 	struct sockaddr_in6 *addr6 = NULL;
99 
100 	AA_BUG(!addr);
101 	AA_BUG(!maddr);
102 
103 	maddr->addrtype = addrtype;
104 	if (!addr || addrlen < offsetofend(struct sockaddr, sa_family)) {
105 		maddr->addrp = NULL;
106 		maddr->port = 0;
107 		maddr->len = 0;
108 		return 0;
109 	}
110 
111 	/*
112 	 * its possibly to have sk->sk_family == PF_INET6 and
113 	 * addr->sa_family == AF_INET. sk_family is used for socket
114 	 * mediation, sa_family for when we have address ...
115 	 */
116 	switch (addr->sa_family) {
117 	case AF_INET:
118 		addr4 = (struct sockaddr_in *)addr;
119 		if (addrlen < sizeof(struct sockaddr_in))
120 			return -EINVAL;
121 		maddr->port = addr4->sin_port;
122 		maddr->addrp = (char *)&addr4->sin_addr.s_addr;
123 		maddr->len = 4;
124 		break;
125 	case AF_INET6:
126 		addr6 = (struct sockaddr_in6 *)addr;
127 		if (addrlen < SIN6_LEN_RFC2133)
128 			return -EINVAL;
129 		maddr->port = addr6->sin6_port;
130 		maddr->addrp = (char *)&addr6->sin6_addr.s6_addr;
131 		maddr->len = 16;
132 		break;
133 	default:
134 		return -EAFNOSUPPORT;
135 	}
136 	/* per ip spec, && sk->sk_type == SOCK_RAW*/
137 	if (raw_port && addrtype != ADDR_REMOTE)
138 		maddr->port = htons(raw_port);
139 	if (ad)
140 		set_ad_addr(ad, addr->sa_family, addrtype != ADDR_REMOTE, maddr);
141 
142 	return 0;
143 }
144 
145 /* -ENOTCONN if not connected */
146 static int map_sock_addr(struct socket *sock, enum addr_type addrtype,
147 			 struct stored_match_addr *maddr,
148 			 struct apparmor_audit_data *ad)
149 {
150 	/* do we need early bailout for !family ... */
151 	maddr->addrlen = sock->ops->getname(sock, (struct sockaddr *) &maddr->addr, addrtype != ADDR_REMOTE ? 0 : 1);
152 	if (maddr->addrlen == -ENOTCONN) {
153 		maddr->addrlen = 0;
154 		return map_addr(NULL, 0, 0, addrtype, &maddr->maddr, ad);
155 	} else if (maddr->addrlen < 0)
156 		return maddr->addrlen;
157 	return map_addr(&maddr->addr, maddr->addrlen, 0, addrtype,
158 			&maddr->maddr, ad);
159 }
160 
161 /* TODO: combine with connect map addr */
162 /* TODO: raw_port */
163 static int bind_map_addr(const struct sock *sk, struct sockaddr *addr,
164 			 int addrlen,
165 			 struct match_addr *maddr,
166 			 struct apparmor_audit_data *ad)
167 {
168 	struct sockaddr_in *addr4 = NULL;
169 	struct sockaddr_in6 *addr6 = NULL;
170 	u16 family;
171 
172 	AA_BUG(!sk);
173 	AA_BUG(!addr);
174 	AA_BUG(!maddr);
175 
176 	if (addrlen < offsetofend(struct sockaddr, sa_family))
177 		return -EINVAL;
178 
179 	maddr->addrtype = ADDR_LOCAL;
180 	/*
181 	 * its possibly to have sk->sk_family == PF_INET6 and
182 	 * addr->sa_family == AF_INET. sk_family is used for socket
183 	 * mediation, sa_family for when we have address ...
184 	 */
185 	family = addr->sa_family;
186 	switch (addr->sa_family) {
187 	case AF_UNSPEC:
188 		if (sk->sk_family == PF_INET6) {
189 			/* Length check from inet6_bind_sk() */
190 			if (addrlen < SIN6_LEN_RFC2133)
191 				return -EINVAL;
192 			/* Family check from __inet6_bind() */
193 			return -EAFNOSUPPORT;
194 		}
195 		/* see __inet_bind(), we only want to allow
196 		 * AF_UNSPEC if the address is INADDR_ANY
197 		 */
198 		addr4 = (struct sockaddr_in *)addr;
199 		if (addr4->sin_addr.s_addr != htonl(INADDR_ANY))
200 			return -EAFNOSUPPORT;
201 		family = AF_INET;
202 		fallthrough;
203 	case AF_INET:
204 		addr4 = (struct sockaddr_in *)addr;
205 		if (addrlen < sizeof(struct sockaddr_in))
206 			return -EINVAL;
207 		maddr->port = addr4->sin_port;
208 		maddr->addrp = (char *)&addr4->sin_addr.s_addr;
209 		maddr->len = 4;
210 		break;
211 	case AF_INET6:
212 		addr6 = (struct sockaddr_in6 *)addr;
213 		if (addrlen < SIN6_LEN_RFC2133)
214 			return -EINVAL;
215 		maddr->port = addr6->sin6_port;
216 		maddr->addrp = (char *)&addr6->sin6_addr.s6_addr;
217 		maddr->len = 16;
218 		break;
219 	default:
220 		return -EAFNOSUPPORT;
221 	}
222 
223 	if (ad)
224 		set_ad_addr(ad, family, true, maddr);
225 
226 	return 0;
227 }
228 
229 
230 static inline int profile_sk_perm(struct aa_profile *profile, u32 request,
231 				  const struct sock *sk,
232 				  struct match_addr *maddr,
233 				  struct apparmor_audit_data *ad)
234 {
235 	AA_BUG(!profile);
236 	AA_BUG(!sk);
237 
238 	return aa_profile_af_sk_perm(profile, ad, request, sk);
239 }
240 
241 /* no kernel_t bailout */
242 static int profile_create_perm(struct aa_profile *profile, int family,
243 			       int type, int protocol,
244 			       struct apparmor_audit_data *ad)
245 {
246 	AA_BUG(!profile);
247 
248 	return aa_profile_af_perm(profile, ad, AA_MAY_CREATE, family, type,
249 				  protocol);
250 }
251 
252 
253 /* sendmsg/rcvmsg/connect */
254 static int profile_remote_perm(struct aa_profile *profile,
255 			       const struct sock *sk,
256 			       u32 request, struct match_addr *raddr,
257 			       struct match_addr *laddr,
258 			       struct apparmor_audit_data *ad)
259 {
260 	AA_BUG(!profile);
261 	AA_BUG(!sk);
262 	AA_BUG(!raddr);
263 	AA_BUG(!laddr);
264 	AA_BUG(sk->sk_family != PF_INET && sk->sk_family != PF_INET6,
265 	       "family=%d", sk->sk_family);
266 
267 	return aa_profile_af_sk_perm(profile, ad, request, sk);
268 }
269 
270 static int profile_bind_perm(struct aa_profile *profile,
271 			     const struct sock *sk,
272 			     struct match_addr *maddr,
273 			     struct apparmor_audit_data *ad)
274 {
275 	return aa_profile_af_sk_perm(profile, ad, AA_MAY_BIND, sk);
276 
277 }
278 
279 static int profile_listen_perm(struct aa_profile *profile,
280 			       const struct sock *sk,
281 			       struct match_addr *maddr, int backlog,
282 			       struct apparmor_audit_data *ad)
283 {
284 	AA_BUG(!profile);
285 	AA_BUG(!sk);
286 	AA_BUG(!maddr);
287 	AA_BUG(sk->sk_family != PF_INET && sk->sk_family != PF_INET6,
288 	       "family=%d", sk->sk_family);
289 
290 	return aa_profile_af_sk_perm(profile, ad, AA_MAY_LISTEN, sk);
291 }
292 
293 static inline int profile_accept_perm(struct aa_profile *profile,
294 				      const struct sock *sk,
295 				      struct match_addr *maddr,
296 				      const struct sock *newsk,
297 				      struct apparmor_audit_data *ad)
298 {
299 	AA_BUG(!profile);
300 	AA_BUG(!sk);
301 	/* AA_BUG(!newsk);  newsk can be null here, since not using atm ... */
302 	AA_BUG(!maddr);
303 	AA_BUG(sk->sk_family != PF_INET && sk->sk_family != PF_INET6,
304 	       "family=%d", sk->sk_family);
305 
306 	return aa_profile_af_sk_perm(profile, ad, AA_MAY_ACCEPT, sk);
307 }
308 
309 /* getopt/setopt */
310 static int profile_opt_perm(struct aa_profile *profile, u32 request,
311 			    const struct sock *sk, struct match_addr *maddr,
312 			    int level, int optname,
313 			    struct apparmor_audit_data *ad)
314 {
315 	AA_BUG(!profile);
316 	AA_BUG(!sk);
317 	AA_BUG(!maddr);
318 	AA_BUG(sk->sk_family != PF_INET && sk->sk_family != PF_INET6,
319 	       "family=%d", sk->sk_family);
320 
321 	return aa_profile_af_sk_perm(profile, ad, request, sk);
322 }
323 
324 /* ---------------------------------------------------------------------- */
325 
326 // TODO: cleanup init to use recursion, so we can have N init fns, in 1 macro
327 // TODO: lift DEFINE_AUDIT out of macro into init fn???
328 
329 /* no kernel_t bailout */
330 #define label_sk_has_perm2(CRED, LABEL, SOCKSK, OP, REQUEST, PROFILE, AAD, XXXX, YYYY, CALLBACKFN) \
331 ({								\
332 	int __EERROR = 0;					\
333 	if (label_mediates(LABEL, AA_CLASS_NET)) {		\
334 		struct aa_profile *PROFILE;			\
335 		DEFINE_AUDIT_SK(AAD, OP, CRED, SOCKSK);		\
336 		(AAD).subj_cred = (CRED);			\
337 		(AAD).request = (REQUEST);			\
338 		__EERROR = (XXXX);				\
339 		if (__EERROR == 0) {				\
340 			__EERROR = (YYYY);			\
341 			if (__EERROR == 0) {			\
342 				__EERROR = fn_for_each(LABEL, PROFILE,	\
343 						       (CALLBACKFN));	\
344 			}						\
345 		}							\
346 	}							\
347 	__EERROR;						\
348 })
349 
350 /* no kernel_t bailout */
351 #define label_sk_has_perm(CRED, LABEL, SOCKSK, OP, REQUEST, PROFILE, AAD, CALLBACKFN) \
352 	label_sk_has_perm2(CRED, LABEL, SOCKSK, OP, REQUEST, PROFILE, AAD, \
353 			   0, 0, CALLBACKFN)
354 
355 /* no kernel_t bailout */
356 #define label_sk_has_perm1(CRED, LABEL, SOCKSK, OP, REQUEST, PROFILE, AAD, XXXX, CALLBACKFN) \
357 	label_sk_has_perm2(CRED, LABEL, SOCKSK, OP, REQUEST, PROFILE, AAD, \
358 			   XXXX, 0, CALLBACKFN)
359 
360 
361 /* Early bailout for kernel_t - 2 init args before callback */
362 #define sk_has_perm2(SOCKSK, OP, REQUEST, PROFILE, AAD, XXXXY, YYYYX, CALLBACKFN) \
363 ({									\
364 	struct aa_label *__label;					\
365 	struct aa_sk_ctx *__ctx = aa_sock(SOCKSK);			\
366 	int __ERROR = 0;						\
367 	bool __needput;						\
368 	if (rcu_access_pointer(__ctx->label) != kernel_t) {		\
369 									\
370 		__label = begin_current_label_crit_section(&__needput);	\
371                 __ERROR = label_sk_has_perm2(current_cred(), __label, SOCKSK, OP, REQUEST, PROFILE, AAD, XXXXY, YYYYX, CALLBACKFN); \
372 		end_current_label_crit_section(__label, __needput);	\
373 	}								\
374 	__ERROR;							\
375 })
376 
377 /* Early bailout for kernel_t - no init args before callback */
378 #define sk_has_perm(SOCKSK, OP, REQUEST, PROFILE, AAD, CALLBACKFN)	\
379 	sk_has_perm2(SOCKSK, OP, REQUEST, PROFILE, AAD, 0, 0, CALLBACKFN)
380 
381 
382 /* Early bailout for kernel_t - 1 init arg before callback */
383 #define sk_has_perm1(SOCKSK, OP, REQUEST, PROFILE, AAD, XXXXY, CALLBACKFN) \
384 	sk_has_perm2(SOCKSK, OP, REQUEST, PROFILE, AAD, XXXXY, 0, CALLBACKFN)
385 
386 
387 
388 /* no kernel_t early bailout */
389 /* NOTE: already lifted label_mediates into lsm.c */
390 int aa_inet_create_perm(struct aa_label *label, int family, int type,
391 			int protocol)
392 {
393 	struct aa_profile *profile;
394 	int error = 0;
395 	DEFINE_AUDIT_NET(ad, OP_CREATE, current_cred(), NULL, family, type,
396 			 protocol);
397 
398 	ad.subj_cred = current_cred();
399 	set_ad_create(&ad, family, type, protocol);
400 	error = fn_for_each(label, profile,
401 			    profile_create_perm(profile, family, type,
402 						protocol, &ad));
403 
404 	return error;
405 }
406 
407 int aa_inet_bind_perm(struct socket *sock, struct sockaddr *addr,
408 		      int addrlen)
409 {
410 	struct match_addr maddr;
411 
412 	return sk_has_perm1(sock->sk, OP_BIND, AA_MAY_BIND, profile, ad,
413 			    bind_map_addr(sock->sk, addr, addrlen, &maddr,
414 					  &ad),
415 			    profile_bind_perm(profile, sock->sk, &maddr, &ad));
416 }
417 
418 int aa_inet_connect_perm(struct socket *sock, struct sockaddr *addr,
419 			 int addrlen)
420 {
421 	struct stored_match_addr laddr;
422 	struct match_addr raddr;
423 
424 	/* disconnect socket */
425 	if (addrlen < offsetofend(struct sockaddr, sa_family))
426 		return -EINVAL;
427 	if (addr->sa_family == AF_UNSPEC)
428 		return 0;
429 
430 	/* do we need early bailout for !family ... */
431 	return sk_has_perm2(sock->sk, OP_CONNECT, AA_MAY_CONNECT, profile, ad,
432 			    map_sock_addr(sock, ADDR_LOCAL, &laddr, &ad),
433 			    map_addr(addr, addrlen, 0, ADDR_REMOTE, &raddr,
434 				     &ad),
435 			    profile_remote_perm(profile, sock->sk,
436 						AA_MAY_CONNECT, &raddr,
437 						&laddr.maddr, &ad));
438 }
439 
440 int aa_inet_listen_perm(struct socket *sock, int backlog)
441 {
442 	struct stored_match_addr maddr;
443 
444 	/* do we need early bailout for !family ... */
445 	return sk_has_perm1(sock->sk, OP_LISTEN, AA_MAY_LISTEN, profile, ad,
446 			    map_sock_addr(sock, ADDR_LOCAL, &maddr, &ad),
447 			    profile_listen_perm(profile, sock->sk, &maddr.maddr,
448 						backlog, &ad));
449 }
450 
451 /* ability of sock to connect, not peer address binding */
452 int aa_inet_accept_perm(struct socket *sock, struct socket *newsock)
453 {
454 	struct stored_match_addr maddr;
455 	int error;
456 
457 	error = sk_has_perm1(sock->sk, OP_ACCEPT, AA_MAY_ACCEPT, profile, ad,
458 			     map_sock_addr(sock, ADDR_LOCAL, &maddr, &ad),
459 			     profile_accept_perm(profile, sock->sk,
460 						 &maddr.maddr,
461 						 newsock->sk, &ad));
462 
463 	/* selinux updates inode - need to investigate this more */
464 	return error;
465 }
466 
467 /* sendmsg, recvmsg. */
468 int aa_inet_msg_perm(const char *op, u32 request, struct socket *sock,
469 		     struct msghdr *msg, int size)
470 {
471 	struct stored_match_addr laddr;
472 	struct match_addr raddr;
473 
474 	/* do we need early bailout for !family ... */
475 	return sk_has_perm2(sock->sk, op, request, profile, ad,
476 			    map_sock_addr(sock, ADDR_LOCAL, &laddr, &ad),
477 			    map_addr(msg->msg_name, msg->msg_namelen, 0,
478 				     ADDR_REMOTE, &raddr, &ad),
479 			    profile_remote_perm(profile, sock->sk, request,
480 						&raddr, &laddr.maddr, &ad));
481 }
482 
483 /* getopt, setopt */
484 int aa_inet_opt_perm(const char *op, u32 request, struct socket *sock,
485 		     int level, int optname)
486 {
487 	struct stored_match_addr maddr;
488 
489 	return sk_has_perm1(sock->sk, op, request, profile, ad,
490 			    map_sock_addr(sock, ADDR_LOCAL, &maddr, &ad),
491 			    profile_opt_perm(profile, request, sock->sk,
492 					    &maddr.maddr, level, optname, &ad));
493 }
494 
495 static int inet_label_sock_perm(const struct cred *cred, struct aa_label *label,
496 				const char *op, u32 request,
497 				struct socket *sock)
498 {
499 	struct stored_match_addr maddr;
500 
501 	return label_sk_has_perm1(cred, label, sock->sk, op, request, profile,
502 				  ad,
503 			map_sock_addr(sock, ADDR_LOCAL, &maddr, &ad),
504 			profile_sk_perm(profile, request, sock->sk,
505 					&maddr.maddr, &ad));
506 }
507 
508 /* revalidation, get/set attr/getsockname/peername */
509 int aa_inet_sock_perm(const char *op, u32 request, struct socket *sock)
510 {
511 	struct aa_sk_ctx *ctx = aa_sock(sock->sk);
512 	struct aa_label *label;
513 	bool needput;
514 	int error;
515 
516 	if (rcu_access_pointer(ctx->label) == kernel_t)
517 		return 0;
518 
519 	label = begin_current_label_crit_section(&needput);
520 	error = inet_label_sock_perm(current_cred(), label, op, request, sock);
521 	end_current_label_crit_section(label, needput);
522 
523 	return error;
524 }
525 
526 int aa_inet_file_perm(const struct cred *subj_cred, struct aa_label *label,
527 		      const char *op, u32 request, struct socket *sock)
528 {
529 	u32 sk_req = request & ~NET_PEER_MASK;
530 	struct stored_match_addr laddr;
531 	const struct sock *sk = sock->sk;
532 	int error = 0;
533 
534 	AA_BUG(!label);
535 	AA_BUG(!sock);
536 	AA_BUG(!sock->sk);
537 	AA_BUG(sk->sk_family != PF_INET && sk->sk_family != PF_INET6,
538 	       "family=%d", sk->sk_family);
539 
540 	/* access to the local sock */
541 	error = label_sk_has_perm1(subj_cred, label, sock->sk, op, request,
542 				   profile, ad,
543 			map_sock_addr(sock, ADDR_LOCAL, &laddr, &ad),
544 			profile_sk_perm(profile, sk_req, sock->sk, &laddr.maddr,
545 					&ad));
546 
547 	if (!error) {
548 		struct stored_match_addr raddr;
549 
550 		/* TODO: have ad here: instead of in CB so we do have to redo */
551 		error = map_sock_addr(sock, ADDR_REMOTE, &raddr, NULL);
552 		if (!error && raddr.maddr.addrp) {
553 			error = label_sk_has_perm1(subj_cred, label, sock->sk,
554 						   op, request, profile, ad,
555 					set_ad_addr(&ad, raddr.addr.sa_family,
556 						    false, &raddr.maddr),
557 					profile_remote_perm(profile, sock->sk,
558 							    request,
559 							    &raddr.maddr,
560 							    &laddr.maddr, &ad));
561 		}
562 	}
563 
564 	return error;
565 }
566