Commit d893f1bc authored by Al Viro's avatar Al Viro
Browse files

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: default avatarMiklos Szeredi <miklos@szeredi.hu>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent a4118ee1
...@@ -1574,6 +1574,7 @@ static struct file *finish_open(struct nameidata *nd, ...@@ -1574,6 +1574,7 @@ static struct file *finish_open(struct nameidata *nd,
*/ */
if (will_truncate) if (will_truncate)
mnt_drop_write(nd->path.mnt); mnt_drop_write(nd->path.mnt);
path_put(&nd->path);
return filp; return filp;
exit: exit:
...@@ -1675,6 +1676,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path, ...@@ -1675,6 +1676,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
} }
filp = nameidata_to_filp(nd); filp = nameidata_to_filp(nd);
mnt_drop_write(nd->path.mnt); mnt_drop_write(nd->path.mnt);
path_put(&nd->path);
if (!IS_ERR(filp)) { if (!IS_ERR(filp)) {
error = ima_file_check(filp, acc_mode); error = ima_file_check(filp, acc_mode);
if (error) { if (error) {
......
...@@ -786,11 +786,11 @@ struct file *nameidata_to_filp(struct nameidata *nd) ...@@ -786,11 +786,11 @@ struct file *nameidata_to_filp(struct nameidata *nd)
/* Pick up the filp from the open intent */ /* Pick up the filp from the open intent */
filp = nd->intent.open.file; filp = nd->intent.open.file;
/* Has the filesystem initialised the file for us? */ /* Has the filesystem initialised the file for us? */
if (filp->f_path.dentry == NULL) if (filp->f_path.dentry == NULL) {
path_get(&nd->path);
filp = __dentry_open(nd->path.dentry, nd->path.mnt, filp, filp = __dentry_open(nd->path.dentry, nd->path.mnt, filp,
NULL, cred); NULL, cred);
else }
path_put(&nd->path);
return filp; return filp;
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment