]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - security/apparmor/net.c
UBUNTU: SAUCE: apparmor: fix vec_unique for vectors larger than 8
[mirror_ubuntu-zesty-kernel.git] / security / apparmor / net.c
CommitLineData
80594fc2
JJ
1/*
2 * AppArmor security module
3 *
4 * This file contains AppArmor network mediation
5 *
6 * Copyright (C) 1998-2008 Novell/SUSE
7 * Copyright 2009-2014 Canonical Ltd.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation, version 2 of the
12 * License.
13 */
14
15#include "include/af_unix.h"
16#include "include/apparmor.h"
17#include "include/audit.h"
18#include "include/context.h"
19#include "include/label.h"
20#include "include/net.h"
21#include "include/policy.h"
22
23#include "net_names.h"
24
25
26struct aa_fs_entry aa_fs_entry_network[] = {
27 AA_FS_FILE_STRING("af_mask", AA_FS_AF_MASK),
28 AA_FS_FILE_BOOLEAN("af_unix", 1),
29 { }
30};
31
32static const char *net_mask_names[] = {
33 "unknown",
34 "send",
35 "receive",
36 "unknown",
37
38 "create",
39 "shutdown",
40 "connect",
41 "unknown",
42
43 "setattr",
44 "getattr",
45 "setcred",
46 "getcred",
47
48 "chmod",
49 "chown",
50 "chgrp",
51 "lock",
52
53 "mmap",
54 "mprot",
55 "unknown",
56 "unknown",
57
58 "accept",
59 "bind",
60 "listen",
61 "unknown",
62
63 "setopt",
64 "getopt",
65 "unknown",
66 "unknown",
67
68 "unknown",
69 "unknown",
70 "unknown",
71 "unknown",
72};
73
74static void audit_unix_addr(struct audit_buffer *ab, const char *str,
75 struct sockaddr_un *addr, int addrlen)
76{
77 int len = unix_addr_len(addrlen);
78
79 if (!addr || len <= 0) {
80 audit_log_format(ab, " %s=none", str);
81 } else if (addr->sun_path[0]) {
82 audit_log_format(ab, " %s=", str);
83 audit_log_untrustedstring(ab, addr->sun_path);
84 } else {
85 audit_log_format(ab, " %s=\"@", str);
86 if (audit_string_contains_control(&addr->sun_path[1], len - 1))
87 audit_log_n_hex(ab, &addr->sun_path[1], len - 1);
88 else
89 audit_log_format(ab, "%.*s", len - 1,
90 &addr->sun_path[1]);
91 audit_log_format(ab, "\"");
92 }
93}
94
95static void audit_unix_sk_addr(struct audit_buffer *ab, const char *str,
96 struct sock *sk)
97{
98 struct unix_sock *u = unix_sk(sk);
99 if (u && u->addr)
100 audit_unix_addr(ab, str, u->addr->name, u->addr->len);
101 else
102 audit_unix_addr(ab, str, NULL, 0);
103}
104
105/* audit callback for net specific fields */
106void audit_net_cb(struct audit_buffer *ab, void *va)
107{
108 struct common_audit_data *sa = va;
109
110 audit_log_format(ab, " family=");
111 if (address_family_names[sa->u.net->family]) {
112 audit_log_string(ab, address_family_names[sa->u.net->family]);
113 } else {
114 audit_log_format(ab, "\"unknown(%d)\"", sa->u.net->family);
115 }
116 audit_log_format(ab, " sock_type=");
117 if (sock_type_names[aad(sa)->net.type]) {
118 audit_log_string(ab, sock_type_names[aad(sa)->net.type]);
119 } else {
120 audit_log_format(ab, "\"unknown(%d)\"", aad(sa)->net.type);
121 }
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
160/* Generic af perm */
161int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa,
162 u32 request, u16 family, int type)
163{
164 struct aa_perms perms = { };
165
166 AA_BUG(family >= AF_MAX);
167 AA_BUG(type < 0 && type >= SOCK_MAX);
168
169 if (profile_unconfined(profile))
170 return 0;
171
172 perms.allow = (profile->net.allow[family] & (1 << type)) ?
173 ALL_PERMS_MASK : 0;
174 perms.audit = (profile->net.audit[family] & (1 << type)) ?
175 ALL_PERMS_MASK : 0;
176 perms.quiet = (profile->net.quiet[family] & (1 << type)) ?
177 ALL_PERMS_MASK : 0;
178 aa_apply_modes_to_perms(profile, &perms);
179
180 return aa_check_perms(profile, &perms, request, sa, audit_net_cb);
181}
182
183static int aa_af_perm(struct aa_label *label, const char *op, u32 request,
184 u16 family, int type, int protocol)
185{
186 struct aa_profile *profile;
187 DEFINE_AUDIT_NET(sa, op, NULL, family, type, protocol);
188
189 return fn_for_each_confined(label, profile,
190 aa_profile_af_perm(profile, &sa, request, family, type));
191}
192
193static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request,
194 struct sock *sk)
195{
196 struct aa_profile *profile;
197 DEFINE_AUDIT_SK(sa, op, sk);
198
199 AA_BUG(!label);
200 AA_BUG(!sk);
201
202 if (unconfined(label))
203 return 0;
204
205 return fn_for_each_confined(label, profile,
206 aa_profile_af_sk_perm(profile, &sa, request, sk));
207}
208
209static int aa_sk_perm(const char *op, u32 request, struct sock *sk)
210{
211 struct aa_label *label;
212 int error;
213
214 AA_BUG(!sk);
215 AA_BUG(in_interrupt());
216
217 /* TODO: switch to begin_current_label ???? */
218 label = aa_begin_current_label(DO_UPDATE);
219 error = aa_label_sk_perm(label, op, request, sk);
220 aa_end_current_label(label);
221
222 return error;
223}
224
225#define af_select(FAMILY, FN, DEF_FN) \
226({ \
227 int __e; \
228 switch ((FAMILY)) { \
229 case AF_UNIX: \
230 __e = aa_unix_ ## FN; \
231 break; \
232 default: \
233 __e = DEF_FN; \
234 } \
235 __e; \
236})
237
238/* TODO: push into lsm.c ???? */
239
240/* revaliation, get/set attr, shutdown */
241int aa_sock_perm(const char *op, u32 request, struct socket *sock)
242{
243 AA_BUG(!sock);
244 AA_BUG(!sock->sk);
245 AA_BUG(in_interrupt());
246
247 return af_select(sock->sk->sk_family,
248 sock_perm(op, request, sock),
249 aa_sk_perm(op, request, sock->sk));
250}
251
252int aa_sock_create_perm(struct aa_label *label, int family, int type,
253 int protocol)
254{
255 AA_BUG(!label);
256 /* TODO: .... */
257 AA_BUG(in_interrupt());
258
259 return af_select(family,
260 create_perm(label, family, type, protocol),
261 aa_af_perm(label, OP_CREATE, AA_MAY_CREATE, family,
262 type, protocol));
263}
264
265int aa_sock_bind_perm(struct socket *sock, struct sockaddr *address,
266 int addrlen)
267{
268 AA_BUG(!sock);
269 AA_BUG(!sock->sk);
270 AA_BUG(!address);
271 /* TODO: .... */
272 AA_BUG(in_interrupt());
273
274 return af_select(sock->sk->sk_family,
275 bind_perm(sock, address, addrlen),
276 aa_sk_perm(OP_BIND, AA_MAY_BIND, sock->sk));
277}
278
279int aa_sock_connect_perm(struct socket *sock, struct sockaddr *address,
280 int addrlen)
281{
282 AA_BUG(!sock);
283 AA_BUG(!sock->sk);
284 AA_BUG(!address);
285 /* TODO: .... */
286 AA_BUG(in_interrupt());
287
288 return af_select(sock->sk->sk_family,
289 connect_perm(sock, address, addrlen),
290 aa_sk_perm(OP_CONNECT, AA_MAY_CONNECT, sock->sk));
291}
292
293int aa_sock_listen_perm(struct socket *sock, int backlog)
294{
295 AA_BUG(!sock);
296 AA_BUG(!sock->sk);
297 /* TODO: .... */
298 AA_BUG(in_interrupt());
299
300 return af_select(sock->sk->sk_family,
301 listen_perm(sock, backlog),
302 aa_sk_perm(OP_LISTEN, AA_MAY_LISTEN, sock->sk));
303}
304
305/* ability of sock to connect, not peer address binding */
306int aa_sock_accept_perm(struct socket *sock, struct socket *newsock)
307{
308 AA_BUG(!sock);
309 AA_BUG(!sock->sk);
310 AA_BUG(!newsock);
311 /* TODO: .... */
312 AA_BUG(in_interrupt());
313
314 return af_select(sock->sk->sk_family,
315 accept_perm(sock, newsock),
316 aa_sk_perm(OP_ACCEPT, AA_MAY_ACCEPT, sock->sk));
317}
318
319/* sendmsg, recvmsg */
320int aa_sock_msg_perm(const char *op, u32 request, struct socket *sock,
321 struct msghdr *msg, int size)
322{
323 AA_BUG(!sock);
324 AA_BUG(!sock->sk);
325 AA_BUG(!msg);
326 /* TODO: .... */
327 AA_BUG(in_interrupt());
328
329 return af_select(sock->sk->sk_family,
330 msg_perm(op, request, sock, msg, size),
331 aa_sk_perm(op, request, sock->sk));
332}
333
334/* revaliation, get/set attr, opt */
335int aa_sock_opt_perm(const char *op, u32 request, struct socket *sock, int level,
336 int optname)
337{
338 AA_BUG(!sock);
339 AA_BUG(!sock->sk);
340 AA_BUG(in_interrupt());
341
342 return af_select(sock->sk->sk_family,
343 opt_perm(op, request, sock, level, optname),
344 aa_sk_perm(op, request, sock->sk));
345}
346
347int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
348 struct socket *sock)
349{
350 AA_BUG(!label);
351 AA_BUG(!sock);
352 AA_BUG(!sock->sk);
353
354 return af_select(sock->sk->sk_family,
355 file_perm(label, op, request, sock),
356 aa_label_sk_perm(label, op, request, sock->sk));
357}