Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (52 commits)
  init: Open /dev/console from rootfs
  mqueue: fix typo "failues" -> "failures"
  mqueue: only set error codes if they are really necessary
  mqueue: simplify do_open() error handling
  mqueue: apply mathematics distributivity on mq_bytes calculation
  mqueue: remove unneeded info->messages initialization
  mqueue: fix mq_open() file descriptor leak on user-space processes
  fix race in d_splice_alias()
  set S_DEAD on unlink() and non-directory rename() victims
  vfs: add NOFOLLOW flag to umount(2)
  get rid of ->mnt_parent in tomoyo/realpath
  hppfs can use existing proc_mnt, no need for do_kern_mount() in there
  Mirror MS_KERNMOUNT in ->mnt_flags
  get rid of useless vfsmount_lock use in put_mnt_ns()
  Take vfsmount_lock to fs/internal.h
  get rid of insanity with namespace roots in tomoyo
  take check for new events in namespace (guts of mounts_poll()) to namespace.c
  Don't mess with generic_permission() under ->d_lock in hpfs
  sanitize const/signedness for udf
  nilfs: sanitize const/signedness in dealing with ->d_name.name
  ...

Fix up fairly trivial (famous last words...) conflicts in
drivers/infiniband/core/uverbs_main.c and security/tomoyo/realpath.c
This commit is contained in:
Linus Torvalds
2010-03-04 08:15:33 -08:00
73 changed files with 794 additions and 1101 deletions

View File

