diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2010-10-29 03:30:42 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-10-29 04:14:56 -0400 |
commit | d893f1bc2a9f0f7dcb4b433452c59f9bedac0d7d (patch) | |
tree | b3cf84a271ccb19529d83a544b6024bbb23a7801 /fs/open.c | |
parent | a4118ee1d80b527c385cadd14db79559efb8a493 (diff) |
fix open/umount race
nameidata_to_filp() drops nd->path or transfers it to opened
file. In the former case it's a Bad Idea(tm) to do mnt_drop_write()
on nd->path.mnt, since we might race with umount and vfsmount in
question might be gone already.
Fix: don't drop it, then... IOW, have nameidata_to_filp() grab nd->path
in case it transfers it to file and do path_drop() in callers. After
they are through with accessing nd->path...
Reported-by: Miklos Szeredi <miklos@szeredi.hu>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/open.c')
-rw-r--r-- | fs/open.c | 6 |
1 files changed, 3 insertions, 3 deletions
@@ -786,11 +786,11 @@ struct file *nameidata_to_filp(struct nameidata *nd) | |||
786 | /* Pick up the filp from the open intent */ | 786 | /* Pick up the filp from the open intent */ |
787 | filp = nd->intent.open.file; | 787 | filp = nd->intent.open.file; |
788 | /* Has the filesystem initialised the file for us? */ | 788 | /* Has the filesystem initialised the file for us? */ |
789 | if (filp->f_path.dentry == NULL) | 789 | if (filp->f_path.dentry == NULL) { |
790 | path_get(&nd->path); | ||
790 | filp = __dentry_open(nd->path.dentry, nd->path.mnt, filp, | 791 | filp = __dentry_open(nd->path.dentry, nd->path.mnt, filp, |
791 | NULL, cred); | 792 | NULL, cred); |
792 | else | 793 | } |
793 | path_put(&nd->path); | ||
794 | return filp; | 794 | return filp; |
795 | } | 795 | } |
796 | 796 | ||