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