xref: /linux/security/apparmor/net.c (revision c16ce856e422e73a54c41131e0332de1afe09b8b)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * AppArmor security module
4  *
5  * This file contains AppArmor network mediation
6  *
7  * Copyright (C) 1998-2008 Novell/SUSE
8  * Copyright 2009-2017 Canonical Ltd.
9  */
10 
11 #include "include/af_unix.h"
12 #include "include/apparmor.h"
13 #include "include/audit.h"
14 #include "include/cred.h"
15 #include "include/label.h"
16 #include "include/net.h"
17 #include "include/policy.h"
18 #include "include/secid.h"
19 
20 #include "net_names.h"
21 
22 
23 struct aa_sfs_entry aa_sfs_entry_network[] = {
24 	AA_SFS_FILE_STRING("af_mask",	AA_SFS_AF_MASK),
25 	AA_SFS_FILE_BOOLEAN("tcp-fast-open",		1),
26 	{ }
27 };
28 
29 struct aa_sfs_entry aa_sfs_entry_networkv9[] = {
30 	AA_SFS_FILE_STRING("af_mask",	AA_SFS_AF_MASK),
31 	AA_SFS_FILE_BOOLEAN("af_unix",	1),
32 	AA_SFS_FILE_BOOLEAN("tcp-fast-open",		1),
33 	{ }
34 };
35 
36 static const char * const net_mask_names[] = {
37 	"unknown",
38 	"send",
39 	"receive",
40 	"unknown",
41 
42 	"create",
43 	"shutdown",
44 	"connect",
45 	"unknown",
46 
47 	"setattr",
48 	"getattr",
49 	"setcred",
50 	"getcred",
51 
52 	"chmod",
53 	"chown",
54 	"chgrp",
55 	"lock",
56 
57 	"mmap",
58 	"mprot",
59 	"unknown",
60 	"unknown",
61 
62 	"accept",
63 	"bind",
64 	"listen",
65 	"unknown",
66 
67 	"setopt",
68 	"getopt",
69 	"unknown",
70 	"unknown",
71 
72 	"unknown",
73 	"unknown",
74 	"unknown",
75 	"unknown",
76 };
77 
78 static void audit_unix_addr(struct audit_buffer *ab, const char *str,
79 			    struct sockaddr_un *addr, int addrlen)
80 {
81 	int len = unix_addr_len(addrlen);
82 
83 	if (!addr || len <= 0) {
84 		audit_log_format(ab, " %s=none", str);
85 	} else if (addr->sun_path[0]) {
86 		audit_log_format(ab, " %s=", str);
87 		audit_log_untrustedstring(ab, addr->sun_path);
88 	} else {
89 		audit_log_format(ab, " %s=\"@", str);
90 		if (audit_string_contains_control(&addr->sun_path[1], len - 1))
91 			audit_log_n_hex(ab, &addr->sun_path[1], len - 1);
92 		else
93 			audit_log_format(ab, "%.*s", len - 1,
94 					 &addr->sun_path[1]);
95 		audit_log_format(ab, "\"");
96 	}
97 }
98 
99 static void audit_unix_sk_addr(struct audit_buffer *ab, const char *str,
100 			       const struct sock *sk)
101 {
102 	const struct unix_sock *u = unix_sk(sk);
103 
104 	if (u && u->addr) {
105 		int addrlen;
106 		struct sockaddr_un *addr = aa_sunaddr(u, &addrlen);
107 
108 		audit_unix_addr(ab, str, addr, addrlen);
109 	} else {
110 		audit_unix_addr(ab, str, NULL, 0);
111 
112 	}
113 }
114 
115 /* audit callback for net specific fields */
116 void audit_net_cb(struct audit_buffer *ab, void *va)
117 {
118 	struct common_audit_data *sa = va;
119 	struct apparmor_audit_data *ad = aad(sa);
120 
121 	if (address_family_names[ad->common.u.net->family])
122 		audit_log_format(ab, " family=\"%s\"",
123 				 address_family_names[ad->common.u.net->family]);
124 	else
125 		audit_log_format(ab, " family=\"unknown(%d)\"",
126 				 ad->common.u.net->family);
127 	if (sock_type_names[ad->net.type])
128 		audit_log_format(ab, " sock_type=\"%s\"",
129 				 sock_type_names[ad->net.type]);
130 	else
131 		audit_log_format(ab, " sock_type=\"unknown(%d)\"",
132 				 ad->net.type);
133 	audit_log_format(ab, " protocol=%d", ad->net.protocol);
134 
135 	if (ad->request & NET_PERMS_MASK) {
136 		audit_log_format(ab, " requested_mask=");
137 		aa_audit_perm_mask(ab, ad->request, NULL, 0,
138 				   net_mask_names, NET_PERMS_MASK);
139 
140 		if (ad->denied & NET_PERMS_MASK) {
141 			audit_log_format(ab, " denied_mask=");
142 			aa_audit_perm_mask(ab, ad->denied, NULL, 0,
143 					   net_mask_names, NET_PERMS_MASK);
144 		}
145 	}
146 	if (ad->common.u.net->family == PF_UNIX) {
147 		if (ad->net.addr || !ad->common.u.net->sk)
148 			audit_unix_addr(ab, "addr",
149 					unix_addr(ad->net.addr),
150 					ad->net.addrlen);
151 		else
152 			audit_unix_sk_addr(ab, "addr", ad->common.u.net->sk);
153 		if (ad->request & NET_PEER_MASK) {
154 			audit_unix_addr(ab, "peer_addr",
155 					unix_addr(ad->net.peer.addr),
156 					ad->net.peer.addrlen);
157 		}
158 	}
159 	if (ad->peer) {
160 		audit_log_format(ab, " peer=");
161 		aa_label_xaudit(ab, labels_ns(ad->subj_label), ad->peer,
162 				FLAGS_NONE, GFP_ATOMIC);
163 	}
164 }
165 
166 /* standard permission lookup pattern - supports early bailout */
167 int aa_do_perms(struct aa_profile *profile, struct aa_policydb *policy,
168 		aa_state_t state, u32 request,
169 		struct aa_perms *p, struct apparmor_audit_data *ad)
170 {
171 	struct aa_perms perms;
172 
173 	AA_BUG(!profile);
174 	AA_BUG(!policy);
175 
176 
177 	if (state || !p)
178 		p = aa_lookup_perms(policy, state);
179 	perms = *p;
180 	aa_apply_modes_to_perms(profile, &perms);
181 	return aa_check_perms(profile, &perms, request, ad,
182 			      audit_net_cb);
183 }
184 
185 /* only continue match if
186  *   insufficient current perms at current state
187  *   indicates there are more perms in later state
188  * Returns: perms struct if early match
189  */
190 static struct aa_perms *early_match(struct aa_policydb *policy,
191 				    aa_state_t state, u32 request)
192 {
193 	struct aa_perms *p;
194 
195 	p = aa_lookup_perms(policy, state);
196 	if (((p->allow & request) != request) && (p->allow & AA_CONT_MATCH))
197 		return NULL;
198 	return p;
199 }
200 
201 static aa_state_t aa_dfa_match_be16(struct aa_dfa *dfa, aa_state_t state,
202 					  u16 data)
203 {
204 	__be16 buffer = cpu_to_be16(data);
205 
206 	return aa_dfa_match_len(dfa, state, (char *) &buffer, 2);
207 }
208 
209 /**
210  * aa_match_to_prot - match the af, type, protocol triplet
211  * @policy: policy being matched
212  * @state: state to start in
213  * @request: permissions being requested, ignored if @p == NULL
214  * @af: socket address family
215  * @type: socket type
216  * @protocol: socket protocol
217  * @p: output - pointer to permission associated with match
218  * @info: output - pointer to string describing failure
219  *
220  * RETURNS: state match stopped in.
221  *
222  * If @(p) is assigned a value the returned state will be the
223  * corresponding state. Will not set @p on failure or if match completes
224  * only if an early match occurs
225  */
226 aa_state_t aa_match_to_prot(struct aa_policydb *policy, aa_state_t state,
227 			    u32 request, u16 af, int type, int protocol,
228 			    struct aa_perms **p, const char **info)
229 {
230 	state = aa_dfa_match_be16(policy->dfa, state, (u16)af);
231 	if (!state) {
232 		*info = "failed af match";
233 		return state;
234 	}
235 	state = aa_dfa_match_be16(policy->dfa, state, (u16)type);
236 	if (state) {
237 		if (p)
238 			*p = early_match(policy, state, request);
239 		if (!p || !*p) {
240 			state = aa_dfa_match_be16(policy->dfa, state, (u16)protocol);
241 			if (!state)
242 				*info = "failed protocol match";
243 		}
244 	} else {
245 		*info = "failed type match";
246 	}
247 
248 	return state;
249 }
250 
251 /* Generic af perm */
252 int aa_profile_af_perm(struct aa_profile *profile,
253 		       struct apparmor_audit_data *ad, u32 request, u16 family,
254 		       int type, int protocol)
255 {
256 	struct aa_ruleset *rules = profile->label.rules[0];
257 	struct aa_perms *p = NULL;
258 	aa_state_t state;
259 
260 	AA_BUG(family >= AF_MAX);
261 	AA_BUG(type < 0 || type >= SOCK_MAX);
262 	AA_BUG(profile_unconfined(profile));
263 
264 	if (profile_unconfined(profile))
265 		return 0;
266 	state = RULE_MEDIATES_NET(rules);
267 	if (!state)
268 		return 0;
269 	state = aa_match_to_prot(rules->policy, state, request, family, type,
270 				 protocol, &p, &ad->info);
271 	return aa_do_perms(profile, rules->policy, state, request, p, ad);
272 }
273 
274 int aa_af_perm(const struct cred *subj_cred, struct aa_label *label,
275 	       const char *op, u32 request, u16 family, int type, int protocol)
276 {
277 	struct aa_profile *profile;
278 	DEFINE_AUDIT_NET(ad, op, subj_cred, NULL, family, type, protocol);
279 
280 	return fn_for_each_confined(label, profile,
281 			aa_profile_af_perm(profile, &ad, request, family,
282 					   type, protocol));
283 }
284 
285 static int aa_label_sk_perm(const struct cred *subj_cred,
286 			    struct aa_label *label,
287 			    const char *op, u32 request,
288 			    struct sock *sk)
289 {
290 	struct aa_sk_ctx *ctx = aa_sock(sk);
291 	int error = 0;
292 
293 	AA_BUG(!label);
294 	AA_BUG(!sk);
295 
296 	if (rcu_access_pointer(ctx->label) != kernel_t && !unconfined(label)) {
297 		struct aa_profile *profile;
298 		DEFINE_AUDIT_SK(ad, op, subj_cred, sk);
299 
300 		ad.subj_cred = subj_cred;
301 		error = fn_for_each_confined(label, profile,
302 			    aa_profile_af_sk_perm(profile, &ad, request, sk));
303 	}
304 
305 	return error;
306 }
307 
308 int aa_sk_perm(const char *op, u32 request, struct sock *sk)
309 {
310 	struct aa_label *label;
311 	int error;
312 
313 	AA_BUG(!sk);
314 	AA_BUG(in_interrupt());
315 
316 	/* TODO: switch to begin_current_label ???? */
317 	label = begin_current_label_crit_section();
318 	error = aa_label_sk_perm(current_cred(), label, op, request, sk);
319 	end_current_label_crit_section(label);
320 
321 	return error;
322 }
323 
324 
325 int aa_sock_file_perm(const struct cred *subj_cred, struct aa_label *label,
326 		      const char *op, u32 request, struct file *file)
327 {
328 	struct socket *sock = (struct socket *) file->private_data;
329 
330 	AA_BUG(!label);
331 
332 	/* sock && sock->sk can be NULL for sockets being set up or torn down */
333 	if (!sock || !sock->sk)
334 		return 0;
335 
336 	if (sock->sk->sk_family == PF_UNIX)
337 		return aa_unix_file_perm(subj_cred, label, op, request, file);
338 	return aa_label_sk_perm(subj_cred, label, op, request, sock->sk);
339 }
340 
341 #ifdef CONFIG_NETWORK_SECMARK
342 static int apparmor_secmark_init(struct aa_secmark *secmark)
343 {
344 	struct aa_label *label;
345 
346 	if (secmark->label[0] == '*') {
347 		secmark->secid = AA_SECID_WILDCARD;
348 		return 0;
349 	}
350 
351 	label = aa_label_strn_parse(&root_ns->unconfined->label,
352 				    secmark->label, strlen(secmark->label),
353 				    GFP_ATOMIC, false, false);
354 
355 	if (IS_ERR(label))
356 		return PTR_ERR(label);
357 
358 	secmark->secid = label->secid;
359 	aa_put_label(label);
360 
361 	return 0;
362 }
363 
364 static int aa_secmark_perm(struct aa_profile *profile, u32 request, u32 secid,
365 			   struct apparmor_audit_data *ad)
366 {
367 	int i, ret;
368 	struct aa_perms perms = { };
369 	struct aa_ruleset *rules = profile->label.rules[0];
370 
371 	if (rules->secmark_count == 0)
372 		return 0;
373 
374 	for (i = 0; i < rules->secmark_count; i++) {
375 		if (!rules->secmark[i].secid) {
376 			ret = apparmor_secmark_init(&rules->secmark[i]);
377 			if (ret)
378 				return ret;
379 		}
380 
381 		if (rules->secmark[i].secid == secid ||
382 		    rules->secmark[i].secid == AA_SECID_WILDCARD) {
383 			if (rules->secmark[i].deny)
384 				perms.deny = ALL_PERMS_MASK;
385 			else
386 				perms.allow = ALL_PERMS_MASK;
387 
388 			if (rules->secmark[i].audit)
389 				perms.audit = ALL_PERMS_MASK;
390 		}
391 	}
392 
393 	aa_apply_modes_to_perms(profile, &perms);
394 
395 	return aa_check_perms(profile, &perms, request, ad, audit_net_cb);
396 }
397 
398 int apparmor_secmark_check(struct aa_label *label, char *op, u32 request,
399 			   u32 secid, const struct sock *sk)
400 {
401 	struct aa_profile *profile;
402 	DEFINE_AUDIT_SK(ad, op, NULL, sk);
403 
404 	return fn_for_each_confined(label, profile,
405 				    aa_secmark_perm(profile, request, secid,
406 						    &ad));
407 }
408 #endif
409