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