@@ -548,6 +548,11 @@ int audit_remove_tree_rule(struct audit_krule *rule)
return 0;
}
static int compare_root(struct vfsmount *mnt, void *arg)
{
return mnt->mnt_root->d_inode == arg;
}
void audit_trim_trees(void)
{
struct list_head cursor;
@@ -559,7 +564,6 @@ void audit_trim_trees(void)
struct path path;
struct vfsmount *root_mnt;
struct node *node;
struct list_head list;
int err;
tree = container_of(cursor.next, struct audit_tree, list);
@@ -577,24 +581,16 @@ void audit_trim_trees(void)
if (!root_mnt)
goto skip_it;
list_add_tail(&list, &root_mnt->mnt_list);
spin_lock(&hash_lock);
list_for_each_entry(node, &tree->chunks, list) {
struct audit_chunk *chunk = find_chunk(node);
struct inode *inode = chunk->watch.inode;
struct vfsmount *mnt;
struct inode *inode = find_chunk(node)->watch.inode;
node->index |= 1U<<31;
list_for_each_entry(mnt, &list, mnt_list) {
if (mnt->mnt_root->d_inode == inode) {
node->index &= ~(1U<<31);
break;
}
}
if (iterate_mounts(compare_root, inode, root_mnt))
node->index &= ~(1U<<31);
}
spin_unlock(&hash_lock);
trim_marked(tree);
put_tree(tree);
list_del_init(&list);
drop_collected_mounts(root_mnt);
skip_it:
mutex_lock(&audit_filter_mutex);
@@ -603,22 +599,6 @@ skip_it:
mutex_unlock(&audit_filter_mutex);
}
static int is_under(struct vfsmount *mnt, struct dentry *dentry,
struct path *path)
{
if (mnt != path->mnt) {
for (;;) {
if (mnt->mnt_parent == mnt)
return 0;
if (mnt->mnt_parent == path->mnt)
break;
mnt = mnt->mnt_parent;
}
dentry = mnt->mnt_mountpoint;
}
return is_subdir(dentry, path->dentry);
}
int audit_make_tree(struct audit_krule *rule, char *pathname, u32 op)
{
@@ -638,13 +618,17 @@ void audit_put_tree(struct audit_tree *tree)
put_tree(tree);
}
static int tag_mount(struct vfsmount *mnt, void *arg)
{
return tag_chunk(mnt->mnt_root->d_inode, arg);
}
/* called with audit_filter_mutex */
int audit_add_tree_rule(struct audit_krule *rule)
{
struct audit_tree *seed = rule->tree, *tree;
struct path path;
struct vfsmount *mnt, *p;
struct list_head list;
struct vfsmount *mnt;
int err;
list_for_each_entry(tree, &tree_list, list) {
@@ -670,16 +654,9 @@ int audit_add_tree_rule(struct audit_krule *rule)
err = -ENOMEM;
goto Err;
}
list_add_tail(&list, &mnt->mnt_list);
get_tree(tree);
list_for_each_entry(p, &list, mnt_list) {
err = tag_chunk(p->mnt_root->d_inode, tree);
if (err)
break;
}
list_del(&list);
err = iterate_mounts(tag_mount, tree, mnt);
drop_collected_mounts(mnt);
if (!err) {
@@ -714,31 +691,23 @@ int audit_tag_tree(char *old, char *new)
{
struct list_head cursor, barrier;
int failed = 0;
struct path path;
struct path path1, path2;
struct vfsmount *tagged;
struct list_head list;
struct vfsmount *mnt;
struct dentry *dentry;
int err;
err = kern_path(new, 0, &path);
err = kern_path(new, 0, &path2);
if (err)
return err;
tagged = collect_mounts(&path);
path_put(&path);
tagged = collect_mounts(&path2);
path_put(&path2);
if (!tagged)
return -ENOMEM;
err = kern_path(old, 0, &path);
err = kern_path(old, 0, &path1);
if (err) {
drop_collected_mounts(tagged);
return err;
}
mnt = mntget(path.mnt);
dentry = dget(path.dentry);
path_put(&path);
list_add_tail(&list, &tagged->mnt_list);
mutex_lock(&audit_filter_mutex);
list_add(&barrier, &tree_list);
@@ -746,7 +715,7 @@ int audit_tag_tree(char *old, char *new)
while (cursor.next != &tree_list) {
struct audit_tree *tree;
struct vfsmount *p;
int good_one = 0;
tree = container_of(cursor.next, struct audit_tree, list);
get_tree(tree);
@@ -754,30 +723,19 @@ int audit_tag_tree(char *old, char *new)
list_add(&cursor, &tree->list);
mutex_unlock(&audit_filter_mutex);
err = kern_path(tree->pathname, 0, &path);
if (err) {
err = kern_path(tree->pathname, 0, &path2);
if (!err) {
good_one = path_is_under(&path1, &path2);
path_put(&path2);
}
if (!good_one) {
put_tree(tree);
mutex_lock(&audit_filter_mutex);
continue;
}
spin_lock(&vfsmount_lock);
if (!is_under(mnt, dentry, &path)) {
spin_unlock(&vfsmount_lock);
path_put(&path);
put_tree(tree);
mutex_lock(&audit_filter_mutex);
continue;
}
spin_unlock(&vfsmount_lock);
path_put(&path);
list_for_each_entry(p, &list, mnt_list) {
failed = tag_chunk(p->mnt_root->d_inode, tree);
if (failed)
break;
}
failed = iterate_mounts(tag_mount, tree, tagged);
if (failed) {
put_tree(tree);
mutex_lock(&audit_filter_mutex);
@@ -818,10 +776,8 @@ int audit_tag_tree(char *old, char *new)
}
list_del(&barrier);
list_del(&cursor);
list_del(&list);
mutex_unlock(&audit_filter_mutex);
dput(dentry);
mntput(mnt);
path_put(&path1);
drop_collected_mounts(tagged);
return failed;
}

View File

@@ -1988,7 +1988,6 @@ void __audit_inode(const char *name, const struct dentry *dentry)
/**
* audit_inode_child - collect inode info for created/removed objects
* @dname: inode's dentry name
* @dentry: dentry being audited
* @parent: inode of dentry parent
*
@@ -2000,13 +1999,14 @@ void __audit_inode(const char *name, const struct dentry *dentry)
* must be hooked prior, in order to capture the target inode during
* unsuccessful attempts.
*/
void __audit_inode_child(const char *dname, const struct dentry *dentry,
void __audit_inode_child(const struct dentry *dentry,
const struct inode *parent)
{
int idx;
struct audit_context *context = current->audit_context;
const char *found_parent = NULL, *found_child = NULL;
const struct inode *inode = dentry->d_inode;
const char *dname = dentry->d_name.name;
int dirlen = 0;
if (!context->in_syscall)
@@ -2014,9 +2014,6 @@ void __audit_inode_child(const char *dname, const struct dentry *dentry,
if (inode)
handle_one(inode);
/* determine matching parent */
if (!dname)
goto add_names;
/* parent is more likely, look for it first */
for (idx = 0; idx < context->name_count; idx++) {

View File

@@ -1331,7 +1331,7 @@ static ssize_t binary_sysctl(const int *name, int nlen,
ssize_t result;
char *pathname;
int flags;
int acc_mode, fmode;
int acc_mode;
pathname = sysctl_getname(name, nlen, &table);
result = PTR_ERR(pathname);
@@ -1342,15 +1342,12 @@ static ssize_t binary_sysctl(const int *name, int nlen,
if (oldval && oldlen && newval && newlen) {
flags = O_RDWR;
acc_mode = MAY_READ | MAY_WRITE;
fmode = FMODE_READ | FMODE_WRITE;
} else if (newval && newlen) {
flags = O_WRONLY;
acc_mode = MAY_WRITE;
fmode = FMODE_WRITE;
} else if (oldval && oldlen) {
flags = O_RDONLY;
acc_mode = MAY_READ;
fmode = FMODE_READ;
} else {
result = 0;
goto out_putname;
@@ -1361,7 +1358,7 @@ static ssize_t binary_sysctl(const int *name, int nlen,
if (result)
goto out_putname;
result = may_open(&nd.path, acc_mode, fmode);
result = may_open(&nd.path, acc_mode, flags);
if (result)
goto out_putpath;