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->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(struct aa_label *label, const char *op, u32 request, u16 family, 139 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(struct aa_label *label, const char *op, u32 request, 150 struct sock *sk) 151 { 152 struct aa_sk_ctx *ctx = SK_CTX(sk); 153 int error = 0; 154 155 AA_BUG(!label); 156 AA_BUG(!sk); 157 158 if (ctx->label != kernel_t && !unconfined(label)) { 159 struct aa_profile *profile; 160 DEFINE_AUDIT_SK(ad, op, sk); 161 162 error = fn_for_each_confined(label, profile, 163 aa_profile_af_sk_perm(profile, &ad, request, sk)); 164 } 165 166 return error; 167 } 168 169 int aa_sk_perm(const char *op, u32 request, struct sock *sk) 170 { 171 struct aa_label *label; 172 int error; 173 174 AA_BUG(!sk); 175 AA_BUG(in_interrupt()); 176 177 /* TODO: switch to begin_current_label ???? */ 178 label = begin_current_label_crit_section(); 179 error = aa_label_sk_perm(label, op, request, sk); 180 end_current_label_crit_section(label); 181 182 return error; 183 } 184 185 186 int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, 187 struct socket *sock) 188 { 189 AA_BUG(!label); 190 AA_BUG(!sock); 191 AA_BUG(!sock->sk); 192 193 return aa_label_sk_perm(label, op, request, sock->sk); 194 } 195 196 #ifdef CONFIG_NETWORK_SECMARK 197 static int apparmor_secmark_init(struct aa_secmark *secmark) 198 { 199 struct aa_label *label; 200 201 if (secmark->label[0] == '*') { 202 secmark->secid = AA_SECID_WILDCARD; 203 return 0; 204 } 205 206 label = aa_label_strn_parse(&root_ns->unconfined->label, 207 secmark->label, strlen(secmark->label), 208 GFP_ATOMIC, false, false); 209 210 if (IS_ERR(label)) 211 return PTR_ERR(label); 212 213 secmark->secid = label->secid; 214 215 return 0; 216 } 217 218 static int aa_secmark_perm(struct aa_profile *profile, u32 request, u32 secid, 219 struct apparmor_audit_data *ad) 220 { 221 int i, ret; 222 struct aa_perms perms = { }; 223 struct aa_ruleset *rules = list_first_entry(&profile->rules, 224 typeof(*rules), list); 225 226 if (rules->secmark_count == 0) 227 return 0; 228 229 for (i = 0; i < rules->secmark_count; i++) { 230 if (!rules->secmark[i].secid) { 231 ret = apparmor_secmark_init(&rules->secmark[i]); 232 if (ret) 233 return ret; 234 } 235 236 if (rules->secmark[i].secid == secid || 237 rules->secmark[i].secid == AA_SECID_WILDCARD) { 238 if (rules->secmark[i].deny) 239 perms.deny = ALL_PERMS_MASK; 240 else 241 perms.allow = ALL_PERMS_MASK; 242 243 if (rules->secmark[i].audit) 244 perms.audit = ALL_PERMS_MASK; 245 } 246 } 247 248 aa_apply_modes_to_perms(profile, &perms); 249 250 return aa_check_perms(profile, &perms, request, ad, audit_net_cb); 251 } 252 253 int apparmor_secmark_check(struct aa_label *label, char *op, u32 request, 254 u32 secid, const struct sock *sk) 255 { 256 struct aa_profile *profile; 257 DEFINE_AUDIT_SK(ad, op, sk); 258 259 return fn_for_each_confined(label, profile, 260 aa_secmark_perm(profile, request, secid, 261 &ad)); 262 } 263 #endif 264