git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge branch 'for-linus2' of git://git.kernel.dk/linux-2.6-block
[safe/jmp/linux-2.6]
/
kernel
/
audit_watch.c
diff --git
a/kernel/audit_watch.c
b/kernel/audit_watch.c
index
da8be6d
..
8df4369
100644
(file)
--- a/
kernel/audit_watch.c
+++ b/
kernel/audit_watch.c
@@
-27,6
+27,7
@@
#include <linux/namei.h>
#include <linux/netlink.h>
#include <linux/sched.h>
#include <linux/namei.h>
#include <linux/netlink.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/inotify.h>
#include <linux/security.h>
#include "audit.h"
#include <linux/inotify.h>
#include <linux/security.h>
#include "audit.h"
@@
-45,8
+46,8
@@
struct audit_watch {
atomic_t count; /* reference count */
struct audit_watch {
atomic_t count; /* reference count */
- char *path; /* insertion path */
dev_t dev; /* associated superblock device */
dev_t dev; /* associated superblock device */
+ char *path; /* insertion path */
unsigned long ino; /* associated inode number */
struct audit_parent *parent; /* associated parent */
struct list_head wlist; /* entry in parent->watches list */
unsigned long ino; /* associated inode number */
struct audit_parent *parent; /* associated parent */
struct list_head wlist; /* entry in parent->watches list */
@@
-234,11
+235,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);
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);
}
audit_log_format(ab, " list=%d res=1", r->listnr);
audit_log_end(ab);
}
@@
-345,7
+342,7
@@
void audit_inotify_unregister(struct list_head *in_list)
}
/* Get path information necessary for adding watches. */
}
/* 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;
{
struct nameidata *ndparent, *ndwatch;
int err;
@@
-380,7
+377,7
@@
int audit_get_nd(char *path, struct nameidata **ndp, struct nameidata **ndw)
}
/* Release resources used for watch path information. */
}
/* 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);
{
if (ndp) {
path_put(&ndp->path);
@@
-426,14
+423,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. */
/* 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 audit_watch *watch = krule->watch;
struct inotify_watch *i_watch;
struct audit_parent *parent;
+ struct nameidata *ndp = NULL, *ndw = NULL;
int ret = 0;
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;
/* update watch filter fields */
if (ndw) {
watch->dev = ndw->path.dentry->d_inode->i_sb->s_dev;
@@
-445,15
+452,14
@@
int audit_add_watch(struct audit_krule *krule, struct nameidata *ndp,
* inotify watch is found, inotify_find_watch() grabs a reference before
* returning.
*/
* 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);
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);
}
} else
parent = container_of(i_watch, struct audit_parent, wdata);
@@
-468,7
+474,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);
/* 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;
return ret;
+
}
void audit_remove_watch_rule(struct audit_krule *krule, struct list_head *list)
}
void audit_remove_watch_rule(struct audit_krule *krule, struct list_head *list)