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