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