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 75 audit_log_format(ab, " family="); 76 if (address_family_names[sa->u.net->family]) 77 audit_log_string(ab, address_family_names[sa->u.net->family]); 78 else 79 audit_log_format(ab, "\"unknown(%d)\"", sa->u.net->family); 80 audit_log_format(ab, " sock_type="); 81 if (sock_type_names[aad(sa)->net.type]) 82 audit_log_string(ab, sock_type_names[aad(sa)->net.type]); 83 else 84 audit_log_format(ab, "\"unknown(%d)\"", aad(sa)->net.type); 85 audit_log_format(ab, " protocol=%d", aad(sa)->net.protocol); 86 87 if (aad(sa)->request & NET_PERMS_MASK) { 88 audit_log_format(ab, " requested_mask="); 89 aa_audit_perm_mask(ab, aad(sa)->request, NULL, 0, 90 net_mask_names, NET_PERMS_MASK); 91 92 if (aad(sa)->denied & NET_PERMS_MASK) { 93 audit_log_format(ab, " denied_mask="); 94 aa_audit_perm_mask(ab, aad(sa)->denied, NULL, 0, 95 net_mask_names, NET_PERMS_MASK); 96 } 97 } 98 if (aad(sa)->peer) { 99 audit_log_format(ab, " peer="); 100 aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer, 101 FLAGS_NONE, GFP_ATOMIC); 102 } 103 } 104 105 /* Generic af perm */ 106 int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa, 107 u32 request, u16 family, int type) 108 { 109 struct aa_perms perms = { }; 110 unsigned int state; 111 __be16 buffer[2]; 112 113 AA_BUG(family >= AF_MAX); 114 AA_BUG(type < 0 || type >= SOCK_MAX); 115 116 if (profile_unconfined(profile)) 117 return 0; 118 state = PROFILE_MEDIATES(profile, AA_CLASS_NET); 119 if (!state) 120 return 0; 121 122 buffer[0] = cpu_to_be16(family); 123 buffer[1] = cpu_to_be16((u16) type); 124 state = aa_dfa_match_len(profile->policy.dfa, state, (char *) &buffer, 125 4); 126 aa_compute_perms(profile->policy.dfa, state, &perms); 127 aa_apply_modes_to_perms(profile, &perms); 128 129 return aa_check_perms(profile, &perms, request, sa, audit_net_cb); 130 } 131 132 int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family, 133 int type, int protocol) 134 { 135 struct aa_profile *profile; 136 DEFINE_AUDIT_NET(sa, op, NULL, family, type, protocol); 137 138 return fn_for_each_confined(label, profile, 139 aa_profile_af_perm(profile, &sa, request, family, 140 type)); 141 } 142 143 static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request, 144 struct sock *sk) 145 { 146 int error = 0; 147 148 AA_BUG(!label); 149 AA_BUG(!sk); 150 151 if (!unconfined(label)) { 152 struct aa_profile *profile; 153 DEFINE_AUDIT_SK(sa, op, sk); 154 155 error = fn_for_each_confined(label, profile, 156 aa_profile_af_sk_perm(profile, &sa, request, sk)); 157 } 158 159 return error; 160 } 161 162 int aa_sk_perm(const char *op, u32 request, struct sock *sk) 163 { 164 struct aa_label *label; 165 int error; 166 167 AA_BUG(!sk); 168 AA_BUG(in_interrupt()); 169 170 /* TODO: switch to begin_current_label ???? */ 171 label = begin_current_label_crit_section(); 172 error = aa_label_sk_perm(label, op, request, sk); 173 end_current_label_crit_section(label); 174 175 return error; 176 } 177 178 179 int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, 180 struct socket *sock) 181 { 182 AA_BUG(!label); 183 AA_BUG(!sock); 184 AA_BUG(!sock->sk); 185 186 return aa_label_sk_perm(label, op, request, sock->sk); 187 } 188 189 #ifdef CONFIG_NETWORK_SECMARK 190 static int apparmor_secmark_init(struct aa_secmark *secmark) 191 { 192 struct aa_label *label; 193 194 if (secmark->label[0] == '*') { 195 secmark->secid = AA_SECID_WILDCARD; 196 return 0; 197 } 198 199 label = aa_label_strn_parse(&root_ns->unconfined->label, 200 secmark->label, strlen(secmark->label), 201 GFP_ATOMIC, false, false); 202 203 if (IS_ERR(label)) 204 return PTR_ERR(label); 205 206 secmark->secid = label->secid; 207 208 return 0; 209 } 210 211 static int aa_secmark_perm(struct aa_profile *profile, u32 request, u32 secid, 212 struct common_audit_data *sa, struct sock *sk) 213 { 214 int i, ret; 215 struct aa_perms perms = { }; 216 217 if (profile->secmark_count == 0) 218 return 0; 219 220 for (i = 0; i < profile->secmark_count; i++) { 221 if (!profile->secmark[i].secid) { 222 ret = apparmor_secmark_init(&profile->secmark[i]); 223 if (ret) 224 return ret; 225 } 226 227 if (profile->secmark[i].secid == secid || 228 profile->secmark[i].secid == AA_SECID_WILDCARD) { 229 if (profile->secmark[i].deny) 230 perms.deny = ALL_PERMS_MASK; 231 else 232 perms.allow = ALL_PERMS_MASK; 233 234 if (profile->secmark[i].audit) 235 perms.audit = ALL_PERMS_MASK; 236 } 237 } 238 239 aa_apply_modes_to_perms(profile, &perms); 240 241 return aa_check_perms(profile, &perms, request, sa, audit_net_cb); 242 } 243 244 int apparmor_secmark_check(struct aa_label *label, char *op, u32 request, 245 u32 secid, struct sock *sk) 246 { 247 struct aa_profile *profile; 248 DEFINE_AUDIT_SK(sa, op, sk); 249 250 return fn_for_each_confined(label, profile, 251 aa_secmark_perm(profile, request, secid, 252 &sa, sk)); 253 } 254 #endif 255