summaryrefslogtreecommitdiffstats
path: root/sys/gnu
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>2000-11-04 08:10:56 +0000
committerbde <bde@FreeBSD.org>2000-11-04 08:10:56 +0000
commitfee8e1a16f8a0e4301c0a5124798b3124c24cc24 (patch)
treefd52352ddb023c3c1bbd29192f19a662fdd5f67f /sys/gnu
parentc42d95e9d708ff966d7791db2c9641f2e2c50e18 (diff)
downloadFreeBSD-src-fee8e1a16f8a0e4301c0a5124798b3124c24cc24.zip
FreeBSD-src-fee8e1a16f8a0e4301c0a5124798b3124c24cc24.tar.gz
Fixed breakage of mknod() in rev.1.48 of ext2_vnops.c and rev.1.126 of
ufs_vnops.c: 1) i_ino was confused with i_number, so the inode number passed to VFS_VGET() was usually wrong (usually 0U). 2) ip was dereferenced after vgone() freed it, so the inode number passed to VFS_VGET() was sometimes not even wrong. Bug (1) was usually fatal in ext2_mknod(), since ext2fs doesn't have space for inode 0 on the disk; ino_to_fsba() subtracts 1 from the inode number, so inode number 0U gives a way out of bounds array index. Bug(1) was usually harmless in ufs_mknod(); ino_to_fsba() doesn't subtract 1, and VFS_VGET() reads suitable garbage (all 0's?) from the disk for the invalid inode number 0U; ufs_mknod() returns a wrong vnode, but most callers just vput() it; the correct vnode is eventually obtained by an implicit VFS_VGET() just like it used to be. Bug (2) usually doesn't happen.
Diffstat (limited to 'sys/gnu')
-rw-r--r--sys/gnu/ext2fs/ext2_vnops.c4
-rw-r--r--sys/gnu/fs/ext2fs/ext2_vnops.c4
2 files changed, 6 insertions, 2 deletions
diff --git a/sys/gnu/ext2fs/ext2_vnops.c b/sys/gnu/ext2fs/ext2_vnops.c
index b96e01c..a99c04f 100644
--- a/sys/gnu/ext2fs/ext2_vnops.c
+++ b/sys/gnu/ext2fs/ext2_vnops.c
@@ -264,6 +264,7 @@ ext2_mknod(ap)
struct vattr *vap = ap->a_vap;
struct vnode **vpp = ap->a_vpp;
struct inode *ip;
+ ino_t ino;
int error;
error = ext2_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
@@ -286,8 +287,9 @@ ext2_mknod(ap)
*/
vput(*vpp);
(*vpp)->v_type = VNON;
+ ino = ip->i_number; /* Save this before vgone() invalidates ip. */
vgone(*vpp);
- error = VFS_VGET(ap->a_dvp->v_mount, ip->i_ino, vpp);
+ error = VFS_VGET(ap->a_dvp->v_mount, ino, vpp);
if (error) {
*vpp = NULL;
return (error);
diff --git a/sys/gnu/fs/ext2fs/ext2_vnops.c b/sys/gnu/fs/ext2fs/ext2_vnops.c
index b96e01c..a99c04f 100644
--- a/sys/gnu/fs/ext2fs/ext2_vnops.c
+++ b/sys/gnu/fs/ext2fs/ext2_vnops.c
@@ -264,6 +264,7 @@ ext2_mknod(ap)
struct vattr *vap = ap->a_vap;
struct vnode **vpp = ap->a_vpp;
struct inode *ip;
+ ino_t ino;
int error;
error = ext2_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
@@ -286,8 +287,9 @@ ext2_mknod(ap)
*/
vput(*vpp);
(*vpp)->v_type = VNON;
+ ino = ip->i_number; /* Save this before vgone() invalidates ip. */
vgone(*vpp);
- error = VFS_VGET(ap->a_dvp->v_mount, ip->i_ino, vpp);
+ error = VFS_VGET(ap->a_dvp->v_mount, ino, vpp);
if (error) {
*vpp = NULL;
return (error);
OpenPOWER on IntegriCloud