Audit: clean up all op= output to include string quoting
[linux-2.6.git] / kernel / audit_watch.c
index da8be6d..0e96dbc 100644 (file)
@@ -234,11 +234,7 @@ static void audit_watch_log_rule_change(struct audit_krule *r, struct audit_watc
                audit_log_string(ab, op);
                audit_log_format(ab, " path=");
                audit_log_untrustedstring(ab, w->path);
-               if (r->filterkey) {
-                       audit_log_format(ab, " key=");
-                       audit_log_untrustedstring(ab, r->filterkey);
-               } else
-                       audit_log_format(ab, " key=(null)");
+               audit_log_key(ab, r->filterkey);
                audit_log_format(ab, " list=%d res=1", r->listnr);
                audit_log_end(ab);
        }
@@ -345,7 +341,7 @@ void audit_inotify_unregister(struct list_head *in_list)
 }
 
 /* Get path information necessary for adding watches. */
-int audit_get_nd(char *path, struct nameidata **ndp, struct nameidata **ndw)
+static int audit_get_nd(char *path, struct nameidata **ndp, struct nameidata **ndw)
 {
        struct nameidata *ndparent, *ndwatch;
        int err;
@@ -380,7 +376,7 @@ int audit_get_nd(char *path, struct nameidata **ndp, struct nameidata **ndw)
 }
 
 /* Release resources used for watch path information. */
-void audit_put_nd(struct nameidata *ndp, struct nameidata *ndw)
+static void audit_put_nd(struct nameidata *ndp, struct nameidata *ndw)
 {
        if (ndp) {
                path_put(&ndp->path);
@@ -426,14 +422,24 @@ static void audit_add_to_parent(struct audit_krule *krule,
 
 /* Find a matching watch entry, or add this one.
  * Caller must hold audit_filter_mutex. */
-int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp,
-                   struct nameidata *ndw)
+int audit_add_watch(struct audit_krule *krule)
 {
        struct audit_watch *watch = krule->watch;
        struct inotify_watch *i_watch;
        struct audit_parent *parent;
+       struct nameidata *ndp = NULL, *ndw = NULL;
        int ret = 0;
 
+       mutex_unlock(&audit_filter_mutex);
+
+       /* Avoid calling path_lookup under audit_filter_mutex. */
+       ret = audit_get_nd(watch->path, &ndp, &ndw);
+       if (ret) {
+               /* caller expects mutex locked */
+               mutex_lock(&audit_filter_mutex);
+               goto error;
+       }
+
        /* update watch filter fields */
        if (ndw) {
                watch->dev = ndw->path.dentry->d_inode->i_sb->s_dev;
@@ -445,15 +451,14 @@ int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp,
         * inotify watch is found, inotify_find_watch() grabs a reference before
         * returning.
         */
-       mutex_unlock(&audit_filter_mutex);
-
        if (inotify_find_watch(audit_ih, ndp->path.dentry->d_inode,
                               &i_watch) < 0) {
                parent = audit_init_parent(ndp);
                if (IS_ERR(parent)) {
                        /* caller expects mutex locked */
                        mutex_lock(&audit_filter_mutex);
-                       return PTR_ERR(parent);
+                       ret = PTR_ERR(parent);
+                       goto error;
                }
        } else
                parent = container_of(i_watch, struct audit_parent, wdata);
@@ -468,7 +473,11 @@ int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp,
 
        /* match get in audit_init_parent or inotify_find_watch */
        put_inotify_watch(&parent->wdata);
+
+error:
+       audit_put_nd(ndp, ndw);         /* NULL args OK */
        return ret;
+
 }
 
 void audit_remove_watch_rule(struct audit_krule *krule, struct list_head *list)