1 // SPDX-License-Identifier: GPL-2.0-only
3 * AppArmor security module
5 * This file contains AppArmor capability mediation functions
7 * Copyright (C) 1998-2008 Novell/SUSE
8 * Copyright 2009-2010 Canonical Ltd.
11 #include <linux/capability.h>
12 #include <linux/errno.h>
13 #include <linux/gfp.h>
14 #include <linux/security.h>
15 #include <linux/timekeeping.h>
17 #include "include/apparmor.h"
18 #include "include/capability.h"
19 #include "include/cred.h"
20 #include "include/policy.h"
21 #include "include/audit.h"
24 * Table of capability names: we generate it from capabilities.h.
26 #include "capability_names.h"
28 struct aa_sfs_entry aa_sfs_entry_caps
[] = {
29 AA_SFS_FILE_STRING("mask", AA_SFS_CAPS_MASK
),
34 const struct cred
*ad_subj_cred
;
35 /* Capabilities go from 0 to CAP_LAST_CAP */
36 u64 ktime_ns_expiration
[CAP_LAST_CAP
+1];
39 static DEFINE_PER_CPU(struct audit_cache
, audit_cache
);
42 * audit_cb - call back for capability components of audit struct
43 * @ab: audit buffer (NOT NULL)
44 * @va: audit struct to audit data from (NOT NULL)
46 static void audit_cb(struct audit_buffer
*ab
, void *va
)
48 struct common_audit_data
*sa
= va
;
50 audit_log_format(ab
, " capname=");
51 audit_log_untrustedstring(ab
, capability_names
[sa
->u
.cap
]);
55 * audit_caps - audit a capability
57 * @profile: profile being tested for confinement (NOT NULL)
58 * @cap: capability tested
59 * @error: error code returned by test
61 * Do auditing of capability and handle, audit/complain/kill modes switching
62 * and duplicate message elimination.
64 * Returns: 0 or ad->error on success, error code on failure
66 static int audit_caps(struct apparmor_audit_data
*ad
, struct aa_profile
*profile
,
69 const u64 AUDIT_CACHE_TIMEOUT_NS
= 1000*1000*1000; /* 1 second */
71 struct aa_ruleset
*rules
= list_first_entry(&profile
->rules
,
72 typeof(*rules
), list
);
73 struct audit_cache
*ent
;
74 int type
= AUDIT_APPARMOR_AUTO
;
79 /* test if auditing is being forced */
80 if (likely((AUDIT_MODE(profile
) != AUDIT_ALL
) &&
81 !cap_raised(rules
->caps
.audit
, cap
)))
83 type
= AUDIT_APPARMOR_AUDIT
;
84 } else if (KILL_MODE(profile
) ||
85 cap_raised(rules
->caps
.kill
, cap
)) {
86 type
= AUDIT_APPARMOR_KILL
;
87 } else if (cap_raised(rules
->caps
.quiet
, cap
) &&
88 AUDIT_MODE(profile
) != AUDIT_NOQUIET
&&
89 AUDIT_MODE(profile
) != AUDIT_ALL
) {
94 /* Do simple duplicate message elimination */
95 ent
= &get_cpu_var(audit_cache
);
96 /* If the capability was never raised the timestamp check would also catch that */
97 if (ad
->subj_cred
== ent
->ad_subj_cred
&& ktime_get_ns() <= ent
->ktime_ns_expiration
[cap
]) {
98 put_cpu_var(audit_cache
);
99 if (COMPLAIN_MODE(profile
))
100 return complain_error(error
);
103 put_cred(ent
->ad_subj_cred
);
104 ent
->ad_subj_cred
= get_cred(ad
->subj_cred
);
105 ent
->ktime_ns_expiration
[cap
] = ktime_get_ns() + AUDIT_CACHE_TIMEOUT_NS
;
107 put_cpu_var(audit_cache
);
109 return aa_audit(type
, profile
, ad
, audit_cb
);
113 * profile_capable - test if profile allows use of capability @cap
114 * @profile: profile being enforced (NOT NULL, NOT unconfined)
115 * @cap: capability to test if allowed
116 * @opts: CAP_OPT_NOAUDIT bit determines whether audit record is generated
117 * @ad: audit data (NOT NULL)
119 * Returns: 0 if allowed else -EPERM
121 static int profile_capable(struct aa_profile
*profile
, int cap
,
122 unsigned int opts
, struct apparmor_audit_data
*ad
)
124 struct aa_ruleset
*rules
= list_first_entry(&profile
->rules
,
125 typeof(*rules
), list
);
128 if (cap_raised(rules
->caps
.allow
, cap
) &&
129 !cap_raised(rules
->caps
.denied
, cap
))
134 if (opts
& CAP_OPT_NOAUDIT
) {
135 if (!COMPLAIN_MODE(profile
))
137 /* audit the cap request in complain mode but note that it
138 * should be optional.
140 ad
->info
= "optional: no audit";
143 return audit_caps(ad
, profile
, cap
, error
);
147 * aa_capable - test permission to use capability
148 * @subj_cred: cred we are testing capability against
149 * @label: label being tested for capability (NOT NULL)
150 * @cap: capability to be tested
151 * @opts: CAP_OPT_NOAUDIT bit determines whether audit record is generated
153 * Look up capability in profile capability set.
155 * Returns: 0 on success, or else an error code.
157 int aa_capable(const struct cred
*subj_cred
, struct aa_label
*label
,
158 int cap
, unsigned int opts
)
160 struct aa_profile
*profile
;
162 DEFINE_AUDIT_DATA(ad
, LSM_AUDIT_DATA_CAP
, AA_CLASS_CAP
, OP_CAPABLE
);
164 ad
.subj_cred
= subj_cred
;
165 ad
.common
.u
.cap
= cap
;
166 error
= fn_for_each_confined(label
, profile
,
167 profile_capable(profile
, cap
, opts
, &ad
));