Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only 2 : : /* 3 : : * AppArmor security module 4 : : * 5 : : * This file contains AppArmor auditing functions 6 : : * 7 : : * Copyright (C) 1998-2008 Novell/SUSE 8 : : * Copyright 2009-2010 Canonical Ltd. 9 : : */ 10 : : 11 : : #include <linux/audit.h> 12 : : #include <linux/socket.h> 13 : : 14 : : #include "include/apparmor.h" 15 : : #include "include/audit.h" 16 : : #include "include/policy.h" 17 : : #include "include/policy_ns.h" 18 : : #include "include/secid.h" 19 : : 20 : : const char *const audit_mode_names[] = { 21 : : "normal", 22 : : "quiet_denied", 23 : : "quiet", 24 : : "noquiet", 25 : : "all" 26 : : }; 27 : : 28 : : static const char *const aa_audit_type[] = { 29 : : "AUDIT", 30 : : "ALLOWED", 31 : : "DENIED", 32 : : "HINT", 33 : : "STATUS", 34 : : "ERROR", 35 : : "KILLED", 36 : : "AUTO" 37 : : }; 38 : : 39 : : /* 40 : : * Currently AppArmor auditing is fed straight into the audit framework. 41 : : * 42 : : * TODO: 43 : : * netlink interface for complain mode 44 : : * user auditing, - send user auditing to netlink interface 45 : : * system control of whether user audit messages go to system log 46 : : */ 47 : : 48 : : /** 49 : : * audit_base - core AppArmor function. 50 : : * @ab: audit buffer to fill (NOT NULL) 51 : : * @ca: audit structure containing data to audit (NOT NULL) 52 : : * 53 : : * Record common AppArmor audit data from @sa 54 : : */ 55 : 0 : static void audit_pre(struct audit_buffer *ab, void *ca) 56 : : { 57 : : struct common_audit_data *sa = ca; 58 : : 59 : 0 : if (aa_g_audit_header) { 60 : 0 : audit_log_format(ab, "apparmor="); 61 : 0 : audit_log_string(ab, aa_audit_type[aad(sa)->type]); 62 : : } 63 : : 64 : 0 : if (aad(sa)->op) { 65 : 0 : audit_log_format(ab, " operation="); 66 : 0 : audit_log_string(ab, aad(sa)->op); 67 : : } 68 : : 69 : 0 : if (aad(sa)->info) { 70 : 0 : audit_log_format(ab, " info="); 71 : 0 : audit_log_string(ab, aad(sa)->info); 72 : 0 : if (aad(sa)->error) 73 : 0 : audit_log_format(ab, " error=%d", aad(sa)->error); 74 : : } 75 : : 76 : 0 : if (aad(sa)->label) { 77 : : struct aa_label *label = aad(sa)->label; 78 : : 79 : 0 : if (label_isprofile(label)) { 80 : 0 : struct aa_profile *profile = labels_profile(label); 81 : : 82 : 0 : if (profile->ns != root_ns) { 83 : 0 : audit_log_format(ab, " namespace="); 84 : 0 : audit_log_untrustedstring(ab, 85 : 0 : profile->ns->base.hname); 86 : : } 87 : 0 : audit_log_format(ab, " profile="); 88 : 0 : audit_log_untrustedstring(ab, profile->base.hname); 89 : : } else { 90 : 0 : audit_log_format(ab, " label="); 91 : 0 : aa_label_xaudit(ab, root_ns, label, FLAG_VIEW_SUBNS, 92 : : GFP_ATOMIC); 93 : : } 94 : : } 95 : : 96 : 0 : if (aad(sa)->name) { 97 : 0 : audit_log_format(ab, " name="); 98 : 0 : audit_log_untrustedstring(ab, aad(sa)->name); 99 : : } 100 : 0 : } 101 : : 102 : : /** 103 : : * aa_audit_msg - Log a message to the audit subsystem 104 : : * @sa: audit event structure (NOT NULL) 105 : : * @cb: optional callback fn for type specific fields (MAYBE NULL) 106 : : */ 107 : 0 : void aa_audit_msg(int type, struct common_audit_data *sa, 108 : : void (*cb) (struct audit_buffer *, void *)) 109 : : { 110 : 0 : aad(sa)->type = type; 111 : 0 : common_lsm_audit(sa, audit_pre, cb); 112 : 0 : } 113 : : 114 : : /** 115 : : * aa_audit - Log a profile based audit event to the audit subsystem 116 : : * @type: audit type for the message 117 : : * @profile: profile to check against (NOT NULL) 118 : : * @sa: audit event (NOT NULL) 119 : : * @cb: optional callback fn for type specific fields (MAYBE NULL) 120 : : * 121 : : * Handle default message switching based off of audit mode flags 122 : : * 123 : : * Returns: error on failure 124 : : */ 125 : 0 : int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa, 126 : : void (*cb) (struct audit_buffer *, void *)) 127 : : { 128 : : AA_BUG(!profile); 129 : : 130 : 0 : if (type == AUDIT_APPARMOR_AUTO) { 131 : 0 : if (likely(!aad(sa)->error)) { 132 : 0 : if (AUDIT_MODE(profile) != AUDIT_ALL) 133 : : return 0; 134 : : type = AUDIT_APPARMOR_AUDIT; 135 : 0 : } else if (COMPLAIN_MODE(profile)) 136 : : type = AUDIT_APPARMOR_ALLOWED; 137 : : else 138 : : type = AUDIT_APPARMOR_DENIED; 139 : : } 140 : 0 : if (AUDIT_MODE(profile) == AUDIT_QUIET || 141 : 0 : (type == AUDIT_APPARMOR_DENIED && 142 : : AUDIT_MODE(profile) == AUDIT_QUIET)) 143 : 0 : return aad(sa)->error; 144 : : 145 : 0 : if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED) 146 : : type = AUDIT_APPARMOR_KILL; 147 : : 148 : 0 : aad(sa)->label = &profile->label; 149 : : 150 : : aa_audit_msg(type, sa, cb); 151 : : 152 : 0 : if (aad(sa)->type == AUDIT_APPARMOR_KILL) 153 : 0 : (void)send_sig_info(SIGKILL, NULL, 154 : 0 : sa->type == LSM_AUDIT_DATA_TASK && sa->u.tsk ? 155 : : sa->u.tsk : current); 156 : : 157 : 0 : if (aad(sa)->type == AUDIT_APPARMOR_ALLOWED) 158 : 0 : return complain_error(aad(sa)->error); 159 : : 160 : 0 : return aad(sa)->error; 161 : : } 162 : : 163 : : struct aa_audit_rule { 164 : : struct aa_label *label; 165 : : }; 166 : : 167 : 0 : void aa_audit_rule_free(void *vrule) 168 : : { 169 : : struct aa_audit_rule *rule = vrule; 170 : : 171 : 0 : if (rule) { 172 : 0 : if (!IS_ERR(rule->label)) 173 : : aa_put_label(rule->label); 174 : 0 : kfree(rule); 175 : : } 176 : 0 : } 177 : : 178 : 0 : int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) 179 : : { 180 : : struct aa_audit_rule *rule; 181 : : 182 : 0 : switch (field) { 183 : : case AUDIT_SUBJ_ROLE: 184 : 0 : if (op != Audit_equal && op != Audit_not_equal) 185 : : return -EINVAL; 186 : : break; 187 : : default: 188 : : return -EINVAL; 189 : : } 190 : : 191 : 0 : rule = kzalloc(sizeof(struct aa_audit_rule), GFP_KERNEL); 192 : : 193 : 0 : if (!rule) 194 : : return -ENOMEM; 195 : : 196 : : /* Currently rules are treated as coming from the root ns */ 197 : 0 : rule->label = aa_label_parse(&root_ns->unconfined->label, rulestr, 198 : : GFP_KERNEL, true, false); 199 : 0 : if (IS_ERR(rule->label)) { 200 : : int err = PTR_ERR(rule->label); 201 : 0 : aa_audit_rule_free(rule); 202 : 0 : return err; 203 : : } 204 : : 205 : 0 : *vrule = rule; 206 : 0 : return 0; 207 : : } 208 : : 209 : 0 : int aa_audit_rule_known(struct audit_krule *rule) 210 : : { 211 : : int i; 212 : : 213 : 0 : for (i = 0; i < rule->field_count; i++) { 214 : 0 : struct audit_field *f = &rule->fields[i]; 215 : : 216 : 0 : switch (f->type) { 217 : : case AUDIT_SUBJ_ROLE: 218 : : return 1; 219 : : } 220 : : } 221 : : 222 : : return 0; 223 : : } 224 : : 225 : 0 : int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule) 226 : : { 227 : : struct aa_audit_rule *rule = vrule; 228 : : struct aa_label *label; 229 : : int found = 0; 230 : : 231 : 0 : label = aa_secid_to_label(sid); 232 : : 233 : 0 : if (!label) 234 : : return -ENOENT; 235 : : 236 : 0 : if (aa_label_is_subset(label, rule->label)) 237 : : found = 1; 238 : : 239 : 0 : switch (field) { 240 : : case AUDIT_SUBJ_ROLE: 241 : 0 : switch (op) { 242 : : case Audit_equal: 243 : 0 : return found; 244 : : case Audit_not_equal: 245 : 0 : return !found; 246 : : } 247 : : } 248 : : return 0; 249 : : }