Skip to content

Commit 2fb59d6

Browse files
author
Linus Torvalds
committed
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()
2 parents efdc313 + 74c3cbe commit 2fb59d6

File tree

21 files changed

+1411
-40
lines changed

21 files changed

+1411
-40
lines changed

fs/dcache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ int sysctl_vfs_cache_pressure __read_mostly = 100;
3838
EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure);
3939

4040
__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);
4242

4343
EXPORT_SYMBOL(dcache_lock);
4444

fs/debugfs/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
413413
d_move(old_dentry, dentry);
414414
fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name,
415415
old_dentry->d_name.name, S_ISDIR(old_dentry->d_inode->i_mode),
416-
NULL, old_dentry->d_inode);
416+
NULL, old_dentry);
417417
fsnotify_oldname_free(old_name);
418418
unlock_rename(new_dir, old_dir);
419419
dput(dentry);

fs/inotify.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,49 @@ s32 inotify_add_watch(struct inotify_handle *ih, struct inotify_watch *watch,
666666
}
667667
EXPORT_SYMBOL_GPL(inotify_add_watch);
668668

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+
669712
/**
670713
* inotify_rm_wd - remove a watch from an inotify instance
671714
* @ih: inotify handle

fs/namei.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,7 +1174,7 @@ static int fastcall do_path_lookup(int dfd, const char *name,
11741174
out:
11751175
if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
11761176
nd->dentry->d_inode))
1177-
audit_inode(name, nd->dentry->d_inode);
1177+
audit_inode(name, nd->dentry);
11781178
out_fail:
11791179
return retval;
11801180

@@ -1214,7 +1214,7 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
12141214
retval = path_walk(name, nd);
12151215
if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
12161216
nd->dentry->d_inode))
1217-
audit_inode(name, nd->dentry->d_inode);
1217+
audit_inode(name, nd->dentry);
12181218

12191219
return retval;
12201220

@@ -1469,7 +1469,7 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
14691469
return -ENOENT;
14701470

14711471
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);
14731473

14741474
error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
14751475
if (error)
@@ -1783,7 +1783,7 @@ int open_namei(int dfd, const char *pathname, int flag,
17831783
* It already exists.
17841784
*/
17851785
mutex_unlock(&dir->d_inode->i_mutex);
1786-
audit_inode(pathname, path.dentry->d_inode);
1786+
audit_inode(pathname, path.dentry);
17871787

17881788
error = -EEXIST;
17891789
if (flag & O_EXCL)
@@ -2562,7 +2562,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
25622562
if (!error) {
25632563
const char *new_name = old_dentry->d_name.name;
25642564
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);
25662566
}
25672567
fsnotify_oldname_free(old_name);
25682568

fs/namespace.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
246246
list_add(&mnt->mnt_slave, &old->mnt_slave_list);
247247
mnt->mnt_master = old;
248248
CLEAR_MNT_SHARED(mnt);
249-
} else {
249+
} else if (!(flag & CL_PRIVATE)) {
250250
if ((flag & CL_PROPAGATION) || IS_MNT_SHARED(old))
251251
list_add(&mnt->mnt_share, &old->mnt_share);
252252
if (IS_MNT_SLAVE(old))
@@ -746,6 +746,26 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
746746
return NULL;
747747
}
748748

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+
749769
/*
750770
* @source_mnt : mount tree to be attached
751771
* @nd : place the mount tree @source_mnt is attached

fs/open.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
569569
dentry = file->f_path.dentry;
570570
inode = dentry->d_inode;
571571

572-
audit_inode(NULL, inode);
572+
audit_inode(NULL, dentry);
573573

574574
err = -EROFS;
575575
if (IS_RDONLY(inode))
@@ -727,7 +727,7 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
727727
goto out;
728728

729729
dentry = file->f_path.dentry;
730-
audit_inode(NULL, dentry->d_inode);
730+
audit_inode(NULL, dentry);
731731
error = chown_common(dentry, user, group);
732732
fput(file);
733733
out:

fs/pnode.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#define CL_COPY_ALL 0x04
2323
#define CL_MAKE_SHARED 0x08
2424
#define CL_PROPAGATION 0x10
25+
#define CL_PRIVATE 0x20
2526

2627
static inline void set_mnt_shared(struct vfsmount *mnt)
2728
{

fs/xattr.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ sys_fsetxattr(int fd, char __user *name, void __user *value,
267267
if (!f)
268268
return error;
269269
dentry = f->f_path.dentry;
270-
audit_inode(NULL, dentry->d_inode);
270+
audit_inode(NULL, dentry);
271271
error = setxattr(dentry, name, value, size, flags);
272272
fput(f);
273273
return error;
@@ -349,7 +349,7 @@ sys_fgetxattr(int fd, char __user *name, void __user *value, size_t size)
349349
f = fget(fd);
350350
if (!f)
351351
return error;
352-
audit_inode(NULL, f->f_path.dentry->d_inode);
352+
audit_inode(NULL, f->f_path.dentry);
353353
error = getxattr(f->f_path.dentry, name, value, size);
354354
fput(f);
355355
return error;
@@ -422,7 +422,7 @@ sys_flistxattr(int fd, char __user *list, size_t size)
422422
f = fget(fd);
423423
if (!f)
424424
return error;
425-
audit_inode(NULL, f->f_path.dentry->d_inode);
425+
audit_inode(NULL, f->f_path.dentry);
426426
error = listxattr(f->f_path.dentry, list, size);
427427
fput(f);
428428
return error;
@@ -485,7 +485,7 @@ sys_fremovexattr(int fd, char __user *name)
485485
if (!f)
486486
return error;
487487
dentry = f->f_path.dentry;
488-
audit_inode(NULL, dentry->d_inode);
488+
audit_inode(NULL, dentry);
489489
error = removexattr(dentry, name);
490490
fput(f);
491491
return error;

include/linux/audit.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@
6363
#define AUDIT_ADD_RULE 1011 /* Add syscall filtering rule */
6464
#define AUDIT_DEL_RULE 1012 /* Delete syscall filtering rule */
6565
#define AUDIT_LIST_RULES 1013 /* List syscall filtering rules */
66+
#define AUDIT_TRIM 1014 /* Trim junk from watched tree */
67+
#define AUDIT_MAKE_EQUIV 1015 /* Append to watched tree */
6668
#define AUDIT_TTY_GET 1016 /* Get TTY auditing status */
6769
#define AUDIT_TTY_SET 1017 /* Set TTY auditing status */
6870

