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