This is a fix for a problem described in PR kern/19572. It was
recently discussed at -hackers. The problem is a null-pointer dereference that happens in kern/vfs_lookup.c when accessing ".." with a v_mount entry for the current directory vnode of NULL. This happens when a volume is forcibly unmounted, and the vnode for a working directory in the mounted volume is cleared. PR: 23191 Submitted by: Thomas Moestl <tmoestl@gmx.net>
This commit is contained in:
parent
9b67ac593b
commit
237710275e
@ -404,6 +404,10 @@ lookup(ndp)
|
|||||||
if ((dp->v_flag & VROOT) == 0 ||
|
if ((dp->v_flag & VROOT) == 0 ||
|
||||||
(cnp->cn_flags & NOCROSSMOUNT))
|
(cnp->cn_flags & NOCROSSMOUNT))
|
||||||
break;
|
break;
|
||||||
|
if (dp->v_mount == NULL) { /* forced unmount */
|
||||||
|
error = EBADF;
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
tdp = dp;
|
tdp = dp;
|
||||||
dp = dp->v_mount->mnt_vnodecovered;
|
dp = dp->v_mount->mnt_vnodecovered;
|
||||||
vput(tdp);
|
vput(tdp);
|
||||||
@ -426,7 +430,7 @@ lookup(ndp)
|
|||||||
printf("not found\n");
|
printf("not found\n");
|
||||||
#endif
|
#endif
|
||||||
if ((error == ENOENT) &&
|
if ((error == ENOENT) &&
|
||||||
(dp->v_flag & VROOT) &&
|
(dp->v_flag & VROOT) && (dp->v_mount != NULL) &&
|
||||||
(dp->v_mount->mnt_flag & MNT_UNION)) {
|
(dp->v_mount->mnt_flag & MNT_UNION)) {
|
||||||
tdp = dp;
|
tdp = dp;
|
||||||
dp = dp->v_mount->mnt_vnodecovered;
|
dp = dp->v_mount->mnt_vnodecovered;
|
||||||
@ -510,6 +514,12 @@ lookup(ndp)
|
|||||||
((cnp->cn_flags & FOLLOW) || trailing_slash ||
|
((cnp->cn_flags & FOLLOW) || trailing_slash ||
|
||||||
*ndp->ni_next == '/')) {
|
*ndp->ni_next == '/')) {
|
||||||
cnp->cn_flags |= ISSYMLINK;
|
cnp->cn_flags |= ISSYMLINK;
|
||||||
|
if (dp->v_mount == NULL) {
|
||||||
|
/* We can't know whether the directory was mounted with
|
||||||
|
* NOSYMFOLLOW, so we can't follow safely. */
|
||||||
|
error = EBADF;
|
||||||
|
goto bad2;
|
||||||
|
}
|
||||||
if (dp->v_mount->mnt_flag & MNT_NOSYMFOLLOW) {
|
if (dp->v_mount->mnt_flag & MNT_NOSYMFOLLOW) {
|
||||||
error = EACCES;
|
error = EACCES;
|
||||||
goto bad2;
|
goto bad2;
|
||||||
|
Loading…
Reference in New Issue
Block a user