summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortruckman <truckman@FreeBSD.org>1998-11-23 00:45:39 +0000
committertruckman <truckman@FreeBSD.org>1998-11-23 00:45:39 +0000
commit0b3bd2def8c0b1aad4cf5df500e9eb3c3947b7c8 (patch)
treed691f40d0b0a4524e2ac6b8b24feccd6908d80ea
parent7db1d5d9598a5047cf40b7cd3e796316f31fb862 (diff)
downloadFreeBSD-src-0b3bd2def8c0b1aad4cf5df500e9eb3c3947b7c8.zip
FreeBSD-src-0b3bd2def8c0b1aad4cf5df500e9eb3c3947b7c8.tar.gz
We can't call fsetown() from sonewconn() because sonewconn() is be called
from an interrupt context and fsetown() wants to peek at curproc, call malloc(..., M_WAITOK), and fiddle with various unprotected data structures. The fix is to move the code that duplicates the F_SETOWN/FIOSETOWN state of the original socket to the new socket from sonewconn() to accept1(), since accept1() runs in the correct context. Deferring this until the process calls accept() is harmless since the process can't do anything useful with SIGIO on the new socket until it has the descriptor for that socket. One could make the case for not bothering to duplicate the F_SETOWN/FIOSETOWN state and requiring the process to explicitly make the fcntl() or ioctl() call on the new socket, but this would be incompatible with the previous implementation and might break programs which rely on the old semantics. This bug was discovered by Andrew Gallatin <gallatin@cs.duke.edu>.
-rw-r--r--sys/kern/uipc_sockbuf.c3
-rw-r--r--sys/kern/uipc_socket2.c3
-rw-r--r--sys/kern/uipc_syscalls.c4
3 files changed, 5 insertions, 5 deletions
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index 6c55ca0..9c4f037 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93
- * $Id: uipc_socket2.c,v 1.40 1998/11/04 20:22:11 fenner Exp $
+ * $Id: uipc_socket2.c,v 1.41 1998/11/11 10:03:56 truckman Exp $
*/
#include <sys/param.h>
@@ -213,7 +213,6 @@ sonewconn(head, connstatus)
so->so_state = head->so_state | SS_NOFDREF;
so->so_proto = head->so_proto;
so->so_timeo = head->so_timeo;
- fsetown(fgetown(head->so_sigio), &so->so_sigio);
so->so_uid = head->so_uid;
(void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat);
diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c
index 6c55ca0..9c4f037 100644
--- a/sys/kern/uipc_socket2.c
+++ b/sys/kern/uipc_socket2.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93
- * $Id: uipc_socket2.c,v 1.40 1998/11/04 20:22:11 fenner Exp $
+ * $Id: uipc_socket2.c,v 1.41 1998/11/11 10:03:56 truckman Exp $
*/
#include <sys/param.h>
@@ -213,7 +213,6 @@ sonewconn(head, connstatus)
so->so_state = head->so_state | SS_NOFDREF;
so->so_proto = head->so_proto;
so->so_timeo = head->so_timeo;
- fsetown(fgetown(head->so_sigio), &so->so_sigio);
so->so_uid = head->so_uid;
(void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat);
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index a857710..5abf279 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94
- * $Id: uipc_syscalls.c,v 1.45 1998/11/15 16:55:09 dg Exp $
+ * $Id: uipc_syscalls.c,v 1.46 1998/11/18 09:00:47 dg Exp $
*/
#include "opt_compat.h"
@@ -260,6 +260,8 @@ accept1(p, uap, compat)
so->so_state &= ~SS_COMP;
so->so_head = NULL;
+ if (head->so_sigio != NULL)
+ fsetown(fgetown(head->so_sigio), &so->so_sigio);
fp->f_type = DTYPE_SOCKET;
fp->f_flag = fflag;
OpenPOWER on IntegriCloud