summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1998-03-01 19:34:16 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1998-03-01 19:34:16 +0000
commitf44d78ca22d5130c3ffa300d35e4fc22e69d337e (patch)
tree489aee50e2d67093e6913dca60debefe9a1486e0
parent180d1a8fdeb91b3359c8cd52423477adb265905d (diff)
crank f_count/f_msgcount to long; when incrementing try to leave 2 slots
empty for unp_gc() in case of cross referenced sockets. part by millert
-rw-r--r--sys/kern/kern_descrip.c19
-rw-r--r--sys/kern/uipc_usrreq.c7
2 files changed, 21 insertions, 5 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 06eb363448f..bd032c20b9a 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_descrip.c,v 1.14 1997/08/31 20:42:15 deraadt Exp $ */
+/* $OpenBSD: kern_descrip.c,v 1.15 1998/03/01 19:34:12 deraadt Exp $ */
/* $NetBSD: kern_descrip.c,v 1.42 1996/03/30 22:24:38 christos Exp $ */
/*
@@ -353,6 +353,8 @@ finishdup(fdp, old, new, retval)
register struct file *fp;
fp = fdp->fd_ofiles[old];
+ if (fp->f_count == LONG_MAX-2)
+ return (EDEADLK);
fdp->fd_ofiles[new] = fp;
fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] &~ UF_EXCLOSE;
fp->f_count++;
@@ -745,8 +747,17 @@ fdcopy(p)
bcopy(fdp->fd_ofileflags, newfdp->fd_ofileflags, i * sizeof(char));
fpp = newfdp->fd_ofiles;
for (i = newfdp->fd_lastfile; i >= 0; i--, fpp++)
- if (*fpp != NULL)
- (*fpp)->f_count++;
+ if (*fpp != NULL) {
+ /*
+ * XXX Gruesome hack. If count gets too high, fail
+ * to copy an fd, since fdcopy()'s callers do not
+ * permit it to indicate failure yet.
+ */
+ if ((*fpp)->f_count == LONG_MAX-2)
+ *fpp = NULL;
+ else
+ (*fpp)->f_count++;
+ }
return (newfdp);
}
@@ -956,6 +967,8 @@ dupfdopen(fdp, indx, dfd, mode, error)
*/
if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag)
return (EACCES);
+ if (wfp->f_count == LONG_MAX-2)
+ return (EDEADLK);
fdp->fd_ofiles[indx] = wfp;
fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
wfp->f_count++;
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index bb6bfbd7098..1d2ef6a345a 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_usrreq.c,v 1.8 1997/11/17 18:09:15 deraadt Exp $ */
+/* $OpenBSD: uipc_usrreq.c,v 1.9 1998/03/01 19:34:15 deraadt Exp $ */
/* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */
/*
@@ -661,6 +661,9 @@ unp_internalize(control, p)
if ((unsigned)fd >= fdp->fd_nfiles ||
fdp->fd_ofiles[fd] == NULL)
return (EBADF);
+ if (fdp->fd_ofiles[fd]->f_count == LONG_MAX-2 ||
+ fdp->fd_ofiles[fd]->f_msgcount == LONG_MAX-2)
+ return (EDEADLK);
}
ip = (int *)(cm + 1);
if (sizeof(int) != sizeof(struct file *)) {
@@ -747,7 +750,7 @@ unp_gc()
* that are not otherwise accessible and then free the rights
* that are stored in messages on them.
*
- * The bug in the orginal code is a little tricky, so I'll describe
+ * The bug in the original code is a little tricky, so I'll describe
* what's wrong with it here.
*
* It is incorrect to simply unp_discard each entry for f_msgcount