xref: /linux/security/apparmor/af_unix.c (revision 8fefe68784ae1606e11a5c65c04167c3b95051a0)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * AppArmor security module
4  *
5  * This file contains AppArmor af_unix fine grained mediation
6  *
7  * Copyright 2023 Canonical Ltd.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation, version 2 of the
12  * License.
13  */
14 
15 #include <linux/fs.h>
16 #include <net/tcp_states.h>
17 
18 #include "include/audit.h"
19 #include "include/af_unix.h"
20 #include "include/apparmor.h"
21 #include "include/file.h"
22 #include "include/label.h"
23 #include "include/net.h"
24 #include "include/path.h"
25 #include "include/policy.h"
26 #include "include/cred.h"
27 
28 
aa_unix_sk(struct unix_sock * u)29 static inline struct sock *aa_unix_sk(struct unix_sock *u)
30 {
31 	return &u->sk;
32 }
33 
unix_fs_perm(const char * op,u32 mask,const struct cred * subj_cred,struct aa_label * label,const struct path * path)34 static int unix_fs_perm(const char *op, u32 mask, const struct cred *subj_cred,
35 			struct aa_label *label, const struct path *path)
36 {
37 	AA_BUG(!label);
38 	AA_BUG(!path);
39 
40 	if (unconfined(label) || !label_mediates(label, AA_CLASS_FILE))
41 		return 0;
42 
43 	mask &= NET_FS_PERMS;
44 	/* if !u->path.dentry socket is being shutdown - implicit delegation
45 	 * until obj delegation is supported
46 	 */
47 	if (path->dentry) {
48 		/* the sunpath may not be valid for this ns so use the path */
49 		struct inode *inode = path->dentry->d_inode;
50 		vfsuid_t vfsuid = i_uid_into_vfsuid(mnt_idmap(path->mnt), inode);
51 		struct path_cond cond = {
52 			.uid = vfsuid_into_kuid(vfsuid),
53 			.mode = inode->i_mode,
54 		};
55 
56 		return aa_path_perm(op, subj_cred, label, path,
57 				    PATH_SOCK_COND, mask, &cond);
58 	} /* else implicitly delegated */
59 
60 	return 0;
61 }
62 
63 /* match_addr special constants */
64 #define ABSTRACT_ADDR "\x00"		/* abstract socket addr */
65 #define ANONYMOUS_ADDR "\x01"		/* anonymous endpoint, no addr */
66 #define DISCONNECTED_ADDR "\x02"	/* addr is another namespace */
67 #define SHUTDOWN_ADDR "\x03"		/* path addr is shutdown and cleared */
68 #define FS_ADDR "/"			/* path addr in fs */
69 
match_addr(const struct aa_dfa * dfa,aa_state_t state,struct sockaddr_un * addr,int addrlen)70 static aa_state_t match_addr(const struct aa_dfa *dfa, aa_state_t state,
71 			     struct sockaddr_un *addr, int addrlen)
72 {
73 	if (addr)
74 		/* include leading \0 */
75 		state = aa_dfa_match_len(dfa, state, addr->sun_path,
76 					 unix_addr_len(addrlen));
77 	else
78 		state = aa_dfa_match_len(dfa, state, ANONYMOUS_ADDR, 1);
79 	/* todo: could change to out of band for cleaner separation */
80 	state = aa_dfa_null_transition(dfa, state);
81 
82 	return state;
83 }
84 
match_to_local(struct aa_policydb * policy,aa_state_t state,u32 request,int type,int protocol,struct sockaddr_un * addr,int addrlen,struct aa_perms ** p,const char ** info)85 static aa_state_t match_to_local(struct aa_policydb *policy,
86 				 aa_state_t state, u32 request,
87 				 int type, int protocol,
88 				 struct sockaddr_un *addr, int addrlen,
89 				 struct aa_perms **p,
90 				 const char **info)
91 {
92 	state = aa_match_to_prot(policy, state, request, PF_UNIX, type,
93 				 protocol, NULL, info);
94 	if (state) {
95 		state = match_addr(policy->dfa, state, addr, addrlen);
96 		if (state) {
97 			/* todo: local label matching */
98 			state = aa_dfa_null_transition(policy->dfa, state);
99 			if (!state)
100 				*info = "failed local label match";
101 		} else {
102 			*info = "failed local address match";
103 		}
104 	}
105 
106 	return state;
107 }
108 
aa_sunaddr(const struct unix_sock * u,int * addrlen)109 struct sockaddr_un *aa_sunaddr(const struct unix_sock *u, int *addrlen)
110 {
111 	struct unix_address *addr;
112 
113 	/* memory barrier is sufficient see note in net/unix/af_unix.c */
114 	addr = smp_load_acquire(&u->addr);
115 	if (addr) {
116 		*addrlen = addr->len;
117 		return addr->name;
118 	}
119 	*addrlen = 0;
120 	return NULL;
121 }
122 
match_to_sk(struct aa_policydb * policy,aa_state_t state,u32 request,struct unix_sock * u,struct aa_perms ** p,const char ** info)123 static aa_state_t match_to_sk(struct aa_policydb *policy,
124 			      aa_state_t state, u32 request,
125 			      struct unix_sock *u, struct aa_perms **p,
126 			      const char **info)
127 {
128 	int addrlen;
129 	struct sockaddr_un *addr = aa_sunaddr(u, &addrlen);
130 
131 	return match_to_local(policy, state, request, u->sk.sk_type,
132 			      u->sk.sk_protocol, addr, addrlen, p, info);
133 }
134 
135 #define CMD_ADDR	1
136 #define CMD_LISTEN	2
137 #define CMD_OPT		4
138 
match_to_cmd(struct aa_policydb * policy,aa_state_t state,u32 request,struct unix_sock * u,char cmd,struct aa_perms ** p,const char ** info)139 static aa_state_t match_to_cmd(struct aa_policydb *policy, aa_state_t state,
140 			       u32 request, struct unix_sock *u,
141 			       char cmd, struct aa_perms **p,
142 			       const char **info)
143 {
144 	AA_BUG(!p);
145 
146 	state = match_to_sk(policy, state, request, u, p, info);
147 	if (state && !*p) {
148 		state = aa_dfa_match_len(policy->dfa, state, &cmd, 1);
149 		if (!state)
150 			*info = "failed cmd selection match";
151 	}
152 
153 	return state;
154 }
155 
match_to_peer(struct aa_policydb * policy,aa_state_t state,u32 request,struct unix_sock * u,struct sockaddr_un * peer_addr,int peer_addrlen,struct aa_perms ** p,const char ** info)156 static aa_state_t match_to_peer(struct aa_policydb *policy, aa_state_t state,
157 				u32 request, struct unix_sock *u,
158 				struct sockaddr_un *peer_addr, int peer_addrlen,
159 				struct aa_perms **p, const char **info)
160 {
161 	AA_BUG(!p);
162 
163 	state = match_to_cmd(policy, state, request, u, CMD_ADDR, p, info);
164 	if (state && !*p) {
165 		state = match_addr(policy->dfa, state, peer_addr, peer_addrlen);
166 		if (!state)
167 			*info = "failed peer address match";
168 	}
169 
170 	return state;
171 }
172 
match_label(struct aa_profile * profile,struct aa_ruleset * rule,aa_state_t state,u32 request,struct aa_profile * peer,const struct aa_perms * p,struct apparmor_audit_data * ad)173 static aa_state_t match_label(struct aa_profile *profile,
174 			      struct aa_ruleset *rule, aa_state_t state,
175 			      u32 request, struct aa_profile *peer,
176 			      const struct aa_perms *p,
177 			      struct apparmor_audit_data *ad)
178 {
179 	AA_BUG(!profile);
180 	AA_BUG(!peer);
181 
182 	ad->peer = &peer->label;
183 
184 	if (state && !p) {
185 		state = aa_dfa_match(rule->policy->dfa, state,
186 				     peer->base.hname);
187 		if (!state)
188 			ad->info = "failed peer label match";
189 
190 	}
191 
192 	return aa_do_perms(profile, rule->policy, state, request, p, ad);
193 }
194 
195 
196 /* unix sock creation comes before we know if the socket will be an fs
197  * socket
198  * v6 - semantics are handled by mapping in profile load
199  * v7 - semantics require sock create for tasks creating an fs socket.
200  * v8 - same as v7
201  */
profile_create_perm(struct aa_profile * profile,int family,int type,int protocol,struct apparmor_audit_data * ad)202 static int profile_create_perm(struct aa_profile *profile, int family,
203 			       int type, int protocol,
204 			       struct apparmor_audit_data *ad)
205 {
206 	struct aa_ruleset *rules = profile->label.rules[0];
207 	aa_state_t state;
208 
209 	AA_BUG(!profile);
210 	AA_BUG(profile_unconfined(profile));
211 
212 	state = RULE_MEDIATES_UNIX(rules);
213 	if (state) {
214 		state = aa_match_to_prot(rules->policy, state, AA_MAY_CREATE,
215 					 PF_UNIX, type, protocol, NULL,
216 					 &ad->info);
217 
218 		return aa_do_perms(profile, rules->policy, state, AA_MAY_CREATE,
219 				   NULL, ad);
220 	}
221 
222 	return aa_profile_af_perm(profile, ad, AA_MAY_CREATE, family, type,
223 				  protocol);
224 }
225 
profile_sk_perm(struct aa_profile * profile,struct apparmor_audit_data * ad,u32 request,struct sock * sk,const struct path * path)226 static int profile_sk_perm(struct aa_profile *profile,
227 			   struct apparmor_audit_data *ad,
228 			   u32 request, struct sock *sk, const struct path *path)
229 {
230 	struct aa_ruleset *rules = profile->label.rules[0];
231 	struct aa_perms *p = NULL;
232 	aa_state_t state;
233 
234 	AA_BUG(!profile);
235 	AA_BUG(!sk);
236 	AA_BUG(profile_unconfined(profile));
237 
238 	state = RULE_MEDIATES_UNIX(rules);
239 	if (state) {
240 		if (is_unix_fs(sk))
241 			return unix_fs_perm(ad->op, request, ad->subj_cred,
242 					    &profile->label,
243 					    &unix_sk(sk)->path);
244 
245 		state = match_to_sk(rules->policy, state, request, unix_sk(sk),
246 				    &p, &ad->info);
247 
248 		return aa_do_perms(profile, rules->policy, state, request, p,
249 				   ad);
250 	}
251 
252 	return aa_profile_af_sk_perm(profile, ad, request, sk);
253 }
254 
profile_bind_perm(struct aa_profile * profile,struct sock * sk,struct apparmor_audit_data * ad)255 static int profile_bind_perm(struct aa_profile *profile, struct sock *sk,
256 			     struct apparmor_audit_data *ad)
257 {
258 	struct aa_ruleset *rules = profile->label.rules[0];
259 	struct aa_perms *p = NULL;
260 	aa_state_t state;
261 
262 	AA_BUG(!profile);
263 	AA_BUG(!sk);
264 	AA_BUG(!ad);
265 	AA_BUG(profile_unconfined(profile));
266 
267 	state = RULE_MEDIATES_UNIX(rules);
268 	if (state) {
269 		if (is_unix_addr_fs(ad->net.addr, ad->net.addrlen))
270 			/* under v7-9 fs hook handles bind */
271 			return 0;
272 		/* bind for abstract socket */
273 		state = match_to_local(rules->policy, state, AA_MAY_BIND,
274 				       sk->sk_type, sk->sk_protocol,
275 				       unix_addr(ad->net.addr),
276 				       ad->net.addrlen,
277 				       &p, &ad->info);
278 
279 		return aa_do_perms(profile, rules->policy, state, AA_MAY_BIND,
280 				   p, ad);
281 	}
282 
283 	return aa_profile_af_sk_perm(profile, ad, AA_MAY_BIND, sk);
284 }
285 
profile_listen_perm(struct aa_profile * profile,struct sock * sk,int backlog,struct apparmor_audit_data * ad)286 static int profile_listen_perm(struct aa_profile *profile, struct sock *sk,
287 			       int backlog, struct apparmor_audit_data *ad)
288 {
289 	struct aa_ruleset *rules = profile->label.rules[0];
290 	struct aa_perms *p = NULL;
291 	aa_state_t state;
292 
293 	AA_BUG(!profile);
294 	AA_BUG(!sk);
295 	AA_BUG(!ad);
296 	AA_BUG(profile_unconfined(profile));
297 
298 	state = RULE_MEDIATES_UNIX(rules);
299 	if (state) {
300 		__be16 b = cpu_to_be16(backlog);
301 
302 		if (is_unix_fs(sk))
303 			return unix_fs_perm(ad->op, AA_MAY_LISTEN,
304 					    ad->subj_cred, &profile->label,
305 					    &unix_sk(sk)->path);
306 
307 		state = match_to_cmd(rules->policy, state, AA_MAY_LISTEN,
308 				     unix_sk(sk), CMD_LISTEN, &p, &ad->info);
309 		if (state && !p) {
310 			state = aa_dfa_match_len(rules->policy->dfa, state,
311 						 (char *) &b, 2);
312 			if (!state)
313 				ad->info = "failed listen backlog match";
314 		}
315 		return aa_do_perms(profile, rules->policy, state, AA_MAY_LISTEN,
316 				   p, ad);
317 	}
318 
319 	return aa_profile_af_sk_perm(profile, ad, AA_MAY_LISTEN, sk);
320 }
321 
profile_accept_perm(struct aa_profile * profile,struct sock * sk,struct apparmor_audit_data * ad)322 static int profile_accept_perm(struct aa_profile *profile,
323 			       struct sock *sk,
324 			       struct apparmor_audit_data *ad)
325 {
326 	struct aa_ruleset *rules = profile->label.rules[0];
327 	struct aa_perms *p = NULL;
328 	aa_state_t state;
329 
330 	AA_BUG(!profile);
331 	AA_BUG(!sk);
332 	AA_BUG(!ad);
333 	AA_BUG(profile_unconfined(profile));
334 
335 	state = RULE_MEDIATES_UNIX(rules);
336 	if (state) {
337 		if (is_unix_fs(sk))
338 			return unix_fs_perm(ad->op, AA_MAY_ACCEPT,
339 					    ad->subj_cred, &profile->label,
340 					    &unix_sk(sk)->path);
341 
342 		state = match_to_sk(rules->policy, state, AA_MAY_ACCEPT,
343 				    unix_sk(sk), &p, &ad->info);
344 
345 		return aa_do_perms(profile, rules->policy, state, AA_MAY_ACCEPT,
346 				   p, ad);
347 	}
348 
349 	return aa_profile_af_sk_perm(profile, ad, AA_MAY_ACCEPT, sk);
350 }
351 
profile_opt_perm(struct aa_profile * profile,u32 request,struct sock * sk,int optname,struct apparmor_audit_data * ad)352 static int profile_opt_perm(struct aa_profile *profile, u32 request,
353 			    struct sock *sk, int optname,
354 			    struct apparmor_audit_data *ad)
355 {
356 	struct aa_ruleset *rules = profile->label.rules[0];
357 	struct aa_perms *p = NULL;
358 	aa_state_t state;
359 
360 	AA_BUG(!profile);
361 	AA_BUG(!sk);
362 	AA_BUG(!ad);
363 	AA_BUG(profile_unconfined(profile));
364 
365 	state = RULE_MEDIATES_UNIX(rules);
366 	if (state) {
367 		__be16 b = cpu_to_be16(optname);
368 		if (is_unix_fs(sk))
369 			return unix_fs_perm(ad->op, request,
370 					    ad->subj_cred, &profile->label,
371 					    &unix_sk(sk)->path);
372 
373 		state = match_to_cmd(rules->policy, state, request, unix_sk(sk),
374 				     CMD_OPT, &p, &ad->info);
375 		if (state && !p) {
376 			state = aa_dfa_match_len(rules->policy->dfa, state,
377 						 (char *) &b, 2);
378 			if (!state)
379 				ad->info = "failed sockopt match";
380 		}
381 		return aa_do_perms(profile, rules->policy, state, request, p,
382 				   ad);
383 	}
384 
385 	return aa_profile_af_sk_perm(profile, ad, request, sk);
386 }
387 
388 /* null peer_label is allowed, in which case the peer_sk label is used */
profile_peer_perm(struct aa_profile * profile,u32 request,struct sock * sk,const struct path * path,struct sockaddr_un * peer_addr,int peer_addrlen,const struct path * peer_path,struct aa_label * peer_label,struct apparmor_audit_data * ad)389 static int profile_peer_perm(struct aa_profile *profile, u32 request,
390 			     struct sock *sk, const struct path *path,
391 			     struct sockaddr_un *peer_addr,
392 			     int peer_addrlen, const struct path *peer_path,
393 			     struct aa_label *peer_label,
394 			     struct apparmor_audit_data *ad)
395 {
396 	struct aa_ruleset *rules = profile->label.rules[0];
397 	struct aa_perms *p = NULL;
398 	aa_state_t state;
399 
400 	AA_BUG(!profile);
401 	AA_BUG(profile_unconfined(profile));
402 	AA_BUG(!sk);
403 	AA_BUG(!peer_label);
404 	AA_BUG(!ad);
405 
406 	state = RULE_MEDIATES_UNIX(rules);
407 	if (state) {
408 		struct aa_profile *peerp;
409 
410 		if (peer_path)
411 			return unix_fs_perm(ad->op, request, ad->subj_cred,
412 					    &profile->label, peer_path);
413 		else if (path)
414 			return unix_fs_perm(ad->op, request, ad->subj_cred,
415 					    &profile->label, path);
416 		state = match_to_peer(rules->policy, state, request,
417 				      unix_sk(sk),
418 				      peer_addr, peer_addrlen, &p, &ad->info);
419 
420 		return fn_for_each_in_scope(peer_label, peerp,
421 				match_label(profile, rules, state, request,
422 					    peerp, p, ad));
423 	}
424 
425 	return aa_profile_af_sk_perm(profile, ad, request, sk);
426 }
427 
428 /* -------------------------------- */
429 
aa_unix_create_perm(struct aa_label * label,int family,int type,int protocol)430 int aa_unix_create_perm(struct aa_label *label, int family, int type,
431 			int protocol)
432 {
433 	if (!unconfined(label)) {
434 		struct aa_profile *profile;
435 		DEFINE_AUDIT_NET(ad, OP_CREATE, current_cred(), NULL, family,
436 				 type, protocol);
437 
438 		return fn_for_each_confined(label, profile,
439 				profile_create_perm(profile, family, type,
440 						    protocol, &ad));
441 	}
442 
443 	return 0;
444 }
445 
aa_unix_label_sk_perm(const struct cred * subj_cred,struct aa_label * label,const char * op,u32 request,struct sock * sk,const struct path * path)446 static int aa_unix_label_sk_perm(const struct cred *subj_cred,
447 				 struct aa_label *label,
448 				 const char *op, u32 request, struct sock *sk,
449 				 const struct path *path)
450 {
451 	if (!unconfined(label)) {
452 		struct aa_profile *profile;
453 		DEFINE_AUDIT_SK(ad, op, subj_cred, sk);
454 
455 		return fn_for_each_confined(label, profile,
456 				profile_sk_perm(profile, &ad, request, sk,
457 						path));
458 	}
459 	return 0;
460 }
461 
462 /* revalidation, get/set attr, shutdown */
aa_unix_sock_perm(const char * op,u32 request,struct socket * sock)463 int aa_unix_sock_perm(const char *op, u32 request, struct socket *sock)
464 {
465 	struct aa_label *label;
466 	bool needput;
467 	int error;
468 
469 	label = begin_current_label_crit_section(&needput);
470 	error = aa_unix_label_sk_perm(current_cred(), label, op,
471 				      request, sock->sk,
472 				      is_unix_fs(sock->sk) ? &unix_sk(sock->sk)->path : NULL);
473 	end_current_label_crit_section(label, needput);
474 
475 	return error;
476 }
477 
valid_addr(struct sockaddr * addr,int addr_len)478 static int valid_addr(struct sockaddr *addr, int addr_len)
479 {
480 	struct sockaddr_un *sunaddr = unix_addr(addr);
481 
482 	/* addr_len == offsetof(struct sockaddr_un, sun_path) is autobind */
483 	if (addr_len < offsetof(struct sockaddr_un, sun_path) ||
484 	    addr_len > sizeof(*sunaddr))
485 		return -EINVAL;
486 	return 0;
487 }
488 
aa_unix_bind_perm(struct socket * sock,struct sockaddr * addr,int addrlen)489 int aa_unix_bind_perm(struct socket *sock, struct sockaddr *addr,
490 		      int addrlen)
491 {
492 	struct aa_profile *profile;
493 	struct aa_label *label;
494 	bool needput;
495 	int error = 0;
496 
497 	error = valid_addr(addr, addrlen);
498 	if (error)
499 		return error;
500 
501 	label = begin_current_label_crit_section(&needput);
502 	/* fs bind is handled by mknod */
503 	if (!unconfined(label)) {
504 		DEFINE_AUDIT_SK(ad, OP_BIND, current_cred(), sock->sk);
505 
506 		ad.net.addr = unix_addr(addr);
507 		ad.net.addrlen = addrlen;
508 
509 		error = fn_for_each_confined(label, profile,
510 				profile_bind_perm(profile, sock->sk, &ad));
511 	}
512 	end_current_label_crit_section(label, needput);
513 
514 	return error;
515 }
516 
517 /*
518  * unix connections are covered by the
519  * - unix_stream_connect (stream) and unix_may_send hooks (dgram)
520  * - fs connect is handled by open
521  * This is just here to document this is not needed for af_unix
522  *
523 int aa_unix_connect_perm(struct socket *sock, struct sockaddr *address,
524 			 int addrlen)
525 {
526 	return 0;
527 }
528 */
529 
aa_unix_listen_perm(struct socket * sock,int backlog)530 int aa_unix_listen_perm(struct socket *sock, int backlog)
531 {
532 	struct aa_profile *profile;
533 	struct aa_label *label;
534 	bool needput;
535 	int error = 0;
536 
537 	label = begin_current_label_crit_section(&needput);
538 	if (!unconfined(label)) {
539 		DEFINE_AUDIT_SK(ad, OP_LISTEN, current_cred(), sock->sk);
540 
541 		error = fn_for_each_confined(label, profile,
542 				profile_listen_perm(profile, sock->sk,
543 						    backlog, &ad));
544 	}
545 	end_current_label_crit_section(label, needput);
546 
547 	return error;
548 }
549 
550 
551 /* ability of sock to connect, not peer address binding */
aa_unix_accept_perm(struct socket * sock,struct socket * newsock)552 int aa_unix_accept_perm(struct socket *sock, struct socket *newsock)
553 {
554 	struct aa_profile *profile;
555 	struct aa_label *label;
556 	bool needput;
557 	int error = 0;
558 
559 	label = begin_current_label_crit_section(&needput);
560 	if (!unconfined(label)) {
561 		DEFINE_AUDIT_SK(ad, OP_ACCEPT, current_cred(), sock->sk);
562 
563 		error = fn_for_each_confined(label, profile,
564 				profile_accept_perm(profile, sock->sk, &ad));
565 	}
566 	end_current_label_crit_section(label, needput);
567 
568 	return error;
569 }
570 
571 
572 /*
573  * dgram handled by unix_may_sendmsg, right to send on stream done at connect
574  * could do per msg unix_stream here, but connect + socket transfer is
575  * sufficient. This is just here to document this is not needed for af_unix
576  *
577  * sendmsg, recvmsg
578 int aa_unix_msg_perm(const char *op, u32 request, struct socket *sock,
579 		     struct msghdr *msg, int size)
580 {
581 	return 0;
582 }
583 */
584 
aa_unix_opt_perm(const char * op,u32 request,struct socket * sock,int level,int optname)585 int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock,
586 		     int level, int optname)
587 {
588 	struct aa_profile *profile;
589 	struct aa_label *label;
590 	bool needput;
591 	int error = 0;
592 
593 	label = begin_current_label_crit_section(&needput);
594 	if (!unconfined(label)) {
595 		DEFINE_AUDIT_SK(ad, op, current_cred(), sock->sk);
596 
597 		error = fn_for_each_confined(label, profile,
598 				profile_opt_perm(profile, request, sock->sk,
599 						 optname, &ad));
600 	}
601 	end_current_label_crit_section(label, needput);
602 
603 	return error;
604 }
605 
unix_peer_perm(const struct cred * subj_cred,struct aa_label * label,const char * op,u32 request,struct sock * sk,const struct path * path,struct sockaddr_un * peer_addr,int peer_addrlen,const struct path * peer_path,struct aa_label * peer_label)606 static int unix_peer_perm(const struct cred *subj_cred,
607 			  struct aa_label *label, const char *op, u32 request,
608 			  struct sock *sk, const struct path *path,
609 			  struct sockaddr_un *peer_addr, int peer_addrlen,
610 			  const struct path *peer_path, struct aa_label *peer_label)
611 {
612 	struct aa_profile *profile;
613 	DEFINE_AUDIT_SK(ad, op, subj_cred, sk);
614 
615 	ad.net.peer.addr = peer_addr;
616 	ad.net.peer.addrlen = peer_addrlen;
617 
618 	return fn_for_each_confined(label, profile,
619 			profile_peer_perm(profile, request, sk, path,
620 					  peer_addr, peer_addrlen, peer_path,
621 					  peer_label, &ad));
622 }
623 
624 /*
625  *
626  * Requires: lock held on both @sk and @peer_sk
627  *           called by unix_stream_connect, unix_may_send
628  */
aa_unix_peer_perm(const struct cred * subj_cred,struct aa_label * label,const char * op,u32 request,struct sock * sk,struct sock * peer_sk,struct aa_label * peer_label)629 int aa_unix_peer_perm(const struct cred *subj_cred,
630 		      struct aa_label *label, const char *op, u32 request,
631 		      struct sock *sk, struct sock *peer_sk,
632 		      struct aa_label *peer_label)
633 {
634 	struct unix_sock *peeru = unix_sk(peer_sk);
635 	struct unix_sock *u = unix_sk(sk);
636 	int plen;
637 	struct sockaddr_un *paddr = aa_sunaddr(unix_sk(peer_sk), &plen);
638 
639 	AA_BUG(!label);
640 	AA_BUG(!sk);
641 	AA_BUG(!peer_sk);
642 	AA_BUG(!peer_label);
643 
644 	return unix_peer_perm(subj_cred, label, op, request, sk,
645 			      is_unix_fs(sk) ? &u->path : NULL,
646 			      paddr, plen,
647 			      is_unix_fs(peer_sk) ? &peeru->path : NULL,
648 			      peer_label);
649 }
650 
651 /* sk_plabel for comparison only */
update_sk_ctx(struct sock * sk,struct aa_label * label,struct aa_label * plabel)652 static void update_sk_ctx(struct sock *sk, struct aa_label *label,
653 			  struct aa_label *plabel)
654 {
655 	struct aa_label *l, *old;
656 	struct aa_sk_ctx *ctx = aa_sock(sk);
657 	bool update_sk;
658 
659 	rcu_read_lock();
660 	update_sk = (plabel &&
661 		     (plabel != rcu_access_pointer(ctx->peer_lastupdate) ||
662 		      !aa_label_is_subset(plabel, rcu_dereference(ctx->peer)))) ||
663 	  !__aa_subj_label_is_cached(label, rcu_dereference(ctx->label));
664 	rcu_read_unlock();
665 	if (!update_sk)
666 		return;
667 
668 	spin_lock(&unix_sk(sk)->lock);
669 	old = rcu_dereference_protected(ctx->label,
670 					lockdep_is_held(&unix_sk(sk)->lock));
671 	l = aa_label_merge(old, label, GFP_ATOMIC);
672 	if (l) {
673 		if (l != old) {
674 			rcu_assign_pointer(ctx->label, l);
675 			aa_put_label(old);
676 		} else
677 			aa_put_label(l);
678 	}
679 	if (plabel && rcu_access_pointer(ctx->peer_lastupdate) != plabel) {
680 		old = rcu_dereference_protected(ctx->peer, lockdep_is_held(&unix_sk(sk)->lock));
681 
682 		if (old == plabel) {
683 			rcu_assign_pointer(ctx->peer_lastupdate,
684 					   aa_get_label(plabel));
685 		} else if (aa_label_is_subset(plabel, old)) {
686 			rcu_assign_pointer(ctx->peer_lastupdate,
687 					   aa_get_label(plabel));
688 			rcu_assign_pointer(ctx->peer, aa_get_label(plabel));
689 			aa_put_label(old);
690 		} /* else race or a subset - don't update */
691 	}
692 	spin_unlock(&unix_sk(sk)->lock);
693 }
694 
update_peer_ctx(struct sock * sk,struct aa_sk_ctx * ctx,struct aa_label * label)695 static void update_peer_ctx(struct sock *sk, struct aa_sk_ctx *ctx,
696 			    struct aa_label *label)
697 {
698 	struct aa_label *l, *old;
699 
700 	spin_lock(&unix_sk(sk)->lock);
701 	old = rcu_dereference_protected(ctx->peer,
702 					lockdep_is_held(&unix_sk(sk)->lock));
703 	l = aa_label_merge(old, label, GFP_ATOMIC);
704 	if (l) {
705 		if (l != old) {
706 			rcu_assign_pointer(ctx->peer, l);
707 			aa_put_label(old);
708 		} else
709 			aa_put_label(l);
710 	}
711 	spin_unlock(&unix_sk(sk)->lock);
712 }
713 
714 /* This fn is only checked if something has changed in the security
715  * boundaries. Otherwise cached info off file is sufficient
716  */
aa_unix_file_perm(const struct cred * subj_cred,struct aa_label * label,const char * op,u32 request,struct file * file)717 int aa_unix_file_perm(const struct cred *subj_cred, struct aa_label *label,
718 		      const char *op, u32 request, struct file *file)
719 {
720 	struct socket *sock = (struct socket *) file->private_data;
721 	struct sockaddr_un *addr, *peer_addr;
722 	int addrlen, peer_addrlen;
723 	struct aa_label *plabel = NULL;
724 	struct sock *peer_sk = NULL;
725 	u32 sk_req = request & ~NET_PEER_MASK;
726 	struct path path;
727 	bool is_sk_fs;
728 	int error = 0;
729 
730 	AA_BUG(!label);
731 	AA_BUG(!sock);
732 	AA_BUG(!sock->sk);
733 	AA_BUG(sock->sk->sk_family != PF_UNIX);
734 
735 	/* investigate only using lock via unix_peer_get()
736 	 * addr only needs the memory barrier, but need to investigate
737 	 * path
738 	 */
739 	unix_state_lock(sock->sk);
740 	peer_sk = unix_peer(sock->sk);
741 	if (peer_sk)
742 		sock_hold(peer_sk);
743 
744 	is_sk_fs = is_unix_fs(sock->sk);
745 	addr = aa_sunaddr(unix_sk(sock->sk), &addrlen);
746 	path = unix_sk(sock->sk)->path;
747 	unix_state_unlock(sock->sk);
748 
749 	if (is_sk_fs && peer_sk)
750 		sk_req = request;
751 	if (sk_req) {
752 			error = aa_unix_label_sk_perm(subj_cred, label, op,
753 						      sk_req, sock->sk,
754 						      is_sk_fs ? &path : NULL);
755 	}
756 	if (!peer_sk)
757 		goto out;
758 
759 	if (!is_sk_fs) {
760 		bool is_peer_fs = is_unix_fs(peer_sk);
761 
762 		peer_addr = aa_sunaddr(unix_sk(peer_sk), &peer_addrlen);
763 		if (is_peer_fs) {
764 			struct path peer_path;
765 
766 			unix_state_lock(peer_sk);
767 			peer_path = unix_sk(peer_sk)->path;
768 			if (peer_path.dentry)
769 				path_get(&peer_path);
770 			unix_state_unlock(peer_sk);
771 
772 			last_error(error,
773 				   unix_fs_perm(op, request, subj_cred, label,
774 						&peer_path));
775 			if (peer_path.dentry)
776 				path_put(&peer_path);
777 		} else {
778 			struct aa_sk_ctx *pctx = aa_sock(peer_sk);
779 
780 			rcu_read_lock();
781 			plabel = aa_get_newest_label(pctx->label);
782 			rcu_read_unlock();
783 			/* no fs check of aa_unix_peer_perm because conditions
784 			 * above ensure they will never be done
785 			 */
786 			last_error(error,
787 				xcheck(unix_peer_perm(subj_cred, label, op,
788 					      MAY_READ | MAY_WRITE, sock->sk,
789 					      is_sk_fs ? &path : NULL,
790 					      peer_addr, peer_addrlen,
791 					      NULL, plabel),
792 				       unix_peer_perm(file->f_cred, plabel, op,
793 					      MAY_READ | MAY_WRITE, peer_sk,
794 					      NULL, addr, addrlen,
795 					      is_sk_fs ? &path : NULL,
796 					      label)));
797 			if (!error && !__aa_subj_label_is_cached(plabel, label))
798 				update_peer_ctx(peer_sk, pctx, label);
799 		}
800 	}
801 	sock_put(peer_sk);
802 
803 out:
804 
805 	/* update peer cache to latest successful perm check */
806 	if (error == 0)
807 		update_sk_ctx(sock->sk, label, plabel);
808 	aa_put_label(plabel);
809 
810 	return error;
811 }
812 
813