]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - kernel/auditfilter.c
ipv4: Don't recompute net in ipmr_queue_xmit
[karo-tx-linux.git] / kernel / auditfilter.c
index b4d8c366ec3030f38b2be1bd9274bfdbfc76e12a..7714d93edb8505fc6bbd212ad3dbcec9d05b4cdb 100644 (file)
@@ -405,6 +405,12 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f)
                if (f->val > AUDIT_MAX_FIELD_COMPARE)
                        return -EINVAL;
                break;
+       case AUDIT_EXE:
+               if (f->op != Audit_equal)
+                       return -EINVAL;
+               if (entry->rule.listnr != AUDIT_FILTER_EXIT)
+                       return -EINVAL;
+               break;
        };
        return 0;
 }
@@ -419,6 +425,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
        size_t remain = datasz - sizeof(struct audit_rule_data);
        int i;
        char *str;
+       struct audit_fsnotify_mark *audit_mark;
 
        entry = audit_to_entry_common(data);
        if (IS_ERR(entry))
@@ -539,6 +546,24 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
                        entry->rule.buflen += f->val;
                        entry->rule.filterkey = str;
                        break;
+               case AUDIT_EXE:
+                       if (entry->rule.exe || f->val > PATH_MAX)
+                               goto exit_free;
+                       str = audit_unpack_string(&bufp, &remain, f->val);
+                       if (IS_ERR(str)) {
+                               err = PTR_ERR(str);
+                               goto exit_free;
+                       }
+                       entry->rule.buflen += f->val;
+
+                       audit_mark = audit_alloc_mark(&entry->rule, str, f->val);
+                       if (IS_ERR(audit_mark)) {
+                               kfree(str);
+                               err = PTR_ERR(audit_mark);
+                               goto exit_free;
+                       }
+                       entry->rule.exe = audit_mark;
+                       break;
                }
        }
 
@@ -551,6 +576,8 @@ exit_nofree:
 exit_free:
        if (entry->rule.tree)
                audit_put_tree(entry->rule.tree); /* that's the temporary one */
+       if (entry->rule.exe)
+               audit_remove_mark(entry->rule.exe); /* that's the template one */
        audit_free_rule(entry);
        return ERR_PTR(err);
 }
@@ -615,6 +642,10 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule)
                        data->buflen += data->values[i] =
                                audit_pack_string(&bufp, krule->filterkey);
                        break;
+               case AUDIT_EXE:
+                       data->buflen += data->values[i] =
+                               audit_pack_string(&bufp, audit_mark_path(krule->exe));
+                       break;
                case AUDIT_LOGINUID_SET:
                        if (krule->pflags & AUDIT_LOGINUID_LEGACY && !f->val) {
                                data->fields[i] = AUDIT_LOGINUID;
@@ -678,6 +709,12 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b)
                        if (strcmp(a->filterkey, b->filterkey))
                                return 1;
                        break;
+               case AUDIT_EXE:
+                       /* both paths exist based on above type compare */
+                       if (strcmp(audit_mark_path(a->exe),
+                                  audit_mark_path(b->exe)))
+                               return 1;
+                       break;
                case AUDIT_UID:
                case AUDIT_EUID:
                case AUDIT_SUID:
@@ -799,8 +836,14 @@ struct audit_entry *audit_dupe_rule(struct audit_krule *old)
                                err = -ENOMEM;
                        else
                                new->filterkey = fk;
+                       break;
+               case AUDIT_EXE:
+                       err = audit_dupe_exe(new, old);
+                       break;
                }
                if (err) {
+                       if (new->exe)
+                               audit_remove_mark(new->exe);
                        audit_free_rule(entry);
                        return ERR_PTR(err);
                }
@@ -963,6 +1006,9 @@ int audit_del_rule(struct audit_entry *entry)
        if (e->rule.tree)
                audit_remove_tree_rule(&e->rule);
 
+       if (e->rule.exe)
+               audit_remove_mark_rule(&e->rule);
+
 #ifdef CONFIG_AUDITSYSCALL
        if (!dont_count)
                audit_n_rules--;
@@ -1067,8 +1113,11 @@ int audit_rule_change(int type, __u32 portid, int seq, void *data,
                WARN_ON(1);
        }
 
-       if (err || type == AUDIT_DEL_RULE)
+       if (err || type == AUDIT_DEL_RULE) {
+               if (entry->rule.exe)
+                       audit_remove_mark(entry->rule.exe);
                audit_free_rule(entry);
+       }
 
        return err;
 }
@@ -1360,6 +1409,8 @@ static int update_lsm_rule(struct audit_krule *r)
                return 0;
 
        nentry = audit_dupe_rule(r);
+       if (entry->rule.exe)
+               audit_remove_mark(entry->rule.exe);
        if (IS_ERR(nentry)) {
                /* save the first error encountered for the
                 * return value */