0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/capability.h>
0012 #include <linux/errno.h>
0013 #include <linux/gfp.h>
0014 #include <linux/security.h>
0015
0016 #include "include/apparmor.h"
0017 #include "include/capability.h"
0018 #include "include/cred.h"
0019 #include "include/policy.h"
0020 #include "include/audit.h"
0021
0022
0023
0024
0025 #include "capability_names.h"
0026
0027 struct aa_sfs_entry aa_sfs_entry_caps[] = {
0028 AA_SFS_FILE_STRING("mask", AA_SFS_CAPS_MASK),
0029 { }
0030 };
0031
0032 struct audit_cache {
0033 struct aa_profile *profile;
0034 kernel_cap_t caps;
0035 };
0036
0037 static DEFINE_PER_CPU(struct audit_cache, audit_cache);
0038
0039
0040
0041
0042
0043
0044 static void audit_cb(struct audit_buffer *ab, void *va)
0045 {
0046 struct common_audit_data *sa = va;
0047
0048 audit_log_format(ab, " capname=");
0049 audit_log_untrustedstring(ab, capability_names[sa->u.cap]);
0050 }
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile,
0065 int cap, int error)
0066 {
0067 struct audit_cache *ent;
0068 int type = AUDIT_APPARMOR_AUTO;
0069
0070 aad(sa)->error = error;
0071
0072 if (likely(!error)) {
0073
0074 if (likely((AUDIT_MODE(profile) != AUDIT_ALL) &&
0075 !cap_raised(profile->caps.audit, cap)))
0076 return 0;
0077 type = AUDIT_APPARMOR_AUDIT;
0078 } else if (KILL_MODE(profile) ||
0079 cap_raised(profile->caps.kill, cap)) {
0080 type = AUDIT_APPARMOR_KILL;
0081 } else if (cap_raised(profile->caps.quiet, cap) &&
0082 AUDIT_MODE(profile) != AUDIT_NOQUIET &&
0083 AUDIT_MODE(profile) != AUDIT_ALL) {
0084
0085 return error;
0086 }
0087
0088
0089 ent = &get_cpu_var(audit_cache);
0090 if (profile == ent->profile && cap_raised(ent->caps, cap)) {
0091 put_cpu_var(audit_cache);
0092 if (COMPLAIN_MODE(profile))
0093 return complain_error(error);
0094 return error;
0095 } else {
0096 aa_put_profile(ent->profile);
0097 ent->profile = aa_get_profile(profile);
0098 cap_raise(ent->caps, cap);
0099 }
0100 put_cpu_var(audit_cache);
0101
0102 return aa_audit(type, profile, sa, audit_cb);
0103 }
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114 static int profile_capable(struct aa_profile *profile, int cap,
0115 unsigned int opts, struct common_audit_data *sa)
0116 {
0117 int error;
0118
0119 if (cap_raised(profile->caps.allow, cap) &&
0120 !cap_raised(profile->caps.denied, cap))
0121 error = 0;
0122 else
0123 error = -EPERM;
0124
0125 if (opts & CAP_OPT_NOAUDIT) {
0126 if (!COMPLAIN_MODE(profile))
0127 return error;
0128
0129
0130
0131 aad(sa)->info = "optional: no audit";
0132 }
0133
0134 return audit_caps(sa, profile, cap, error);
0135 }
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147 int aa_capable(struct aa_label *label, int cap, unsigned int opts)
0148 {
0149 struct aa_profile *profile;
0150 int error = 0;
0151 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_CAP, OP_CAPABLE);
0152
0153 sa.u.cap = cap;
0154 error = fn_for_each_confined(label, profile,
0155 profile_capable(profile, cap, opts, &sa));
0156
0157 return error;
0158 }