diff options
author | alfred <alfred@FreeBSD.org> | 2000-11-30 20:04:44 +0000 |
---|---|---|
committer | alfred <alfred@FreeBSD.org> | 2000-11-30 20:04:44 +0000 |
commit | 69ecf492a62855b29a6ffc300a3df3c98a8cce35 (patch) | |
tree | 20ecf16d0d3b173f888d61cb7cb278b327d53e8e /sys | |
parent | 9b42eed500521f19d2d168abf5fbfb0ac47301ee (diff) | |
download | FreeBSD-src-69ecf492a62855b29a6ffc300a3df3c98a8cce35.zip FreeBSD-src-69ecf492a62855b29a6ffc300a3df3c98a8cce35.tar.gz |
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>
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/vfs_lookup.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index 4cd4b01..b963a94 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -404,6 +404,10 @@ dirloop: if ((dp->v_flag & VROOT) == 0 || (cnp->cn_flags & NOCROSSMOUNT)) break; + if (dp->v_mount == NULL) { /* forced unmount */ + error = EBADF; + goto bad; + } tdp = dp; dp = dp->v_mount->mnt_vnodecovered; vput(tdp); @@ -426,7 +430,7 @@ unionlookup: printf("not found\n"); #endif if ((error == ENOENT) && - (dp->v_flag & VROOT) && + (dp->v_flag & VROOT) && (dp->v_mount != NULL) && (dp->v_mount->mnt_flag & MNT_UNION)) { tdp = dp; dp = dp->v_mount->mnt_vnodecovered; @@ -510,6 +514,12 @@ unionlookup: ((cnp->cn_flags & FOLLOW) || trailing_slash || *ndp->ni_next == '/')) { 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) { error = EACCES; goto bad2; |