]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blob - security/apparmor/net.c
UBUNTU: SAUCE: apparmor: af_unix mediation
[mirror_ubuntu-focal-kernel.git] / security / apparmor / net.c
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_network_compat[] = {
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 struct sock *sk)
99 {
100 struct unix_sock *u = unix_sk(sk);
101 if (u && u->addr)
102 audit_unix_addr(ab, str, u->addr->name, u->addr->len);
103 else
104 audit_unix_addr(ab, str, NULL, 0);
105 }
106
107 /* audit callback for net specific fields */
108 void audit_net_cb(struct audit_buffer *ab, void *va)
109 {
110 struct common_audit_data *sa = va;
111
112 audit_log_format(ab, " family=");
113 if (address_family_names[sa->u.net->family])
114 audit_log_string(ab, address_family_names[sa->u.net->family]);
115 else
116 audit_log_format(ab, "\"unknown(%d)\"", sa->u.net->family);
117 audit_log_format(ab, " sock_type=");
118 if (sock_type_names[aad(sa)->net.type])
119 audit_log_string(ab, sock_type_names[aad(sa)->net.type]);
120 else
121 audit_log_format(ab, "\"unknown(%d)\"", aad(sa)->net.type);
122 audit_log_format(ab, " protocol=%d", aad(sa)->net.protocol);
123
124 if (aad(sa)->request & NET_PERMS_MASK) {
125 audit_log_format(ab, " requested_mask=");
126 aa_audit_perm_mask(ab, aad(sa)->request, NULL, 0,
127 net_mask_names, NET_PERMS_MASK);
128
129 if (aad(sa)->denied & NET_PERMS_MASK) {
130 audit_log_format(ab, " denied_mask=");
131 aa_audit_perm_mask(ab, aad(sa)->denied, NULL, 0,
132 net_mask_names, NET_PERMS_MASK);
133 }
134 }
135 if (sa->u.net->family == AF_UNIX) {
136 if ((aad(sa)->request & ~NET_PEER_MASK) && aad(sa)->net.addr)
137 audit_unix_addr(ab, "addr",
138 unix_addr(aad(sa)->net.addr),
139 aad(sa)->net.addrlen);
140 else
141 audit_unix_sk_addr(ab, "addr", sa->u.net->sk);
142 if (aad(sa)->request & NET_PEER_MASK) {
143 if (aad(sa)->net.addr)
144 audit_unix_addr(ab, "peer_addr",
145 unix_addr(aad(sa)->net.addr),
146 aad(sa)->net.addrlen);
147 else
148 audit_unix_sk_addr(ab, "peer_addr",
149 aad(sa)->net.peer_sk);
150 }
151 }
152 if (aad(sa)->peer) {
153 audit_log_format(ab, " peer=");
154 aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
155 FLAGS_NONE, GFP_ATOMIC);
156 }
157 }
158
159 /* Generic af perm */
160 int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa,
161 u32 request, u16 family, int type)
162 {
163 struct aa_perms perms = { };
164 unsigned int state;
165 __be16 buffer[2];
166
167 AA_BUG(family >= AF_MAX);
168 AA_BUG(type < 0 || type >= SOCK_MAX);
169
170 if (profile_unconfined(profile))
171 return 0;
172 state = PROFILE_MEDIATES(profile, AA_CLASS_NET);
173 if (state) {
174 if (!state)
175 return 0;
176 buffer[0] = cpu_to_be16(family);
177 buffer[1] = cpu_to_be16((u16) type);
178 state = aa_dfa_match_len(profile->policy.dfa, state,
179 (char *) &buffer, 4);
180 aa_compute_perms(profile->policy.dfa, state, &perms);
181 } else if (profile->net_compat) {
182 /* 2.x socket mediation compat */
183 perms.allow = (profile->net_compat->allow[family] & (1 << type)) ?
184 ALL_PERMS_MASK : 0;
185 perms.audit = (profile->net_compat->audit[family] & (1 << type)) ?
186 ALL_PERMS_MASK : 0;
187 perms.quiet = (profile->net_compat->quiet[family] & (1 << type)) ?
188 ALL_PERMS_MASK : 0;
189
190 } else {
191 return 0;
192 }
193 aa_apply_modes_to_perms(profile, &perms);
194
195 return aa_check_perms(profile, &perms, request, sa, audit_net_cb);
196 }
197
198 int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family,
199 int type, int protocol)
200 {
201 struct aa_profile *profile;
202 DEFINE_AUDIT_NET(sa, op, NULL, family, type, protocol);
203
204 return fn_for_each_confined(label, profile,
205 aa_profile_af_perm(profile, &sa, request, family,
206 type));
207 }
208
209 static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request,
210 struct sock *sk)
211 {
212 int error = 0;
213
214 AA_BUG(!label);
215 AA_BUG(!sk);
216
217 if (!unconfined(label)) {
218 struct aa_profile *profile;
219 DEFINE_AUDIT_SK(sa, op, sk);
220
221 error = fn_for_each_confined(label, profile,
222 aa_profile_af_sk_perm(profile, &sa, request, sk));
223 }
224
225 return error;
226 }
227
228 int aa_sk_perm(const char *op, u32 request, struct sock *sk)
229 {
230 struct aa_label *label;
231 int error;
232
233 AA_BUG(!sk);
234 AA_BUG(in_interrupt());
235
236 /* TODO: switch to begin_current_label ???? */
237 label = begin_current_label_crit_section();
238 error = aa_label_sk_perm(label, op, request, sk);
239 end_current_label_crit_section(label);
240
241 return error;
242 }
243
244
245 int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
246 struct socket *sock)
247 {
248 AA_BUG(!label);
249 AA_BUG(!sock);
250 AA_BUG(!sock->sk);
251
252 return af_select(sock->sk->sk_family,
253 file_perm(label, op, request, sock),
254 aa_label_sk_perm(label, op, request, sock->sk));
255 }
256
257 #ifdef CONFIG_NETWORK_SECMARK
258 static int apparmor_secmark_init(struct aa_secmark *secmark)
259 {
260 struct aa_label *label;
261
262 if (secmark->label[0] == '*') {
263 secmark->secid = AA_SECID_WILDCARD;
264 return 0;
265 }
266
267 label = aa_label_strn_parse(&root_ns->unconfined->label,
268 secmark->label, strlen(secmark->label),
269 GFP_ATOMIC, false, false);
270
271 if (IS_ERR(label))
272 return PTR_ERR(label);
273
274 secmark->secid = label->secid;
275
276 return 0;
277 }
278
279 static int aa_secmark_perm(struct aa_profile *profile, u32 request, u32 secid,
280 struct common_audit_data *sa, struct sock *sk)
281 {
282 int i, ret;
283 struct aa_perms perms = { };
284
285 if (profile->secmark_count == 0)
286 return 0;
287
288 for (i = 0; i < profile->secmark_count; i++) {
289 if (!profile->secmark[i].secid) {
290 ret = apparmor_secmark_init(&profile->secmark[i]);
291 if (ret)
292 return ret;
293 }
294
295 if (profile->secmark[i].secid == secid ||
296 profile->secmark[i].secid == AA_SECID_WILDCARD) {
297 if (profile->secmark[i].deny)
298 perms.deny = ALL_PERMS_MASK;
299 else
300 perms.allow = ALL_PERMS_MASK;
301
302 if (profile->secmark[i].audit)
303 perms.audit = ALL_PERMS_MASK;
304 }
305 }
306
307 aa_apply_modes_to_perms(profile, &perms);
308
309 return aa_check_perms(profile, &perms, request, sa, audit_net_cb);
310 }
311
312 int apparmor_secmark_check(struct aa_label *label, char *op, u32 request,
313 u32 secid, struct sock *sk)
314 {
315 struct aa_profile *profile;
316 DEFINE_AUDIT_SK(sa, op, sk);
317
318 return fn_for_each_confined(label, profile,
319 aa_secmark_perm(profile, request, secid,
320 &sa, sk));
321 }
322 #endif