summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2004-12-05 22:30:28 +0000
committermarcel <marcel@FreeBSD.org>2004-12-05 22:30:28 +0000
commit8b42e21d12e627514808f983d93b02293eaab637 (patch)
treeb7d392ad362fc25b52f43db8941e094488d81377 /sys
parenta12b213cad178436bbc1475d01f6bc93f197db3b (diff)
downloadFreeBSD-src-8b42e21d12e627514808f983d93b02293eaab637.zip
FreeBSD-src-8b42e21d12e627514808f983d93b02293eaab637.tar.gz
Fix null-pointer indirect function calls introduced in the previous
commit. In the new world order, the transitive closure on the vector operations is not precomputed. As such, it's unsafe to actually use any of the function pointers in an indirect function call. They can be null, and we need to use the default vector in that case. This is mostly a quick fix for the four function pointers that are ed explicitly. A more generic or scalable solution is likely to see the light of day. No pathos on: current@
Diffstat (limited to 'sys')
-rw-r--r--sys/gnu/ext2fs/ext2_vnops.c8
-rw-r--r--sys/gnu/fs/ext2fs/ext2_vnops.c8
-rw-r--r--sys/nfsclient/nfs_vnops.c6
-rw-r--r--sys/sys/vnode.h39
-rw-r--r--sys/ufs/ufs/ufs_vnops.c8
5 files changed, 54 insertions, 15 deletions
diff --git a/sys/gnu/ext2fs/ext2_vnops.c b/sys/gnu/ext2fs/ext2_vnops.c
index ebc39d0..aad5909 100644
--- a/sys/gnu/ext2fs/ext2_vnops.c
+++ b/sys/gnu/ext2fs/ext2_vnops.c
@@ -1476,7 +1476,7 @@ ext2fifo_read(ap)
uio = ap->a_uio;
resid = uio->uio_resid;
- error = fifo_specops.vop_read(ap);
+ error = vop_read(&fifo_specops, ap);
ip = VTOI(ap->a_vp);
if ((ap->a_vp->v_mount->mnt_flag & MNT_NOATIME) == 0 && ip != NULL &&
(uio->uio_resid != resid || (error == 0 && resid != 0)))
@@ -1502,7 +1502,7 @@ ext2fifo_write(ap)
uio = ap->a_uio;
resid = uio->uio_resid;
- error = fifo_specops.vop_write(ap);
+ error = vop_write(&fifo_specops, ap);
ip = VTOI(ap->a_vp);
if (ip != NULL && (uio->uio_resid != resid || (error == 0 && resid != 0)))
VTOI(ap->a_vp)->i_flag |= IN_CHANGE | IN_UPDATE;
@@ -1529,7 +1529,7 @@ ext2fifo_close(ap)
if (vp->v_usecount > 1)
ext2_itimes(vp);
VI_UNLOCK(vp);
- return (fifo_specops.vop_close(ap));
+ return (vop_close(&fifo_specops, ap));
}
/*
@@ -1543,7 +1543,7 @@ ext2fifo_kqfilter(ap)
{
int error;
- error = fifo_specops.vop_kqfilter(ap);
+ error = vop_kqfilter(&fifo_specops, ap);
if (error)
error = ext2_kqfilter(ap);
return (error);
diff --git a/sys/gnu/fs/ext2fs/ext2_vnops.c b/sys/gnu/fs/ext2fs/ext2_vnops.c
index ebc39d0..aad5909 100644
--- a/sys/gnu/fs/ext2fs/ext2_vnops.c
+++ b/sys/gnu/fs/ext2fs/ext2_vnops.c
@@ -1476,7 +1476,7 @@ ext2fifo_read(ap)
uio = ap->a_uio;
resid = uio->uio_resid;
- error = fifo_specops.vop_read(ap);
+ error = vop_read(&fifo_specops, ap);
ip = VTOI(ap->a_vp);
if ((ap->a_vp->v_mount->mnt_flag & MNT_NOATIME) == 0 && ip != NULL &&
(uio->uio_resid != resid || (error == 0 && resid != 0)))
@@ -1502,7 +1502,7 @@ ext2fifo_write(ap)
uio = ap->a_uio;
resid = uio->uio_resid;
- error = fifo_specops.vop_write(ap);
+ error = vop_write(&fifo_specops, ap);
ip = VTOI(ap->a_vp);
if (ip != NULL && (uio->uio_resid != resid || (error == 0 && resid != 0)))
VTOI(ap->a_vp)->i_flag |= IN_CHANGE | IN_UPDATE;
@@ -1529,7 +1529,7 @@ ext2fifo_close(ap)
if (vp->v_usecount > 1)
ext2_itimes(vp);
VI_UNLOCK(vp);
- return (fifo_specops.vop_close(ap));
+ return (vop_close(&fifo_specops, ap));
}
/*
@@ -1543,7 +1543,7 @@ ext2fifo_kqfilter(ap)
{
int error;
- error = fifo_specops.vop_kqfilter(ap);
+ error = vop_kqfilter(&fifo_specops, ap);
if (error)
error = ext2_kqfilter(ap);
return (error);
diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c
index 50756d3..48153d8 100644
--- a/sys/nfsclient/nfs_vnops.c
+++ b/sys/nfsclient/nfs_vnops.c
@@ -3036,7 +3036,7 @@ nfsfifo_read(struct vop_read_args *ap)
*/
np->n_flag |= NACC;
getnanotime(&np->n_atim);
- return (fifo_specops.vop_read(ap));
+ return (vop_read(&fifo_specops, ap));
}
/*
@@ -3052,7 +3052,7 @@ nfsfifo_write(struct vop_write_args *ap)
*/
np->n_flag |= NUPD;
getnanotime(&np->n_mtim);
- return (fifo_specops.vop_write(ap));
+ return (vop_write(&fifo_specops, ap));
}
/*
@@ -3087,7 +3087,7 @@ nfsfifo_close(struct vop_close_args *ap)
VOP_UNLOCK(vp, 0, ap->a_td);
}
}
- return (fifo_specops.vop_close(ap));
+ return (vop_close(&fifo_specops, ap));
}
/*
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 1cc45d1..394dd9b 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -698,6 +698,45 @@ extern struct vop_vector default_vnodeops;
#define VOP_EINVAL ((void*)(uintptr_t)vop_einval)
#define VOP_EOPNOTSUPP ((void*)(uintptr_t)vop_eopnotsupp)
+struct vop_close_args;
+static __inline int
+vop_close(struct vop_vector *vp, struct vop_close_args *ap)
+{
+
+ while (vp != NULL && vp->vop_close == NULL)
+ vp = vp->vop_default;
+ return ((vp != NULL) ? vp->vop_close(ap) : EOPNOTSUPP);
+}
+
+struct vop_kqfilter_args;
+static __inline int
+vop_kqfilter(struct vop_vector *vp, struct vop_kqfilter_args *ap)
+{
+
+ while (vp != NULL && vp->vop_kqfilter == NULL)
+ vp = vp->vop_default;
+ return ((vp != NULL) ? vp->vop_kqfilter(ap) : EOPNOTSUPP);
+}
+
+struct vop_read_args;
+static __inline int
+vop_read(struct vop_vector *vp, struct vop_read_args *ap)
+{
+
+ while (vp != NULL && vp->vop_read == NULL)
+ vp = vp->vop_default;
+ return ((vp != NULL) ? vp->vop_read(ap) : EOPNOTSUPP);
+}
+
+struct vop_write_args;
+static __inline int
+vop_write(struct vop_vector *vp, struct vop_write_args *ap)
+{
+
+ while (vp != NULL && vp->vop_write == NULL)
+ vp = vp->vop_default;
+ return ((vp != NULL) ? vp->vop_write(ap) : EOPNOTSUPP);
+}
#endif /* _KERNEL */
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index ede11e3..301e388 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -2020,7 +2020,7 @@ ufsfifo_read(ap)
uio = ap->a_uio;
resid = uio->uio_resid;
- error = fifo_specops.vop_read(ap);
+ error = vop_read(&fifo_specops, ap);
ip = VTOI(ap->a_vp);
if ((ap->a_vp->v_mount->mnt_flag & MNT_NOATIME) == 0 && ip != NULL &&
(uio->uio_resid != resid || (error == 0 && resid != 0)))
@@ -2046,7 +2046,7 @@ ufsfifo_write(ap)
uio = ap->a_uio;
resid = uio->uio_resid;
- error = fifo_specops.vop_write(ap);
+ error = vop_write(&fifo_specops, ap);
ip = VTOI(ap->a_vp);
if (ip != NULL && (uio->uio_resid != resid || (error == 0 && resid != 0)))
ip->i_flag |= IN_CHANGE | IN_UPDATE;
@@ -2073,7 +2073,7 @@ ufsfifo_close(ap)
if (vp->v_usecount > 1)
ufs_itimes(vp);
VI_UNLOCK(vp);
- return (fifo_specops.vop_close(ap));
+ return (vop_close(&fifo_specops, ap));
}
/*
@@ -2087,7 +2087,7 @@ ufsfifo_kqfilter(ap)
{
int error;
- error = fifo_specops.vop_kqfilter(ap);
+ error = vop_kqfilter(&fifo_specops, ap);
if (error)
error = ufs_kqfilter(ap);
return (error);
OpenPOWER on IntegriCloud