aboutsummaryrefslogtreecommitdiffstats
path: root/security/apparmor/capability.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/apparmor/capability.c')
-rw-r--r--security/apparmor/capability.c61
1 files changed, 40 insertions, 21 deletions
diff --git a/security/apparmor/capability.c b/security/apparmor/capability.c
index ed0a3e6b8022..67e347192a55 100644
--- a/security/apparmor/capability.c
+++ b/security/apparmor/capability.c
@@ -28,8 +28,8 @@
28 */ 28 */
29#include "capability_names.h" 29#include "capability_names.h"
30 30
31struct aa_fs_entry aa_fs_entry_caps[] = { 31struct aa_sfs_entry aa_sfs_entry_caps[] = {
32 AA_FS_FILE_STRING("mask", AA_FS_CAPS_MASK), 32 AA_SFS_FILE_STRING("mask", AA_SFS_CAPS_MASK),
33 { } 33 { }
34}; 34};
35 35
@@ -48,15 +48,16 @@ static DEFINE_PER_CPU(struct audit_cache, audit_cache);
48static void audit_cb(struct audit_buffer *ab, void *va) 48static void audit_cb(struct audit_buffer *ab, void *va)
49{ 49{
50 struct common_audit_data *sa = va; 50 struct common_audit_data *sa = va;
51
51 audit_log_format(ab, " capname="); 52 audit_log_format(ab, " capname=");
52 audit_log_untrustedstring(ab, capability_names[sa->u.cap]); 53 audit_log_untrustedstring(ab, capability_names[sa->u.cap]);
53} 54}
54 55
55/** 56/**
56 * audit_caps - audit a capability 57 * audit_caps - audit a capability
58 * @sa: audit data
57 * @profile: profile being tested for confinement (NOT NULL) 59 * @profile: profile being tested for confinement (NOT NULL)
58 * @cap: capability tested 60 * @cap: capability tested
59 @audit: whether an audit record should be generated
60 * @error: error code returned by test 61 * @error: error code returned by test
61 * 62 *
62 * Do auditing of capability and handle, audit/complain/kill modes switching 63 * Do auditing of capability and handle, audit/complain/kill modes switching
@@ -64,16 +65,13 @@ static void audit_cb(struct audit_buffer *ab, void *va)
64 * 65 *
65 * Returns: 0 or sa->error on success, error code on failure 66 * Returns: 0 or sa->error on success, error code on failure
66 */ 67 */
67static int audit_caps(struct aa_profile *profile, int cap, int audit, 68static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile,
68 int error) 69 int cap, int error)
69{ 70{
70 struct audit_cache *ent; 71 struct audit_cache *ent;
71 int type = AUDIT_APPARMOR_AUTO; 72 int type = AUDIT_APPARMOR_AUTO;
72 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_CAP, OP_CAPABLE); 73
73 sa.u.cap = cap; 74 aad(sa)->error = error;
74 aad(&sa)->error = error;
75 if (audit == SECURITY_CAP_NOAUDIT)
76 aad(&sa)->info = "optional: no audit";
77 75
78 if (likely(!error)) { 76 if (likely(!error)) {
79 /* test if auditing is being forced */ 77 /* test if auditing is being forced */
@@ -105,24 +103,44 @@ static int audit_caps(struct aa_profile *profile, int cap, int audit,
105 } 103 }
106 put_cpu_var(audit_cache); 104 put_cpu_var(audit_cache);
107 105
108 return aa_audit(type, profile, &sa, audit_cb); 106 return aa_audit(type, profile, sa, audit_cb);
109} 107}
110 108
111/** 109/**
112 * profile_capable - test if profile allows use of capability @cap 110 * profile_capable - test if profile allows use of capability @cap
113 * @profile: profile being enforced (NOT NULL, NOT unconfined) 111 * @profile: profile being enforced (NOT NULL, NOT unconfined)
114 * @cap: capability to test if allowed 112 * @cap: capability to test if allowed
113 * @audit: whether an audit record should be generated
114 * @sa: audit data (MAY BE NULL indicating no auditing)
115 * 115 *
116 * Returns: 0 if allowed else -EPERM 116 * Returns: 0 if allowed else -EPERM
117 */ 117 */
118static int profile_capable(struct aa_profile *profile, int cap) 118static int profile_capable(struct aa_profile *profile, int cap, int audit,
119 struct common_audit_data *sa)
119{ 120{
120 return cap_raised(profile->caps.allow, cap) ? 0 : -EPERM; 121 int error;
122
123 if (cap_raised(profile->caps.allow, cap) &&
124 !cap_raised(profile->caps.denied, cap))
125 error = 0;
126 else
127 error = -EPERM;
128
129 if (audit == SECURITY_CAP_NOAUDIT) {
130 if (!COMPLAIN_MODE(profile))
131 return error;
132 /* audit the cap request in complain mode but note that it
133 * should be optional.
134 */
135 aad(sa)->info = "optional: no audit";
136 }
137
138 return audit_caps(sa, profile, cap, error);
121} 139}
122 140
123/** 141/**
124 * aa_capable - test permission to use capability 142 * aa_capable - test permission to use capability
125 * @profile: profile being tested against (NOT NULL) 143 * @label: label being tested for capability (NOT NULL)
126 * @cap: capability to be tested 144 * @cap: capability to be tested
127 * @audit: whether an audit record should be generated 145 * @audit: whether an audit record should be generated
128 * 146 *
@@ -130,14 +148,15 @@ static int profile_capable(struct aa_profile *profile, int cap)
130 * 148 *
131 * Returns: 0 on success, or else an error code. 149 * Returns: 0 on success, or else an error code.
132 */ 150 */
133int aa_capable(struct aa_profile *profile, int cap, int audit) 151int aa_capable(struct aa_label *label, int cap, int audit)
134{ 152{
135 int error = profile_capable(profile, cap); 153 struct aa_profile *profile;
154 int error = 0;
155 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_CAP, OP_CAPABLE);
136 156
137 if (audit == SECURITY_CAP_NOAUDIT) { 157 sa.u.cap = cap;
138 if (!COMPLAIN_MODE(profile)) 158 error = fn_for_each_confined(label, profile,
139 return error; 159 profile_capable(profile, cap, audit, &sa));
140 }
141 160
142 return audit_caps(profile, cap, audit, error); 161 return error;
143} 162}