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