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_networkv9[] = { 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 const struct sock *sk) 99 { 100 const struct unix_sock *u = unix_sk(sk); 101 102 if (u && u->addr) { 103 int addrlen; 104 struct sockaddr_un *addr = aa_sunaddr(u, &addrlen); 105 106 audit_unix_addr(ab, str, addr, addrlen); 107 } else { 108 audit_unix_addr(ab, str, NULL, 0); 109 110 } 111 } 112 113 /* audit callback for net specific fields */ 114 void audit_net_cb(struct audit_buffer *ab, void *va) 115 { 116 struct common_audit_data *sa = va; 117 struct apparmor_audit_data *ad = aad(sa); 118 119 if (address_family_names[ad->common.u.net->family]) 120 audit_log_format(ab, " family=\"%s\"", 121 address_family_names[ad->common.u.net->family]); 122 else 123 audit_log_format(ab, " family=\"unknown(%d)\"", 124 ad->common.u.net->family); 125 if (sock_type_names[ad->net.type]) 126 audit_log_format(ab, " sock_type=\"%s\"", 127 sock_type_names[ad->net.type]); 128 else 129 audit_log_format(ab, " sock_type=\"unknown(%d)\"", 130 ad->net.type); 131 audit_log_format(ab, " protocol=%d", ad->net.protocol); 132 133 if (ad->request & NET_PERMS_MASK) { 134 audit_log_format(ab, " requested_mask="); 135 aa_audit_perm_mask(ab, ad->request, NULL, 0, 136 net_mask_names, NET_PERMS_MASK); 137 138 if (ad->denied & NET_PERMS_MASK) { 139 audit_log_format(ab, " denied_mask="); 140 aa_audit_perm_mask(ab, ad->denied, NULL, 0, 141 net_mask_names, NET_PERMS_MASK); 142 } 143 } 144 if (ad->common.u.net->family == PF_UNIX) { 145 if (ad->net.addr || !ad->common.u.net->sk) 146 audit_unix_addr(ab, "addr", 147 unix_addr(ad->net.addr), 148 ad->net.addrlen); 149 else 150 audit_unix_sk_addr(ab, "addr", ad->common.u.net->sk); 151 if (ad->request & NET_PEER_MASK) { 152 audit_unix_addr(ab, "peer_addr", 153 unix_addr(ad->net.peer.addr), 154 ad->net.peer.addrlen); 155 } 156 } 157 if (ad->peer) { 158 audit_log_format(ab, " peer="); 159 aa_label_xaudit(ab, labels_ns(ad->subj_label), ad->peer, 160 FLAGS_NONE, GFP_ATOMIC); 161 } 162 } 163 164 /* standard permission lookup pattern - supports early bailout */ 165 int aa_do_perms(struct aa_profile *profile, struct aa_policydb *policy, 166 aa_state_t state, u32 request, 167 struct aa_perms *p, struct apparmor_audit_data *ad) 168 { 169 struct aa_perms perms; 170 171 AA_BUG(!profile); 172 AA_BUG(!policy); 173 174 175 if (state || !p) 176 p = aa_lookup_perms(policy, state); 177 perms = *p; 178 aa_apply_modes_to_perms(profile, &perms); 179 return aa_check_perms(profile, &perms, request, ad, 180 audit_net_cb); 181 } 182 183 /* only continue match if 184 * insufficient current perms at current state 185 * indicates there are more perms in later state 186 * Returns: perms struct if early match 187 */ 188 static struct aa_perms *early_match(struct aa_policydb *policy, 189 aa_state_t state, u32 request) 190 { 191 struct aa_perms *p; 192 193 p = aa_lookup_perms(policy, state); 194 if (((p->allow & request) != request) && (p->allow & AA_CONT_MATCH)) 195 return NULL; 196 return p; 197 } 198 199 static aa_state_t aa_dfa_match_be16(struct aa_dfa *dfa, aa_state_t state, 200 u16 data) 201 { 202 __be16 buffer = cpu_to_be16(data); 203 204 return aa_dfa_match_len(dfa, state, (char *) &buffer, 2); 205 } 206 207 /** 208 * aa_match_to_prot - match the af, type, protocol triplet 209 * @policy: policy being matched 210 * @state: state to start in 211 * @request: permissions being requested, ignored if @p == NULL 212 * @af: socket address family 213 * @type: socket type 214 * @protocol: socket protocol 215 * @p: output - pointer to permission associated with match 216 * @info: output - pointer to string describing failure 217 * 218 * RETURNS: state match stopped in. 219 * 220 * If @(p) is assigned a value the returned state will be the 221 * corresponding state. Will not set @p on failure or if match completes 222 * only if an early match occurs 223 */ 224 aa_state_t aa_match_to_prot(struct aa_policydb *policy, aa_state_t state, 225 u32 request, u16 af, int type, int protocol, 226 struct aa_perms **p, const char **info) 227 { 228 state = aa_dfa_match_be16(policy->dfa, state, (u16)af); 229 if (!state) { 230 *info = "failed af match"; 231 return state; 232 } 233 state = aa_dfa_match_be16(policy->dfa, state, (u16)type); 234 if (state) { 235 if (p) 236 *p = early_match(policy, state, request); 237 if (!p || !*p) { 238 state = aa_dfa_match_be16(policy->dfa, state, (u16)protocol); 239 if (!state) 240 *info = "failed protocol match"; 241 } 242 } else { 243 *info = "failed type match"; 244 } 245 246 return state; 247 } 248 249 /* Generic af perm */ 250 int aa_profile_af_perm(struct aa_profile *profile, 251 struct apparmor_audit_data *ad, u32 request, u16 family, 252 int type, int protocol) 253 { 254 struct aa_ruleset *rules = profile->label.rules[0]; 255 struct aa_perms *p = NULL; 256 aa_state_t state; 257 258 AA_BUG(family >= AF_MAX); 259 AA_BUG(type < 0 || type >= SOCK_MAX); 260 AA_BUG(profile_unconfined(profile)); 261 262 if (profile_unconfined(profile)) 263 return 0; 264 state = RULE_MEDIATES_NET(rules); 265 if (!state) 266 return 0; 267 state = aa_match_to_prot(rules->policy, state, request, family, type, 268 protocol, &p, &ad->info); 269 return aa_do_perms(profile, rules->policy, state, request, p, ad); 270 } 271 272 int aa_af_perm(const struct cred *subj_cred, struct aa_label *label, 273 const char *op, u32 request, u16 family, int type, int protocol) 274 { 275 struct aa_profile *profile; 276 DEFINE_AUDIT_NET(ad, op, subj_cred, NULL, family, type, protocol); 277 278 return fn_for_each_confined(label, profile, 279 aa_profile_af_perm(profile, &ad, request, family, 280 type, protocol)); 281 } 282 283 static int aa_label_sk_perm(const struct cred *subj_cred, 284 struct aa_label *label, 285 const char *op, u32 request, 286 struct sock *sk) 287 { 288 struct aa_sk_ctx *ctx = aa_sock(sk); 289 int error = 0; 290 291 AA_BUG(!label); 292 AA_BUG(!sk); 293 294 if (rcu_access_pointer(ctx->label) != kernel_t && !unconfined(label)) { 295 struct aa_profile *profile; 296 DEFINE_AUDIT_SK(ad, op, subj_cred, sk); 297 298 ad.subj_cred = subj_cred; 299 error = fn_for_each_confined(label, profile, 300 aa_profile_af_sk_perm(profile, &ad, request, sk)); 301 } 302 303 return error; 304 } 305 306 int aa_sk_perm(const char *op, u32 request, struct sock *sk) 307 { 308 struct aa_label *label; 309 int error; 310 311 AA_BUG(!sk); 312 AA_BUG(in_interrupt()); 313 314 /* TODO: switch to begin_current_label ???? */ 315 label = begin_current_label_crit_section(); 316 error = aa_label_sk_perm(current_cred(), label, op, request, sk); 317 end_current_label_crit_section(label); 318 319 return error; 320 } 321 322 323 int aa_sock_file_perm(const struct cred *subj_cred, struct aa_label *label, 324 const char *op, u32 request, struct file *file) 325 { 326 struct socket *sock = (struct socket *) file->private_data; 327 328 AA_BUG(!label); 329 AA_BUG(!sock); 330 AA_BUG(!sock->sk); 331 332 if (sock->sk->sk_family == PF_UNIX) 333 return aa_unix_file_perm(subj_cred, label, op, request, file); 334 return aa_label_sk_perm(subj_cred, label, op, request, sock->sk); 335 } 336 337 #ifdef CONFIG_NETWORK_SECMARK 338 static int apparmor_secmark_init(struct aa_secmark *secmark) 339 { 340 struct aa_label *label; 341 342 if (secmark->label[0] == '*') { 343 secmark->secid = AA_SECID_WILDCARD; 344 return 0; 345 } 346 347 label = aa_label_strn_parse(&root_ns->unconfined->label, 348 secmark->label, strlen(secmark->label), 349 GFP_ATOMIC, false, false); 350 351 if (IS_ERR(label)) 352 return PTR_ERR(label); 353 354 secmark->secid = label->secid; 355 356 return 0; 357 } 358 359 static int aa_secmark_perm(struct aa_profile *profile, u32 request, u32 secid, 360 struct apparmor_audit_data *ad) 361 { 362 int i, ret; 363 struct aa_perms perms = { }; 364 struct aa_ruleset *rules = profile->label.rules[0]; 365 366 if (rules->secmark_count == 0) 367 return 0; 368 369 for (i = 0; i < rules->secmark_count; i++) { 370 if (!rules->secmark[i].secid) { 371 ret = apparmor_secmark_init(&rules->secmark[i]); 372 if (ret) 373 return ret; 374 } 375 376 if (rules->secmark[i].secid == secid || 377 rules->secmark[i].secid == AA_SECID_WILDCARD) { 378 if (rules->secmark[i].deny) 379 perms.deny = ALL_PERMS_MASK; 380 else 381 perms.allow = ALL_PERMS_MASK; 382 383 if (rules->secmark[i].audit) 384 perms.audit = ALL_PERMS_MASK; 385 } 386 } 387 388 aa_apply_modes_to_perms(profile, &perms); 389 390 return aa_check_perms(profile, &perms, request, ad, audit_net_cb); 391 } 392 393 int apparmor_secmark_check(struct aa_label *label, char *op, u32 request, 394 u32 secid, const struct sock *sk) 395 { 396 struct aa_profile *profile; 397 DEFINE_AUDIT_SK(ad, op, NULL, sk); 398 399 return fn_for_each_confined(label, profile, 400 aa_secmark_perm(profile, request, secid, 401 &ad)); 402 } 403 #endif 404