xref: /openbmc/linux/security/apparmor/net.c (revision 9fb29c73)
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/cred.h"
18 #include "include/label.h"
19 #include "include/net.h"
20 #include "include/policy.h"
21 #include "include/secid.h"
22 
23 #include "net_names.h"
24 
25 
26 struct aa_sfs_entry aa_sfs_entry_network[] = {
27 	AA_SFS_FILE_STRING("af_mask",	AA_SFS_AF_MASK),
28 	{ }
29 };
30 
31 static const char * const net_mask_names[] = {
32 	"unknown",
33 	"send",
34 	"receive",
35 	"unknown",
36 
37 	"create",
38 	"shutdown",
39 	"connect",
40 	"unknown",
41 
42 	"setattr",
43 	"getattr",
44 	"setcred",
45 	"getcred",
46 
47 	"chmod",
48 	"chown",
49 	"chgrp",
50 	"lock",
51 
52 	"mmap",
53 	"mprot",
54 	"unknown",
55 	"unknown",
56 
57 	"accept",
58 	"bind",
59 	"listen",
60 	"unknown",
61 
62 	"setopt",
63 	"getopt",
64 	"unknown",
65 	"unknown",
66 
67 	"unknown",
68 	"unknown",
69 	"unknown",
70 	"unknown",
71 };
72 
73 
74 /* audit callback for net specific fields */
75 void audit_net_cb(struct audit_buffer *ab, void *va)
76 {
77 	struct common_audit_data *sa = va;
78 
79 	audit_log_format(ab, " family=");
80 	if (address_family_names[sa->u.net->family])
81 		audit_log_string(ab, address_family_names[sa->u.net->family]);
82 	else
83 		audit_log_format(ab, "\"unknown(%d)\"", sa->u.net->family);
84 	audit_log_format(ab, " sock_type=");
85 	if (sock_type_names[aad(sa)->net.type])
86 		audit_log_string(ab, sock_type_names[aad(sa)->net.type]);
87 	else
88 		audit_log_format(ab, "\"unknown(%d)\"", aad(sa)->net.type);
89 	audit_log_format(ab, " protocol=%d", aad(sa)->net.protocol);
90 
91 	if (aad(sa)->request & NET_PERMS_MASK) {
92 		audit_log_format(ab, " requested_mask=");
93 		aa_audit_perm_mask(ab, aad(sa)->request, NULL, 0,
94 				   net_mask_names, NET_PERMS_MASK);
95 
96 		if (aad(sa)->denied & NET_PERMS_MASK) {
97 			audit_log_format(ab, " denied_mask=");
98 			aa_audit_perm_mask(ab, aad(sa)->denied, NULL, 0,
99 					   net_mask_names, NET_PERMS_MASK);
100 		}
101 	}
102 	if (aad(sa)->peer) {
103 		audit_log_format(ab, " peer=");
104 		aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
105 				FLAGS_NONE, GFP_ATOMIC);
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 	unsigned int state;
115 	__be16 buffer[2];
116 
117 	AA_BUG(family >= AF_MAX);
118 	AA_BUG(type < 0 || type >= SOCK_MAX);
119 
120 	if (profile_unconfined(profile))
121 		return 0;
122 	state = PROFILE_MEDIATES(profile, AA_CLASS_NET);
123 	if (!state)
124 		return 0;
125 
126 	buffer[0] = cpu_to_be16(family);
127 	buffer[1] = cpu_to_be16((u16) type);
128 	state = aa_dfa_match_len(profile->policy.dfa, state, (char *) &buffer,
129 				 4);
130 	aa_compute_perms(profile->policy.dfa, state, &perms);
131 	aa_apply_modes_to_perms(profile, &perms);
132 
133 	return aa_check_perms(profile, &perms, request, sa, audit_net_cb);
134 }
135 
136 int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family,
137 	       int type, int protocol)
138 {
139 	struct aa_profile *profile;
140 	DEFINE_AUDIT_NET(sa, op, NULL, family, type, protocol);
141 
142 	return fn_for_each_confined(label, profile,
143 			aa_profile_af_perm(profile, &sa, request, family,
144 					   type));
145 }
146 
147 static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request,
148 			    struct sock *sk)
149 {
150 	int error = 0;
151 
152 	AA_BUG(!label);
153 	AA_BUG(!sk);
154 
155 	if (!unconfined(label)) {
156 		struct aa_profile *profile;
157 		DEFINE_AUDIT_SK(sa, op, sk);
158 
159 		error = fn_for_each_confined(label, profile,
160 			    aa_profile_af_sk_perm(profile, &sa, request, sk));
161 	}
162 
163 	return error;
164 }
165 
166 int aa_sk_perm(const char *op, u32 request, struct sock *sk)
167 {
168 	struct aa_label *label;
169 	int error;
170 
171 	AA_BUG(!sk);
172 	AA_BUG(in_interrupt());
173 
174 	/* TODO: switch to begin_current_label ???? */
175 	label = begin_current_label_crit_section();
176 	error = aa_label_sk_perm(label, op, request, sk);
177 	end_current_label_crit_section(label);
178 
179 	return error;
180 }
181 
182 
183 int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
184 		      struct socket *sock)
185 {
186 	AA_BUG(!label);
187 	AA_BUG(!sock);
188 	AA_BUG(!sock->sk);
189 
190 	return aa_label_sk_perm(label, op, request, sock->sk);
191 }
192 
193 #ifdef CONFIG_NETWORK_SECMARK
194 static int apparmor_secmark_init(struct aa_secmark *secmark)
195 {
196 	struct aa_label *label;
197 
198 	if (secmark->label[0] == '*') {
199 		secmark->secid = AA_SECID_WILDCARD;
200 		return 0;
201 	}
202 
203 	label = aa_label_strn_parse(&root_ns->unconfined->label,
204 				    secmark->label, strlen(secmark->label),
205 				    GFP_ATOMIC, false, false);
206 
207 	if (IS_ERR(label))
208 		return PTR_ERR(label);
209 
210 	secmark->secid = label->secid;
211 
212 	return 0;
213 }
214 
215 static int aa_secmark_perm(struct aa_profile *profile, u32 request, u32 secid,
216 			   struct common_audit_data *sa, struct sock *sk)
217 {
218 	int i, ret;
219 	struct aa_perms perms = { };
220 
221 	if (profile->secmark_count == 0)
222 		return 0;
223 
224 	for (i = 0; i < profile->secmark_count; i++) {
225 		if (!profile->secmark[i].secid) {
226 			ret = apparmor_secmark_init(&profile->secmark[i]);
227 			if (ret)
228 				return ret;
229 		}
230 
231 		if (profile->secmark[i].secid == secid ||
232 		    profile->secmark[i].secid == AA_SECID_WILDCARD) {
233 			if (profile->secmark[i].deny)
234 				perms.deny = ALL_PERMS_MASK;
235 			else
236 				perms.allow = ALL_PERMS_MASK;
237 
238 			if (profile->secmark[i].audit)
239 				perms.audit = ALL_PERMS_MASK;
240 		}
241 	}
242 
243 	aa_apply_modes_to_perms(profile, &perms);
244 
245 	return aa_check_perms(profile, &perms, request, sa, audit_net_cb);
246 }
247 
248 int apparmor_secmark_check(struct aa_label *label, char *op, u32 request,
249 			   u32 secid, struct sock *sk)
250 {
251 	struct aa_profile *profile;
252 	DEFINE_AUDIT_SK(sa, op, sk);
253 
254 	return fn_for_each_confined(label, profile,
255 				    aa_secmark_perm(profile, request, secid,
256 						    &sa, sk));
257 }
258 #endif
259