summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authoralfred <alfred@FreeBSD.org>2000-11-30 20:04:44 +0000
committeralfred <alfred@FreeBSD.org>2000-11-30 20:04:44 +0000
commit69ecf492a62855b29a6ffc300a3df3c98a8cce35 (patch)
tree20ecf16d0d3b173f888d61cb7cb278b327d53e8e /sys
parent9b42eed500521f19d2d168abf5fbfb0ac47301ee (diff)
downloadFreeBSD-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.c12
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;
OpenPOWER on IntegriCloud