diff options
author | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 1998-08-21 23:31:36 +0000 |
---|---|---|
committer | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 1998-08-21 23:31:36 +0000 |
commit | 89632bb6a0545c56ef2bc8d3372c2cef3c34d570 (patch) | |
tree | 6adce8471c48de2b564946923fa029be082ddd26 /sys/isofs/cd9660 | |
parent | 1274d4f909c6bc16b5a91647f99d09c4db759407 (diff) |
Fix malloc race in the cd9660 fs.
Diffstat (limited to 'sys/isofs/cd9660')
-rw-r--r-- | sys/isofs/cd9660/cd9660_node.c | 15 | ||||
-rw-r--r-- | sys/isofs/cd9660/cd9660_node.h | 4 | ||||
-rw-r--r-- | sys/isofs/cd9660/cd9660_vfsops.c | 15 |
3 files changed, 27 insertions, 7 deletions
diff --git a/sys/isofs/cd9660/cd9660_node.c b/sys/isofs/cd9660/cd9660_node.c index 23597ee6d80..050a4f417c3 100644 --- a/sys/isofs/cd9660/cd9660_node.c +++ b/sys/isofs/cd9660/cd9660_node.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cd9660_node.c,v 1.8 1998/07/22 16:40:08 deraadt Exp $ */ +/* $OpenBSD: cd9660_node.c,v 1.9 1998/08/21 23:31:32 csapuntz Exp $ */ /* $NetBSD: cd9660_node.c,v 1.17 1997/05/05 07:13:57 mycroft Exp $ */ /*- @@ -181,7 +181,7 @@ loop: /* * Insert the inode into the hash table, and return it locked. */ -void +int cd9660_ihashins(ip) struct iso_node *ip; { @@ -190,6 +190,13 @@ cd9660_ihashins(ip) simple_lock(&cd9660_ihash_slock); ipp = &isohashtbl[INOHASH(ip->i_dev, ip->i_number)]; + + for (iq = *ipp; iq; iq = iq->i_next) { + if (iq->i_dev == ip->i_dev && + iq->i_number == ip->i_number) + return (EEXIST); + } + if ((iq = *ipp) != NULL) iq->i_prev = &ip->i_next; ip->i_next = iq; @@ -198,6 +205,7 @@ cd9660_ihashins(ip) simple_unlock(&cd9660_ihash_slock); lockmgr(&ip->i_lock, LK_EXCLUSIVE, 0, p); + return (0); } /* @@ -209,6 +217,9 @@ cd9660_ihashrem(ip) { register struct iso_node *iq; + if (ip->i_prev == NULL) + return; + simple_lock(&cd9660_ihash_slock); if ((iq = ip->i_next) != NULL) iq->i_prev = ip->i_prev; diff --git a/sys/isofs/cd9660/cd9660_node.h b/sys/isofs/cd9660/cd9660_node.h index 3d11161935f..357d1b414f4 100644 --- a/sys/isofs/cd9660/cd9660_node.h +++ b/sys/isofs/cd9660/cd9660_node.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cd9660_node.h,v 1.6 1997/11/08 17:21:07 niklas Exp $ */ +/* $OpenBSD: cd9660_node.h,v 1.7 1998/08/21 23:31:34 csapuntz Exp $ */ /* $NetBSD: cd9660_node.h,v 1.15 1997/04/11 21:52:01 kleink Exp $ */ /*- @@ -140,7 +140,7 @@ void cd9660_defattr __P((struct iso_directory_record *, struct iso_node *, void cd9660_deftstamp __P((struct iso_directory_record *, struct iso_node *, struct buf *)); struct vnode *cd9660_ihashget __P((dev_t, ino_t)); -void cd9660_ihashins __P((struct iso_node *)); +int cd9660_ihashins __P((struct iso_node *)); void cd9660_ihashrem __P((struct iso_node *)); int cd9660_tstamp_conv7 __P((u_char *, struct timespec *)); int cd9660_tstamp_conv17 __P((u_char *, struct timespec *)); diff --git a/sys/isofs/cd9660/cd9660_vfsops.c b/sys/isofs/cd9660/cd9660_vfsops.c index 923c285ef8b..c71e5a47505 100644 --- a/sys/isofs/cd9660/cd9660_vfsops.c +++ b/sys/isofs/cd9660/cd9660_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cd9660_vfsops.c,v 1.13 1998/02/08 22:41:32 tholo Exp $ */ +/* $OpenBSD: cd9660_vfsops.c,v 1.14 1998/08/21 23:31:35 csapuntz Exp $ */ /* $NetBSD: cd9660_vfsops.c,v 1.26 1997/06/13 15:38:58 pk Exp $ */ /*- @@ -683,6 +683,7 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir) dev_t dev; int error; +retry: imp = VFSTOISOFS(mp); dev = imp->im_dev; if ((*vpp = cd9660_ihashget(dev, ino)) != NULLVP) @@ -708,7 +709,16 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir) * for old data structures to be purged or for the contents of the * disk portion of this inode to be read. */ - cd9660_ihashins(ip); + error = cd9660_ihashins(ip); + + if (error) { + vrele(vp); + + if (error == EEXIST) + goto retry; + + return (error); + } if (isodir == 0) { int lbn, off; @@ -855,7 +865,6 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir) */ vp = nvp; ip->i_vnode = vp; - cd9660_ihashins(ip); } break; case VLNK: |