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