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