root/security/apparmor/capability.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. audit_cb
  2. audit_caps
  3. profile_capable
  4. aa_capable

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * AppArmor security module
   4  *
   5  * This file contains AppArmor capability mediation functions
   6  *
   7  * Copyright (C) 1998-2008 Novell/SUSE
   8  * Copyright 2009-2010 Canonical Ltd.
   9  */
  10 
  11 #include <linux/capability.h>
  12 #include <linux/errno.h>
  13 #include <linux/gfp.h>
  14 #include <linux/security.h>
  15 
  16 #include "include/apparmor.h"
  17 #include "include/capability.h"
  18 #include "include/cred.h"
  19 #include "include/policy.h"
  20 #include "include/audit.h"
  21 
  22 /*
  23  * Table of capability names: we generate it from capabilities.h.
  24  */
  25 #include "capability_names.h"
  26 
  27 struct aa_sfs_entry aa_sfs_entry_caps[] = {
  28         AA_SFS_FILE_STRING("mask", AA_SFS_CAPS_MASK),
  29         { }
  30 };
  31 
  32 struct audit_cache {
  33         struct aa_profile *profile;
  34         kernel_cap_t caps;
  35 };
  36 
  37 static DEFINE_PER_CPU(struct audit_cache, audit_cache);
  38 
  39 /**
  40  * audit_cb - call back for capability components of audit struct
  41  * @ab - audit buffer   (NOT NULL)
  42  * @va - audit struct to audit data from  (NOT NULL)
  43  */
  44 static void audit_cb(struct audit_buffer *ab, void *va)
  45 {
  46         struct common_audit_data *sa = va;
  47 
  48         audit_log_format(ab, " capname=");
  49         audit_log_untrustedstring(ab, capability_names[sa->u.cap]);
  50 }
  51 
  52 /**
  53  * audit_caps - audit a capability
  54  * @sa: audit data
  55  * @profile: profile being tested for confinement (NOT NULL)
  56  * @cap: capability tested
  57  * @error: error code returned by test
  58  *
  59  * Do auditing of capability and handle, audit/complain/kill modes switching
  60  * and duplicate message elimination.
  61  *
  62  * Returns: 0 or sa->error on success,  error code on failure
  63  */
  64 static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile,
  65                       int cap, int error)
  66 {
  67         struct audit_cache *ent;
  68         int type = AUDIT_APPARMOR_AUTO;
  69 
  70         aad(sa)->error = error;
  71 
  72         if (likely(!error)) {
  73                 /* test if auditing is being forced */
  74                 if (likely((AUDIT_MODE(profile) != AUDIT_ALL) &&
  75                            !cap_raised(profile->caps.audit, cap)))
  76                         return 0;
  77                 type = AUDIT_APPARMOR_AUDIT;
  78         } else if (KILL_MODE(profile) ||
  79                    cap_raised(profile->caps.kill, cap)) {
  80                 type = AUDIT_APPARMOR_KILL;
  81         } else if (cap_raised(profile->caps.quiet, cap) &&
  82                    AUDIT_MODE(profile) != AUDIT_NOQUIET &&
  83                    AUDIT_MODE(profile) != AUDIT_ALL) {
  84                 /* quiet auditing */
  85                 return error;
  86         }
  87 
  88         /* Do simple duplicate message elimination */
  89         ent = &get_cpu_var(audit_cache);
  90         if (profile == ent->profile && cap_raised(ent->caps, cap)) {
  91                 put_cpu_var(audit_cache);
  92                 if (COMPLAIN_MODE(profile))
  93                         return complain_error(error);
  94                 return error;
  95         } else {
  96                 aa_put_profile(ent->profile);
  97                 ent->profile = aa_get_profile(profile);
  98                 cap_raise(ent->caps, cap);
  99         }
 100         put_cpu_var(audit_cache);
 101 
 102         return aa_audit(type, profile, sa, audit_cb);
 103 }
 104 
 105 /**
 106  * profile_capable - test if profile allows use of capability @cap
 107  * @profile: profile being enforced    (NOT NULL, NOT unconfined)
 108  * @cap: capability to test if allowed
 109  * @opts: CAP_OPT_NOAUDIT bit determines whether audit record is generated
 110  * @sa: audit data (MAY BE NULL indicating no auditing)
 111  *
 112  * Returns: 0 if allowed else -EPERM
 113  */
 114 static int profile_capable(struct aa_profile *profile, int cap,
 115                            unsigned int opts, struct common_audit_data *sa)
 116 {
 117         int error;
 118 
 119         if (cap_raised(profile->caps.allow, cap) &&
 120             !cap_raised(profile->caps.denied, cap))
 121                 error = 0;
 122         else
 123                 error = -EPERM;
 124 
 125         if (opts & CAP_OPT_NOAUDIT) {
 126                 if (!COMPLAIN_MODE(profile))
 127                         return error;
 128                 /* audit the cap request in complain mode but note that it
 129                  * should be optional.
 130                  */
 131                 aad(sa)->info = "optional: no audit";
 132         }
 133 
 134         return audit_caps(sa, profile, cap, error);
 135 }
 136 
 137 /**
 138  * aa_capable - test permission to use capability
 139  * @label: label being tested for capability (NOT NULL)
 140  * @cap: capability to be tested
 141  * @opts: CAP_OPT_NOAUDIT bit determines whether audit record is generated
 142  *
 143  * Look up capability in profile capability set.
 144  *
 145  * Returns: 0 on success, or else an error code.
 146  */
 147 int aa_capable(struct aa_label *label, int cap, unsigned int opts)
 148 {
 149         struct aa_profile *profile;
 150         int error = 0;
 151         DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_CAP, OP_CAPABLE);
 152 
 153         sa.u.cap = cap;
 154         error = fn_for_each_confined(label, profile,
 155                         profile_capable(profile, cap, opts, &sa));
 156 
 157         return error;
 158 }

/* [<][>][^][v][top][bottom][index][help] */