diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-21 11:54:32 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-21 11:54:32 -0400 |
commit | 2fb59d623ad85dfdb8ce03a660051743f7361896 (patch) | |
tree | 3991ab2b88cc369444c136089d9c1570c26c6072 /fs | |
parent | efdc31319d43050a5742fb690b1a4beb68092a94 (diff) | |
parent | 74c3cbe33bc077ac1159cadfea608b501e100344 (diff) |
Merge branch 'audit.b43' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current
* 'audit.b43' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current:
[PATCH] audit: watching subtrees
[PATCH] new helper - inotify_evict_watch()
[PATCH] new helper - inotify_clone_watch()
[PATCH] new helpers - collect_mounts() and release_collected_mounts()
[PATCH] pass dentry to audit_inode()/audit_inode_child()
Diffstat (limited to 'fs')
-rw-r--r-- | fs/dcache.c | 2 | ||||
-rw-r--r-- | fs/debugfs/inode.c | 2 | ||||
-rw-r--r-- | fs/inotify.c | 43 | ||||
-rw-r--r-- | fs/namei.c | 10 | ||||
-rw-r--r-- | fs/namespace.c | 22 | ||||
-rw-r--r-- | fs/open.c | 4 | ||||
-rw-r--r-- | fs/pnode.h | 1 | ||||
-rw-r--r-- | fs/xattr.c | 8 |
8 files changed, 78 insertions, 14 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 5489b2d98a00..2bb3f7ac683b 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -38,7 +38,7 @@ int sysctl_vfs_cache_pressure __read_mostly = 100; | |||
38 | EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure); | 38 | EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure); |
39 | 39 | ||
40 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock); | 40 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock); |
41 | static __cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock); | 41 | __cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock); |
42 | 42 | ||
43 | EXPORT_SYMBOL(dcache_lock); | 43 | EXPORT_SYMBOL(dcache_lock); |
44 | 44 | ||
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 11be8a325e26..6a713b33992f 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
@@ -413,7 +413,7 @@ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry, | |||
413 | d_move(old_dentry, dentry); | 413 | d_move(old_dentry, dentry); |
414 | fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name, | 414 | fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name, |
415 | old_dentry->d_name.name, S_ISDIR(old_dentry->d_inode->i_mode), | 415 | old_dentry->d_name.name, S_ISDIR(old_dentry->d_inode->i_mode), |
416 | NULL, old_dentry->d_inode); | 416 | NULL, old_dentry); |
417 | fsnotify_oldname_free(old_name); | 417 | fsnotify_oldname_free(old_name); |
418 | unlock_rename(new_dir, old_dir); | 418 | unlock_rename(new_dir, old_dir); |
419 | dput(dentry); | 419 | dput(dentry); |
diff --git a/fs/inotify.c b/fs/inotify.c index 7457501b9565..2c5b92152876 100644 --- a/fs/inotify.c +++ b/fs/inotify.c | |||
@@ -667,6 +667,49 @@ out: | |||
667 | EXPORT_SYMBOL_GPL(inotify_add_watch); | 667 | EXPORT_SYMBOL_GPL(inotify_add_watch); |
668 | 668 | ||
669 | /** | 669 | /** |
670 | * inotify_clone_watch - put the watch next to existing one | ||
671 | * @old: already installed watch | ||
672 | * @new: new watch | ||
673 | * | ||
674 | * Caller must hold the inotify_mutex of inode we are dealing with; | ||
675 | * it is expected to remove the old watch before unlocking the inode. | ||
676 | */ | ||
677 | s32 inotify_clone_watch(struct inotify_watch *old, struct inotify_watch *new) | ||
678 | { | ||
679 | struct inotify_handle *ih = old->ih; | ||
680 | int ret = 0; | ||
681 | |||
682 | new->mask = old->mask; | ||
683 | new->ih = ih; | ||
684 | |||
685 | mutex_lock(&ih->mutex); | ||
686 | |||
687 | /* Initialize a new watch */ | ||
688 | ret = inotify_handle_get_wd(ih, new); | ||
689 | if (unlikely(ret)) | ||
690 | goto out; | ||
691 | ret = new->wd; | ||
692 | |||
693 | get_inotify_handle(ih); | ||
694 | |||
695 | new->inode = igrab(old->inode); | ||
696 | |||
697 | list_add(&new->h_list, &ih->watches); | ||
698 | list_add(&new->i_list, &old->inode->inotify_watches); | ||
699 | out: | ||
700 | mutex_unlock(&ih->mutex); | ||
701 | return ret; | ||
702 | } | ||
703 | |||
704 | void inotify_evict_watch(struct inotify_watch *watch) | ||
705 | { | ||
706 | get_inotify_watch(watch); | ||
707 | mutex_lock(&watch->ih->mutex); | ||
708 | inotify_remove_watch_locked(watch->ih, watch); | ||
709 | mutex_unlock(&watch->ih->mutex); | ||
710 | } | ||
711 | |||
712 | /** | ||
670 | * inotify_rm_wd - remove a watch from an inotify instance | 713 | * inotify_rm_wd - remove a watch from an inotify instance |
671 | * @ih: inotify handle | 714 | * @ih: inotify handle |
672 | * @wd: watch descriptor to remove | 715 | * @wd: watch descriptor to remove |
diff --git a/fs/namei.c b/fs/namei.c index 1e5c71669164..3b993db26cee 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1174,7 +1174,7 @@ static int fastcall do_path_lookup(int dfd, const char *name, | |||
1174 | out: | 1174 | out: |
1175 | if (unlikely(!retval && !audit_dummy_context() && nd->dentry && | 1175 | if (unlikely(!retval && !audit_dummy_context() && nd->dentry && |
1176 | nd->dentry->d_inode)) | 1176 | nd->dentry->d_inode)) |
1177 | audit_inode(name, nd->dentry->d_inode); | 1177 | audit_inode(name, nd->dentry); |
1178 | out_fail: | 1178 | out_fail: |
1179 | return retval; | 1179 | return retval; |
1180 | 1180 | ||
@@ -1214,7 +1214,7 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt, | |||
1214 | retval = path_walk(name, nd); | 1214 | retval = path_walk(name, nd); |
1215 | if (unlikely(!retval && !audit_dummy_context() && nd->dentry && | 1215 | if (unlikely(!retval && !audit_dummy_context() && nd->dentry && |
1216 | nd->dentry->d_inode)) | 1216 | nd->dentry->d_inode)) |
1217 | audit_inode(name, nd->dentry->d_inode); | 1217 | audit_inode(name, nd->dentry); |
1218 | 1218 | ||
1219 | return retval; | 1219 | return retval; |
1220 | 1220 | ||
@@ -1469,7 +1469,7 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir) | |||
1469 | return -ENOENT; | 1469 | return -ENOENT; |
1470 | 1470 | ||
1471 | BUG_ON(victim->d_parent->d_inode != dir); | 1471 | BUG_ON(victim->d_parent->d_inode != dir); |
1472 | audit_inode_child(victim->d_name.name, victim->d_inode, dir); | 1472 | audit_inode_child(victim->d_name.name, victim, dir); |
1473 | 1473 | ||
1474 | error = permission(dir,MAY_WRITE | MAY_EXEC, NULL); | 1474 | error = permission(dir,MAY_WRITE | MAY_EXEC, NULL); |
1475 | if (error) | 1475 | if (error) |
@@ -1783,7 +1783,7 @@ do_last: | |||
1783 | * It already exists. | 1783 | * It already exists. |
1784 | */ | 1784 | */ |
1785 | mutex_unlock(&dir->d_inode->i_mutex); | 1785 | mutex_unlock(&dir->d_inode->i_mutex); |
1786 | audit_inode(pathname, path.dentry->d_inode); | 1786 | audit_inode(pathname, path.dentry); |
1787 | 1787 | ||
1788 | error = -EEXIST; | 1788 | error = -EEXIST; |
1789 | if (flag & O_EXCL) | 1789 | if (flag & O_EXCL) |
@@ -2562,7 +2562,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
2562 | if (!error) { | 2562 | if (!error) { |
2563 | const char *new_name = old_dentry->d_name.name; | 2563 | const char *new_name = old_dentry->d_name.name; |
2564 | fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir, | 2564 | fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir, |
2565 | new_dentry->d_inode, old_dentry->d_inode); | 2565 | new_dentry->d_inode, old_dentry); |
2566 | } | 2566 | } |
2567 | fsnotify_oldname_free(old_name); | 2567 | fsnotify_oldname_free(old_name); |
2568 | 2568 | ||
diff --git a/fs/namespace.c b/fs/namespace.c index 860752998fb3..06083885b21e 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -246,7 +246,7 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root, | |||
246 | list_add(&mnt->mnt_slave, &old->mnt_slave_list); | 246 | list_add(&mnt->mnt_slave, &old->mnt_slave_list); |
247 | mnt->mnt_master = old; | 247 | mnt->mnt_master = old; |
248 | CLEAR_MNT_SHARED(mnt); | 248 | CLEAR_MNT_SHARED(mnt); |
249 | } else { | 249 | } else if (!(flag & CL_PRIVATE)) { |
250 | if ((flag & CL_PROPAGATION) || IS_MNT_SHARED(old)) | 250 | if ((flag & CL_PROPAGATION) || IS_MNT_SHARED(old)) |
251 | list_add(&mnt->mnt_share, &old->mnt_share); | 251 | list_add(&mnt->mnt_share, &old->mnt_share); |
252 | if (IS_MNT_SLAVE(old)) | 252 | if (IS_MNT_SLAVE(old)) |
@@ -746,6 +746,26 @@ Enomem: | |||
746 | return NULL; | 746 | return NULL; |
747 | } | 747 | } |
748 | 748 | ||
749 | struct vfsmount *collect_mounts(struct vfsmount *mnt, struct dentry *dentry) | ||
750 | { | ||
751 | struct vfsmount *tree; | ||
752 | down_read(&namespace_sem); | ||
753 | tree = copy_tree(mnt, dentry, CL_COPY_ALL | CL_PRIVATE); | ||
754 | up_read(&namespace_sem); | ||
755 | return tree; | ||
756 | } | ||
757 | |||
758 | void drop_collected_mounts(struct vfsmount *mnt) | ||
759 | { | ||
760 | LIST_HEAD(umount_list); | ||
761 | down_read(&namespace_sem); | ||
762 | spin_lock(&vfsmount_lock); | ||
763 | umount_tree(mnt, 0, &umount_list); | ||
764 | spin_unlock(&vfsmount_lock); | ||
765 | up_read(&namespace_sem); | ||
766 | release_mounts(&umount_list); | ||
767 | } | ||
768 | |||
749 | /* | 769 | /* |
750 | * @source_mnt : mount tree to be attached | 770 | * @source_mnt : mount tree to be attached |
751 | * @nd : place the mount tree @source_mnt is attached | 771 | * @nd : place the mount tree @source_mnt is attached |
@@ -569,7 +569,7 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) | |||
569 | dentry = file->f_path.dentry; | 569 | dentry = file->f_path.dentry; |
570 | inode = dentry->d_inode; | 570 | inode = dentry->d_inode; |
571 | 571 | ||
572 | audit_inode(NULL, inode); | 572 | audit_inode(NULL, dentry); |
573 | 573 | ||
574 | err = -EROFS; | 574 | err = -EROFS; |
575 | if (IS_RDONLY(inode)) | 575 | if (IS_RDONLY(inode)) |
@@ -727,7 +727,7 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group) | |||
727 | goto out; | 727 | goto out; |
728 | 728 | ||
729 | dentry = file->f_path.dentry; | 729 | dentry = file->f_path.dentry; |
730 | audit_inode(NULL, dentry->d_inode); | 730 | audit_inode(NULL, dentry); |
731 | error = chown_common(dentry, user, group); | 731 | error = chown_common(dentry, user, group); |
732 | fput(file); | 732 | fput(file); |
733 | out: | 733 | out: |
diff --git a/fs/pnode.h b/fs/pnode.h index d45bd8ec36bf..f249be2fee7a 100644 --- a/fs/pnode.h +++ b/fs/pnode.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #define CL_COPY_ALL 0x04 | 22 | #define CL_COPY_ALL 0x04 |
23 | #define CL_MAKE_SHARED 0x08 | 23 | #define CL_MAKE_SHARED 0x08 |
24 | #define CL_PROPAGATION 0x10 | 24 | #define CL_PROPAGATION 0x10 |
25 | #define CL_PRIVATE 0x20 | ||
25 | 26 | ||
26 | static inline void set_mnt_shared(struct vfsmount *mnt) | 27 | static inline void set_mnt_shared(struct vfsmount *mnt) |
27 | { | 28 | { |
diff --git a/fs/xattr.c b/fs/xattr.c index a44fd92caca3..6645b7313b33 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -267,7 +267,7 @@ sys_fsetxattr(int fd, char __user *name, void __user *value, | |||
267 | if (!f) | 267 | if (!f) |
268 | return error; | 268 | return error; |
269 | dentry = f->f_path.dentry; | 269 | dentry = f->f_path.dentry; |
270 | audit_inode(NULL, dentry->d_inode); | 270 | audit_inode(NULL, dentry); |
271 | error = setxattr(dentry, name, value, size, flags); | 271 | error = setxattr(dentry, name, value, size, flags); |
272 | fput(f); | 272 | fput(f); |
273 | return error; | 273 | return error; |
@@ -349,7 +349,7 @@ sys_fgetxattr(int fd, char __user *name, void __user *value, size_t size) | |||
349 | f = fget(fd); | 349 | f = fget(fd); |
350 | if (!f) | 350 | if (!f) |
351 | return error; | 351 | return error; |
352 | audit_inode(NULL, f->f_path.dentry->d_inode); | 352 | audit_inode(NULL, f->f_path.dentry); |
353 | error = getxattr(f->f_path.dentry, name, value, size); | 353 | error = getxattr(f->f_path.dentry, name, value, size); |
354 | fput(f); | 354 | fput(f); |
355 | return error; | 355 | return error; |
@@ -422,7 +422,7 @@ sys_flistxattr(int fd, char __user *list, size_t size) | |||
422 | f = fget(fd); | 422 | f = fget(fd); |
423 | if (!f) | 423 | if (!f) |
424 | return error; | 424 | return error; |
425 | audit_inode(NULL, f->f_path.dentry->d_inode); | 425 | audit_inode(NULL, f->f_path.dentry); |
426 | error = listxattr(f->f_path.dentry, list, size); | 426 | error = listxattr(f->f_path.dentry, list, size); |
427 | fput(f); | 427 | fput(f); |
428 | return error; | 428 | return error; |
@@ -485,7 +485,7 @@ sys_fremovexattr(int fd, char __user *name) | |||
485 | if (!f) | 485 | if (!f) |
486 | return error; | 486 | return error; |
487 | dentry = f->f_path.dentry; | 487 | dentry = f->f_path.dentry; |
488 | audit_inode(NULL, dentry->d_inode); | 488 | audit_inode(NULL, dentry); |
489 | error = removexattr(dentry, name); | 489 | error = removexattr(dentry, name); |
490 | fput(f); | 490 | fput(f); |
491 | return error; | 491 | return error; |