summaryrefslogtreecommitdiff
path: root/sys/isofs/cd9660
diff options
context:
space:
mode:
authorConstantine Sapuntzakis <csapuntz@cvs.openbsd.org>1998-08-21 23:31:36 +0000
committerConstantine Sapuntzakis <csapuntz@cvs.openbsd.org>1998-08-21 23:31:36 +0000
commit89632bb6a0545c56ef2bc8d3372c2cef3c34d570 (patch)
tree6adce8471c48de2b564946923fa029be082ddd26 /sys/isofs/cd9660
parent1274d4f909c6bc16b5a91647f99d09c4db759407 (diff)
Fix malloc race in the cd9660 fs.
Diffstat (limited to 'sys/isofs/cd9660')
-rw-r--r--sys/isofs/cd9660/cd9660_node.c15
-rw-r--r--sys/isofs/cd9660/cd9660_node.h4
-rw-r--r--sys/isofs/cd9660/cd9660_vfsops.c15
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: