Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * AppArmor security module
0004  *
0005  * This file contains AppArmor capability mediation functions
0006  *
0007  * Copyright (C) 1998-2008 Novell/SUSE
0008  * Copyright 2009-2010 Canonical Ltd.
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  * Table of capability names: we generate it from capabilities.h.
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  * audit_cb - call back for capability components of audit struct
0041  * @ab - audit buffer   (NOT NULL)
0042  * @va - audit struct to audit data from  (NOT NULL)
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  * audit_caps - audit a capability
0054  * @sa: audit data
0055  * @profile: profile being tested for confinement (NOT NULL)
0056  * @cap: capability tested
0057  * @error: error code returned by test
0058  *
0059  * Do auditing of capability and handle, audit/complain/kill modes switching
0060  * and duplicate message elimination.
0061  *
0062  * Returns: 0 or sa->error on success,  error code on failure
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         /* test if auditing is being forced */
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         /* quiet auditing */
0085         return error;
0086     }
0087 
0088     /* Do simple duplicate message elimination */
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  * profile_capable - test if profile allows use of capability @cap
0107  * @profile: profile being enforced    (NOT NULL, NOT unconfined)
0108  * @cap: capability to test if allowed
0109  * @opts: CAP_OPT_NOAUDIT bit determines whether audit record is generated
0110  * @sa: audit data (MAY BE NULL indicating no auditing)
0111  *
0112  * Returns: 0 if allowed else -EPERM
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         /* audit the cap request in complain mode but note that it
0129          * should be optional.
0130          */
0131         aad(sa)->info = "optional: no audit";
0132     }
0133 
0134     return audit_caps(sa, profile, cap, error);
0135 }
0136 
0137 /**
0138  * aa_capable - test permission to use capability
0139  * @label: label being tested for capability (NOT NULL)
0140  * @cap: capability to be tested
0141  * @opts: CAP_OPT_NOAUDIT bit determines whether audit record is generated
0142  *
0143  * Look up capability in profile capability set.
0144  *
0145  * Returns: 0 on success, or else an error code.
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 }