[prev in list] [next in list] [prev in thread] [next in thread]
List: openbsd-bugs
Subject: kernel/1840: broken behaviour of accept() on a disconnected Unix-domain socket
From: rguyom () pobox ! com
Date: 2001-05-24 13:56:59
[Download RAW message or body]
>Number: 1840
>Category: kernel
>Synopsis: broken behaviour of accept() on a disconnected Unix-domain socket
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: bugs
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu May 24 08:00:02 MDT 2001
>Last-Modified:
>Originator: Rémi Guyomarch
>Organization:
net
>Release: 2.9
>Environment:
System : OpenBSD 2.9
Architecture: OpenBSD.i386
Machine : i386
Port : postfix-20010228.pl02-pcre
>Description:
The behaviour of accept() on a disconnected socket has changed since
2.8. Unfortunately, this change breaks Unix-domain sockets in a subtle
way, and postfix have problems with that :
postfix/flush[28969]: fatal: accept connection: Software caused connection abort
postfix/master[24048]: warning: process /usr/local/libexec/postfix/flush pid 28969 exit status 1
postfix/master[24048]: warning: /usr/local/libexec/postfix/flush: bad command startup -- throttling
Note that this bug may or may not bite you, depending on the load
and/or speed of your machine.
A few months ago a fix was commited in NetBSD :
http://mail-index.netbsd.org/source-changes/2001/03/21/0061.html
FreeBSD people commited a similiar fix :
http://docs.freebsd.org/cgi/getmsg.cgi?fetch=265947+0+archive/2001/freebsd-net/20010311.freebsd-net
>How-To-Repeat:
Install the postfix port on 2.9 and wait for 'flush' to log the error
mentionned above. Or write a few lines of code so that a client does
connect() write() and close() on a Unix-domain socket before the server
accept() the connection. The accept() call will fail with ECONNABORTED.
>Fix:
This is just a quick hack. It doesn't deal with protocols other than INET.
A fix a la NetBSD would probably be better (adding a protosw flag).
Index: sys/kern/uipc_socket.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.33
diff -u -r1.33 uipc_socket.c
--- sys/kern/uipc_socket.c 2001/03/06 19:42:43 1.33
+++ sys/kern/uipc_socket.c 2001/05/23 06:37:42
@@ -266,11 +266,7 @@
if ((so->so_state & SS_NOFDREF) == 0)
panic("soaccept: !NOFDREF");
so->so_state &= ~SS_NOFDREF;
- if ((so->so_state & SS_ISDISCONNECTED) == 0)
- error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT, NULL,
- nam, NULL);
- else
- error = ECONNABORTED;
+ error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT, NULL, nam, NULL);
splx(s);
return (error);
}
Index: sys/netinet/tcp_usrreq.c
===================================================================
RCS file: /usr/cvs/src/sys/netinet/tcp_usrreq.c,v
retrieving revision 1.50
diff -u -r1.50 tcp_usrreq.c
--- sys/netinet/tcp_usrreq.c 2000/12/13 09:47:08 1.50
+++ sys/netinet/tcp_usrreq.c 2001/05/23 06:36:34
@@ -351,6 +351,10 @@
* of the peer, storing through addr.
*/
case PRU_ACCEPT:
+ if (so->so_state & SS_ISDISCONNECTED) {
+ error = ECONNABORTED;
+ break;
+ }
#ifdef INET6
if (inp->inp_flags & INP_IPV6)
in6_setpeeraddr(inp, nam);
>Audit-Trail:
>Unformatted:
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic