diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-10-09 03:02:35 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-10-09 03:02:35 -0400 |
commit | 1236d6bb6e19fc72ffc6bbcdeb1bfefe450e54ee (patch) | |
tree | 47da3feee8e263e8c9352c85cf518e624be3c211 /security/apparmor/net.c | |
parent | 750b1a6894ecc9b178c6e3d0a1170122971b2036 (diff) | |
parent | 8a5776a5f49812d29fe4b2d0a2d71675c3facf3f (diff) |
Merge 4.14-rc4 into staging-next
We want the staging/iio fixes in here as well to handle merge issues.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'security/apparmor/net.c')
-rw-r--r-- | security/apparmor/net.c | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/security/apparmor/net.c b/security/apparmor/net.c new file mode 100644 index 000000000000..33d54435f8d6 --- /dev/null +++ b/security/apparmor/net.c | |||
@@ -0,0 +1,184 @@ | |||
1 | /* | ||
2 | * AppArmor security module | ||
3 | * | ||
4 | * This file contains AppArmor network mediation | ||
5 | * | ||
6 | * Copyright (C) 1998-2008 Novell/SUSE | ||
7 | * Copyright 2009-2017 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/apparmor.h" | ||
16 | #include "include/audit.h" | ||
17 | #include "include/context.h" | ||
18 | #include "include/label.h" | ||
19 | #include "include/net.h" | ||
20 | #include "include/policy.h" | ||
21 | |||
22 | #include "net_names.h" | ||
23 | |||
24 | |||
25 | struct aa_sfs_entry aa_sfs_entry_network[] = { | ||
26 | AA_SFS_FILE_STRING("af_mask", AA_SFS_AF_MASK), | ||
27 | { } | ||
28 | }; | ||
29 | |||
30 | static const char * const net_mask_names[] = { | ||
31 | "unknown", | ||
32 | "send", | ||
33 | "receive", | ||
34 | "unknown", | ||
35 | |||
36 | "create", | ||
37 | "shutdown", | ||
38 | "connect", | ||
39 | "unknown", | ||
40 | |||
41 | "setattr", | ||
42 | "getattr", | ||
43 | "setcred", | ||
44 | "getcred", | ||
45 | |||
46 | "chmod", | ||
47 | "chown", | ||
48 | "chgrp", | ||
49 | "lock", | ||
50 | |||
51 | "mmap", | ||
52 | "mprot", | ||
53 | "unknown", | ||
54 | "unknown", | ||
55 | |||
56 | "accept", | ||
57 | "bind", | ||
58 | "listen", | ||
59 | "unknown", | ||
60 | |||
61 | "setopt", | ||
62 | "getopt", | ||
63 | "unknown", | ||
64 | "unknown", | ||
65 | |||
66 | "unknown", | ||
67 | "unknown", | ||
68 | "unknown", | ||
69 | "unknown", | ||
70 | }; | ||
71 | |||
72 | |||
73 | /* audit callback for net specific fields */ | ||
74 | void audit_net_cb(struct audit_buffer *ab, void *va) | ||
75 | { | ||
76 | struct common_audit_data *sa = va; | ||
77 | |||
78 | audit_log_format(ab, " family="); | ||
79 | if (address_family_names[sa->u.net->family]) | ||
80 | audit_log_string(ab, address_family_names[sa->u.net->family]); | ||
81 | else | ||
82 | audit_log_format(ab, "\"unknown(%d)\"", sa->u.net->family); | ||
83 | audit_log_format(ab, " sock_type="); | ||
84 | if (sock_type_names[aad(sa)->net.type]) | ||
85 | audit_log_string(ab, sock_type_names[aad(sa)->net.type]); | ||
86 | else | ||
87 | audit_log_format(ab, "\"unknown(%d)\"", aad(sa)->net.type); | ||
88 | audit_log_format(ab, " protocol=%d", aad(sa)->net.protocol); | ||
89 | |||
90 | if (aad(sa)->request & NET_PERMS_MASK) { | ||
91 | audit_log_format(ab, " requested_mask="); | ||
92 | aa_audit_perm_mask(ab, aad(sa)->request, NULL, 0, | ||
93 | net_mask_names, NET_PERMS_MASK); | ||
94 | |||
95 | if (aad(sa)->denied & NET_PERMS_MASK) { | ||
96 | audit_log_format(ab, " denied_mask="); | ||
97 | aa_audit_perm_mask(ab, aad(sa)->denied, NULL, 0, | ||
98 | net_mask_names, NET_PERMS_MASK); | ||
99 | } | ||
100 | } | ||
101 | if (aad(sa)->peer) { | ||
102 | audit_log_format(ab, " peer="); | ||
103 | aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer, | ||
104 | FLAGS_NONE, GFP_ATOMIC); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | |||
109 | /* Generic af perm */ | ||
110 | int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa, | ||
111 | u32 request, u16 family, int type) | ||
112 | { | ||
113 | struct aa_perms perms = { }; | ||
114 | |||
115 | AA_BUG(family >= AF_MAX); | ||
116 | AA_BUG(type < 0 || type >= SOCK_MAX); | ||
117 | |||
118 | if (profile_unconfined(profile)) | ||
119 | return 0; | ||
120 | |||
121 | perms.allow = (profile->net.allow[family] & (1 << type)) ? | ||
122 | ALL_PERMS_MASK : 0; | ||
123 | perms.audit = (profile->net.audit[family] & (1 << type)) ? | ||
124 | ALL_PERMS_MASK : 0; | ||
125 | perms.quiet = (profile->net.quiet[family] & (1 << type)) ? | ||
126 | ALL_PERMS_MASK : 0; | ||
127 | aa_apply_modes_to_perms(profile, &perms); | ||
128 | |||
129 | return aa_check_perms(profile, &perms, request, sa, audit_net_cb); | ||
130 | } | ||
131 | |||
132 | int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family, | ||
133 | int type, int protocol) | ||
134 | { | ||
135 | struct aa_profile *profile; | ||
136 | DEFINE_AUDIT_NET(sa, op, NULL, family, type, protocol); | ||
137 | |||
138 | return fn_for_each_confined(label, profile, | ||
139 | aa_profile_af_perm(profile, &sa, request, family, | ||
140 | type)); | ||
141 | } | ||
142 | |||
143 | static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request, | ||
144 | struct sock *sk) | ||
145 | { | ||
146 | struct aa_profile *profile; | ||
147 | DEFINE_AUDIT_SK(sa, op, sk); | ||
148 | |||
149 | AA_BUG(!label); | ||
150 | AA_BUG(!sk); | ||
151 | |||
152 | if (unconfined(label)) | ||
153 | return 0; | ||
154 | |||
155 | return fn_for_each_confined(label, profile, | ||
156 | aa_profile_af_sk_perm(profile, &sa, request, sk)); | ||
157 | } | ||
158 | |||
159 | int aa_sk_perm(const char *op, u32 request, struct sock *sk) | ||
160 | { | ||
161 | struct aa_label *label; | ||
162 | int error; | ||
163 | |||
164 | AA_BUG(!sk); | ||
165 | AA_BUG(in_interrupt()); | ||
166 | |||
167 | /* TODO: switch to begin_current_label ???? */ | ||
168 | label = begin_current_label_crit_section(); | ||
169 | error = aa_label_sk_perm(label, op, request, sk); | ||
170 | end_current_label_crit_section(label); | ||
171 | |||
172 | return error; | ||
173 | } | ||
174 | |||
175 | |||
176 | int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, | ||
177 | struct socket *sock) | ||
178 | { | ||
179 | AA_BUG(!label); | ||
180 | AA_BUG(!sock); | ||
181 | AA_BUG(!sock->sk); | ||
182 | |||
183 | return aa_label_sk_perm(label, op, request, sock->sk); | ||
184 | } | ||