@@ -203,6 +205,7 @@
203205
#define AUDIT_SUCCESS 104 /* exit >= 0; value ignored */
204206
#define AUDIT_WATCH 105
205207
#define AUDIT_PERM 106
208+
#define AUDIT_DIR 107
206209

207210
#define AUDIT_ARG0 200
208211
#define AUDIT_ARG1 (AUDIT_ARG0+1)
@@ -366,8 +369,8 @@ extern void audit_syscall_entry(int arch,
366369
extern void audit_syscall_exit(int failed, long return_code);
367370
extern void __audit_getname(const char *name);
368371
extern void audit_putname(const char *name);
369-
extern void __audit_inode(const char *name, const struct inode *inode);
370-
extern void __audit_inode_child(const char *dname, const struct inode *inode,
372+
extern void __audit_inode(const char *name, const struct dentry *dentry);
373+
extern void __audit_inode_child(const char *dname, const struct dentry *dentry,
371374
const struct inode *parent);
372375
extern void __audit_ptrace(struct task_struct *t);
373376

@@ -381,15 +384,15 @@ static inline void audit_getname(const char *name)
381384
if (unlikely(!audit_dummy_context()))
382385
__audit_getname(name);
383386
}
384-
static inline void audit_inode(const char *name, const struct inode *inode) {
387+
static inline void audit_inode(const char *name, const struct dentry *dentry) {
385388
if (unlikely(!audit_dummy_context()))
386-
__audit_inode(name, inode);
389+
__audit_inode(name, dentry);
387390
}
388391
static inline void audit_inode_child(const char *dname,
389-
const struct inode *inode,
392+
const struct dentry *dentry,
390393
const struct inode *parent) {
391394
if (unlikely(!audit_dummy_context()))
392-
__audit_inode_child(dname, inode, parent);
395+
__audit_inode_child(dname, dentry, parent);
393396
}
394397
void audit_core_dumps(long signr);
395398

@@ -477,9 +480,9 @@ extern int audit_signals;
477480
#define audit_dummy_context() 1
478481
#define audit_getname(n) do { ; } while (0)
479482
#define audit_putname(n) do { ; } while (0)
480-
#define __audit_inode(n,i) do { ; } while (0)
483+
#define __audit_inode(n,d) do { ; } while (0)
481484
#define __audit_inode_child(d,i,p) do { ; } while (0)
482-
#define audit_inode(n,i) do { ; } while (0)
485+
#define audit_inode(n,d) do { ; } while (0)
483486
#define audit_inode_child(d,i,p) do { ; } while (0)
484487
#define audit_core_dumps(i) do { ; } while (0)
485488
#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)

include/linux/dcache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ d_iput: no no no yes
178178
#define DCACHE_INOTIFY_PARENT_WATCHED 0x0020 /* Parent inode is watched */
179179

180180
extern spinlock_t dcache_lock;
181+
extern seqlock_t rename_lock;
181182

182183
/**
183184
* d_drop - drop a dentry

0 commit comments

Comments
 (0)