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>
This commit is contained in:
parent
a4118ee1d8
commit
d893f1bc2a
|
@ -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) {
|
||||
|
|
|
@ -786,11 +786,11 @@ struct file *nameidata_to_filp(struct nameidata *nd)
|
|||
/* Pick up the filp from the open intent */
|
||||
filp = nd->intent.open.file;
|
||||
/* 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,
|
||||
NULL, cred);
|
||||
else
|
||||
path_put(&nd->path);
|
||||
}
|
||||
return filp;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue