apparmor: update cap audit to check SECURITY_CAP_NOAUDIT
authorJohn Johansen <john.johansen@canonical.com>
Mon, 16 Jan 2017 08:43:08 +0000 (00:43 -0800)
committerJohn Johansen <john.johansen@canonical.com>
Mon, 16 Jan 2017 09:18:50 +0000 (01:18 -0800)
apparmor should be checking the SECURITY_CAP_NOAUDIT constant. Also
in complain mode make it so apparmor can elect to log a message,
informing of the check.

Signed-off-by: John Johansen <john.johansen@canonical.com>
security/apparmor/capability.c

index 1d2e2de5515f3552cad35a4ef81eedbaa1070309..ed0a3e6b8022de59e523730454e97fbd0d74ec0b 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/capability.h>
 #include <linux/errno.h>
 #include <linux/gfp.h>
+#include <linux/security.h>
 
 #include "include/apparmor.h"
 #include "include/capability.h"
@@ -55,6 +56,7 @@ static void audit_cb(struct audit_buffer *ab, void *va)
  * audit_caps - audit a capability
  * @profile: profile being tested for confinement (NOT NULL)
  * @cap: capability tested
+ @audit: whether an audit record should be generated
  * @error: error code returned by test
  *
  * Do auditing of capability and handle, audit/complain/kill modes switching
@@ -62,13 +64,16 @@ static void audit_cb(struct audit_buffer *ab, void *va)
  *
  * Returns: 0 or sa->error on success,  error code on failure
  */
-static int audit_caps(struct aa_profile *profile, int cap, int error)
+static int audit_caps(struct aa_profile *profile, int cap, int audit,
+                     int error)
 {
        struct audit_cache *ent;
        int type = AUDIT_APPARMOR_AUTO;
        DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_CAP, OP_CAPABLE);
        sa.u.cap = cap;
        aad(&sa)->error = error;
+       if (audit == SECURITY_CAP_NOAUDIT)
+               aad(&sa)->info = "optional: no audit";
 
        if (likely(!error)) {
                /* test if auditing is being forced */
@@ -129,11 +134,10 @@ int aa_capable(struct aa_profile *profile, int cap, int audit)
 {
        int error = profile_capable(profile, cap);
 
-       if (!audit) {
-               if (COMPLAIN_MODE(profile))
-                       return complain_error(error);
-               return error;
+       if (audit == SECURITY_CAP_NOAUDIT) {
+               if (!COMPLAIN_MODE(profile))
+                       return error;
        }
 
-       return audit_caps(profile, cap, error);
+       return audit_caps(profile, cap, audit, error);
 }