Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 234239
b: refs/heads/master
c: 15a9155
h: refs/heads/master
i:
  234237: 96c8de5
  234235: 8c7a698
  234231: 73c3d65
  234223: bed15a0
  234207: 560a3a4
  234175: 5c7a9b2
  234111: eb2d3ab
  233983: 1594574
v: v3
  • Loading branch information
Al Viro committed Mar 14, 2011
1 parent f111dbc commit c36f953
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 54 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 586ce098a23b6ab7383df853a84ae3d48dc889aa
refs/heads/master: 15a9155fe3e8215c02b80df51ec2cac7c0d726ad
85 changes: 32 additions & 53 deletions trunk/kernel/audit_watch.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,9 @@ int audit_watch_compare(struct audit_watch *watch, unsigned long ino, dev_t dev)
}

/* Initialize a parent watch entry. */
static struct audit_parent *audit_init_parent(struct nameidata *ndp)
static struct audit_parent *audit_init_parent(struct path *path)
{
struct inode *inode = ndp->path.dentry->d_inode;
struct inode *inode = path->dentry->d_inode;
struct audit_parent *parent;
int ret;

Expand Down Expand Up @@ -353,53 +353,40 @@ static void audit_remove_parent_watches(struct audit_parent *parent)
}

/* Get path information necessary for adding watches. */
static int audit_get_nd(char *path, struct nameidata **ndp, struct nameidata **ndw)
static int audit_get_nd(struct audit_watch *watch, struct path *parent)
{
struct nameidata *ndparent, *ndwatch;
struct nameidata nd;
struct dentry *d;
int err;

ndparent = kmalloc(sizeof(*ndparent), GFP_KERNEL);
if (unlikely(!ndparent))
return -ENOMEM;
err = path_lookup(watch->path, LOOKUP_PARENT, &nd);
if (err)
return err;

ndwatch = kmalloc(sizeof(*ndwatch), GFP_KERNEL);
if (unlikely(!ndwatch)) {
kfree(ndparent);
return -ENOMEM;
if (nd.last_type != LAST_NORM) {
path_put(&nd.path);
return -EINVAL;
}

err = path_lookup(path, LOOKUP_PARENT, ndparent);
if (err) {
kfree(ndparent);
kfree(ndwatch);
return err;
mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
d = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len);
if (IS_ERR(d)) {
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
path_put(&nd.path);
return PTR_ERR(d);
}

err = path_lookup(path, 0, ndwatch);
if (err) {
kfree(ndwatch);
ndwatch = NULL;
if (d->d_inode) {
/* update watch filter fields */
watch->dev = d->d_inode->i_sb->s_dev;
watch->ino = d->d_inode->i_ino;
}
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);

*ndp = ndparent;
*ndw = ndwatch;

*parent = nd.path;
dput(d);
return 0;
}

/* Release resources used for watch path information. */
static void audit_put_nd(struct nameidata *ndp, struct nameidata *ndw)
{
if (ndp) {
path_put(&ndp->path);
kfree(ndp);
}
if (ndw) {
path_put(&ndw->path);
kfree(ndw);
}
}

/* Associate the given rule with an existing parent.
* Caller must hold audit_filter_mutex. */
static void audit_add_to_parent(struct audit_krule *krule,
Expand Down Expand Up @@ -440,31 +427,24 @@ int audit_add_watch(struct audit_krule *krule, struct list_head **list)
{
struct audit_watch *watch = krule->watch;
struct audit_parent *parent;
struct nameidata *ndp = NULL, *ndw = NULL;
struct path parent_path;
int h, 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;
}
ret = audit_get_nd(watch, &parent_path);

/* caller expects mutex locked */
mutex_lock(&audit_filter_mutex);

/* update watch filter fields */
if (ndw) {
watch->dev = ndw->path.dentry->d_inode->i_sb->s_dev;
watch->ino = ndw->path.dentry->d_inode->i_ino;
}
if (ret)
return ret;

/* either find an old parent or attach a new one */
parent = audit_find_parent(ndp->path.dentry->d_inode);
parent = audit_find_parent(parent_path.dentry->d_inode);
if (!parent) {
parent = audit_init_parent(ndp);
parent = audit_init_parent(&parent_path);
if (IS_ERR(parent)) {
ret = PTR_ERR(parent);
goto error;
Expand All @@ -479,9 +459,8 @@ int audit_add_watch(struct audit_krule *krule, struct list_head **list)
h = audit_hash_ino((u32)watch->ino);
*list = &audit_inode_hash[h];
error:
audit_put_nd(ndp, ndw); /* NULL args OK */
path_put(&parent_path);
return ret;

}

void audit_remove_watch_rule(struct audit_krule *krule)
Expand Down

0 comments on commit c36f953

Please sign in to comment.