diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2010-10-29 09:30:42 +0200 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-10-29 10:14:56 +0200 |
commit | d893f1bc2a9f0f7dcb4b433452c59f9bedac0d7d (patch) | |
tree | b3cf84a271ccb19529d83a544b6024bbb23a7801 /fs/namei.c | |
parent | a couple of open-coded ihold() introduced by nfs merge (diff) | |
download | linux-d893f1bc2a9f0f7dcb4b433452c59f9bedac0d7d.tar.xz linux-d893f1bc2a9f0f7dcb4b433452c59f9bedac0d7d.zip |
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/namei.c')
-rw-r--r-- | fs/namei.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/fs/namei.c b/fs/namei.c index f7dbc06857ab..5362af9b7372 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1574,6 +1574,7 @@ static struct file *finish_open(struct nameidata *nd, */ if (will_truncate) mnt_drop_write(nd->path.mnt); + path_put(&nd->path); return filp; exit: @@ -1675,6 +1676,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path, } filp = nameidata_to_filp(nd); mnt_drop_write(nd->path.mnt); + path_put(&nd->path); if (!IS_ERR(filp)) { error = ima_file_check(filp, acc_mode); if (error) { |