[PATCH] new predicate - AUDIT_FILETYPE
authorAl Viro <viro@zeniv.linux.org.uk>
Mon, 28 Apr 2008 08:15:49 +0000 (04:15 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 28 Apr 2008 10:28:37 +0000 (06:28 -0400)
Argument is S_IF... | <index>, where index is normally 0 or 1.
Triggers if chosen element of ctx->names[] is present and the
mode of object in question matches the upper bits of argument.
I.e. for things like "is the argument of that chmod a directory",
etc.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
include/linux/audit.h
kernel/auditfilter.c
kernel/auditsc.c

index dcd5395..63c3bb9 100644 (file)
 #define AUDIT_WATCH    105
 #define AUDIT_PERM     106
 #define AUDIT_DIR      107
+#define AUDIT_FILETYPE 108
 
 #define AUDIT_ARG0      200
 #define AUDIT_ARG1      (AUDIT_ARG0+1)
index 7c3450d..9435d93 100644 (file)
@@ -478,6 +478,10 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
                        if (f->val & ~15)
                                goto exit_free;
                        break;
+               case AUDIT_FILETYPE:
+                       if ((f->val & ~S_IFMT) > S_IFMT)
+                               goto exit_free;
+                       break;
                case AUDIT_INODE:
                        err = audit_to_inode(&entry->rule, f);
                        if (err)
@@ -649,6 +653,10 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
                        if (f->val & ~15)
                                goto exit_free;
                        break;
+               case AUDIT_FILETYPE:
+                       if ((f->val & ~S_IFMT) > S_IFMT)
+                               goto exit_free;
+                       break;
                default:
                        goto exit_free;
                }
index 0914099..c10e7aa 100644 (file)
@@ -280,6 +280,19 @@ static int audit_match_perm(struct audit_context *ctx, int mask)
        }
 }
 
+static int audit_match_filetype(struct audit_context *ctx, int which)
+{
+       unsigned index = which & ~S_IFMT;
+       mode_t mode = which & S_IFMT;
+       if (index >= ctx->name_count)
+               return 0;
+       if (ctx->names[index].ino == -1)
+               return 0;
+       if ((ctx->names[index].mode ^ mode) & S_IFMT)
+               return 0;
+       return 1;
+}
+
 /*
  * We keep a linked list of fixed-sized (31 pointer) arrays of audit_chunk *;
  * ->first_trees points to its beginning, ->trees - to the current end of data.
@@ -589,6 +602,9 @@ static int audit_filter_rules(struct task_struct *tsk,
                case AUDIT_PERM:
                        result = audit_match_perm(ctx, f->val);
                        break;
+               case AUDIT_FILETYPE:
+                       result = audit_match_filetype(ctx, f->val);
+                       break;
                }
 
                if (!result)