]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - kernel/auditfilter.c
ext4: start searching for the right extent from the goal group.
[linux-2.6-omap-h63xx.git] / kernel / auditfilter.c
index 7c69cb5e44fb87e1126f76f7ed54b0d0b36172e8..98c50cc671bb85525f8534cc422bc692dbef5dc9 100644 (file)
@@ -89,14 +89,9 @@ struct list_head audit_filter_list[AUDIT_NR_FILTERS] = {
 
 DEFINE_MUTEX(audit_filter_mutex);
 
-/* Inotify handle */
-extern struct inotify_handle *audit_ih;
-
 /* Inotify events we care about. */
 #define AUDIT_IN_WATCH IN_MOVE|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MOVE_SELF
 
-extern int audit_enabled;
-
 void audit_free_parent(struct inotify_watch *i_watch)
 {
        struct audit_parent *parent;
@@ -139,8 +134,8 @@ static inline void audit_free_rule(struct audit_entry *e)
        if (e->rule.fields)
                for (i = 0; i < e->rule.field_count; i++) {
                        struct audit_field *f = &e->rule.fields[i];
-                       kfree(f->se_str);
-                       security_audit_rule_free(f->se_rule);
+                       kfree(f->lsm_str);
+                       security_audit_rule_free(f->lsm_rule);
                }
        kfree(e->rule.fields);
        kfree(e->rule.filterkey);
@@ -272,7 +267,7 @@ static int audit_to_watch(struct audit_krule *krule, char *path, int len,
                return -EINVAL;
 
        watch = audit_init_watch(path);
-       if (unlikely(IS_ERR(watch)))
+       if (IS_ERR(watch))
                return PTR_ERR(watch);
 
        audit_get_watch(watch);
@@ -422,7 +417,7 @@ exit_err:
 static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
 {
        struct audit_entry *entry;
-       struct audit_field *f;
+       struct audit_field *ino_f;
        int err = 0;
        int i;
 
@@ -483,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)
@@ -504,9 +503,9 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
                }
        }
 
-       f = entry->rule.inode_f;
-       if (f) {
-               switch(f->op) {
+       ino_f = entry->rule.inode_f;
+       if (ino_f) {
+               switch(ino_f->op) {
                case AUDIT_NOT_EQUAL:
                        entry->rule.inode_f = NULL;
                case AUDIT_EQUAL:
@@ -531,7 +530,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
 {
        int err = 0;
        struct audit_entry *entry;
-       struct audit_field *f;
+       struct audit_field *ino_f;
        void *bufp;
        size_t remain = datasz - sizeof(struct audit_rule_data);
        int i;
@@ -554,8 +553,8 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
                f->op = data->fieldflags[i] & AUDIT_OPERATORS;
                f->type = data->fields[i];
                f->val = data->values[i];
-               f->se_str = NULL;
-               f->se_rule = NULL;
+               f->lsm_str = NULL;
+               f->lsm_rule = NULL;
                switch(f->type) {
                case AUDIT_PID:
                case AUDIT_UID:
@@ -598,7 +597,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
                        entry->rule.buflen += f->val;
 
                        err = security_audit_rule_init(f->type, f->op, str,
-                                                      (void **)&f->se_rule);
+                                                      (void **)&f->lsm_rule);
                        /* Keep currently invalid fields around in case they
                         * become valid after a policy reload. */
                        if (err == -EINVAL) {
@@ -610,7 +609,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
                                kfree(str);
                                goto exit_free;
                        } else
-                               f->se_str = str;
+                               f->lsm_str = str;
                        break;
                case AUDIT_WATCH:
                        str = audit_unpack_string(&bufp, &remain, f->val);
@@ -654,14 +653,18 @@ 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;
                }
        }
 
-       f = entry->rule.inode_f;
-       if (f) {
-               switch(f->op) {
+       ino_f = entry->rule.inode_f;
+       if (ino_f) {
+               switch(ino_f->op) {
                case AUDIT_NOT_EQUAL:
                        entry->rule.inode_f = NULL;
                case AUDIT_EQUAL:
@@ -754,7 +757,7 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule)
                case AUDIT_OBJ_LEV_LOW:
                case AUDIT_OBJ_LEV_HIGH:
                        data->buflen += data->values[i] =
-                               audit_pack_string(&bufp, f->se_str);
+                               audit_pack_string(&bufp, f->lsm_str);
                        break;
                case AUDIT_WATCH:
                        data->buflen += data->values[i] =
@@ -806,7 +809,7 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b)
                case AUDIT_OBJ_TYPE:
                case AUDIT_OBJ_LEV_LOW:
                case AUDIT_OBJ_LEV_HIGH:
-                       if (strcmp(a->fields[i].se_str, b->fields[i].se_str))
+                       if (strcmp(a->fields[i].lsm_str, b->fields[i].lsm_str))
                                return 1;
                        break;
                case AUDIT_WATCH:
@@ -848,7 +851,7 @@ static struct audit_watch *audit_dupe_watch(struct audit_watch *old)
                return ERR_PTR(-ENOMEM);
 
        new = audit_init_watch(path);
-       if (unlikely(IS_ERR(new))) {
+       if (IS_ERR(new)) {
                kfree(path);
                goto out;
        }
@@ -862,28 +865,28 @@ out:
        return new;
 }
 
-/* Duplicate LSM field information.  The se_rule is opaque, so must be
+/* Duplicate LSM field information.  The lsm_rule is opaque, so must be
  * re-initialized. */
 static inline int audit_dupe_lsm_field(struct audit_field *df,
                                           struct audit_field *sf)
 {
        int ret = 0;
-       char *se_str;
+       char *lsm_str;
 
-       /* our own copy of se_str */
-       se_str = kstrdup(sf->se_str, GFP_KERNEL);
-       if (unlikely(!se_str))
+       /* our own copy of lsm_str */
+       lsm_str = kstrdup(sf->lsm_str, GFP_KERNEL);
+       if (unlikely(!lsm_str))
                return -ENOMEM;
-       df->se_str = se_str;
+       df->lsm_str = lsm_str;
 
-       /* our own (refreshed) copy of se_rule */
-       ret = security_audit_rule_init(df->type, df->op, df->se_str,
-                                      (void **)&df->se_rule);
+       /* our own (refreshed) copy of lsm_rule */
+       ret = security_audit_rule_init(df->type, df->op, df->lsm_str,
+                                      (void **)&df->lsm_rule);
        /* Keep currently invalid fields around in case they
         * become valid after a policy reload. */
        if (ret == -EINVAL) {
                printk(KERN_WARNING "audit rule for LSM \'%s\' is "
-                      "invalid\n", df->se_str);
+                      "invalid\n", df->lsm_str);
                ret = 0;
        }
 
@@ -930,7 +933,7 @@ static struct audit_entry *audit_dupe_rule(struct audit_krule *old,
        new->tree = old->tree;
        memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount);
 
-       /* deep copy this information, updating the se_rule fields, because
+       /* deep copy this information, updating the lsm_rule fields, because
         * the originals will all be freed when the old rule is freed. */
        for (i = 0; i < fcount; i++) {
                switch (new->fields[i].type) {
@@ -989,7 +992,7 @@ static void audit_update_watch(struct audit_parent *parent,
                        audit_set_auditable(current->audit_context);
 
                nwatch = audit_dupe_watch(owatch);
-               if (unlikely(IS_ERR(nwatch))) {
+               if (IS_ERR(nwatch)) {
                        mutex_unlock(&audit_filter_mutex);
                        audit_panic("error updating watch, skipping");
                        return;
@@ -1004,7 +1007,7 @@ static void audit_update_watch(struct audit_parent *parent,
                        list_del_rcu(&oentry->list);
 
                        nentry = audit_dupe_rule(&oentry->rule, nwatch);
-                       if (unlikely(IS_ERR(nentry)))
+                       if (IS_ERR(nentry))
                                audit_panic("error updating watch, removing");
                        else {
                                int h = audit_hash_ino((u32)ino);
@@ -1500,8 +1503,9 @@ static void audit_list_rules(int pid, int seq, struct sk_buff_head *q)
 }
 
 /* Log rule additions and removals */
-static void audit_log_rule_change(uid_t loginuid, u32 sid, char *action,
-                                 struct audit_krule *rule, int res)
+static void audit_log_rule_change(uid_t loginuid, u32 sessionid, u32 sid,
+                                 char *action, struct audit_krule *rule,
+                                 int res)
 {
        struct audit_buffer *ab;
 
@@ -1511,7 +1515,7 @@ static void audit_log_rule_change(uid_t loginuid, u32 sid, char *action,
        ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
        if (!ab)
                return;
-       audit_log_format(ab, "auid=%u", loginuid);
+       audit_log_format(ab, "auid=%u ses=%u", loginuid, sessionid);
        if (sid) {
                char *ctx = NULL;
                u32 len;
@@ -1540,10 +1544,11 @@ static void audit_log_rule_change(uid_t loginuid, u32 sid, char *action,
  * @data: payload data
  * @datasz: size of payload data
  * @loginuid: loginuid of sender
+ * @sessionid: sessionid for netlink audit message
  * @sid: SE Linux Security ID of sender
  */
 int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
-                        size_t datasz, uid_t loginuid, u32 sid)
+                        size_t datasz, uid_t loginuid, u32 sessionid, u32 sid)
 {
        struct task_struct *tsk;
        struct audit_netlink_list *dest;
@@ -1590,7 +1595,8 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
 
                err = audit_add_rule(entry,
                                     &audit_filter_list[entry->rule.listnr]);
-               audit_log_rule_change(loginuid, sid, "add", &entry->rule, !err);
+               audit_log_rule_change(loginuid, sessionid, sid, "add",
+                                     &entry->rule, !err);
 
                if (err)
                        audit_free_rule(entry);
@@ -1606,8 +1612,8 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
 
                err = audit_del_rule(entry,
                                     &audit_filter_list[entry->rule.listnr]);
-               audit_log_rule_change(loginuid, sid, "remove", &entry->rule,
-                                     !err);
+               audit_log_rule_change(loginuid, sessionid, sid, "remove",
+                                     &entry->rule, !err);
 
                audit_free_rule(entry);
                break;
@@ -1715,7 +1721,7 @@ static int audit_filter_user_rules(struct netlink_skb_parms *cb,
        return 1;
 }
 
-int audit_filter_user(struct netlink_skb_parms *cb, int type)
+int audit_filter_user(struct netlink_skb_parms *cb)
 {
        enum audit_state state = AUDIT_DISABLED;
        struct audit_entry *e;
@@ -1762,7 +1768,7 @@ unlock_and_return:
        return result;
 }
 
-/* This function will re-initialize the se_rule field of all applicable rules.
+/* This function will re-initialize the lsm_rule field of all applicable rules.
  * It will traverse the filter lists serarching for rules that contain LSM
  * specific filter fields.  When such a rule is found, it is copied, the
  * LSM field is re-initialized, and the old rule is replaced with the
@@ -1785,7 +1791,7 @@ int audit_update_lsm_rules(void)
                        watch = entry->rule.watch;
                        tree = entry->rule.tree;
                        nentry = audit_dupe_rule(&entry->rule, watch);
-                       if (unlikely(IS_ERR(nentry))) {
+                       if (IS_ERR(nentry)) {
                                /* save the first error encountered for the
                                 * return value */
                                if (!err)