summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2004-06-07 21:45:44 +0000
committerrwatson <rwatson@FreeBSD.org>2004-06-07 21:45:44 +0000
commit8555f72de82d6002b93baecd7ae8f5476557788d (patch)
tree6f13674cf87d99d1674d1552b33116dd9088f57f /sys/kern
parent2aec9e5a1887896b2f372c200feecab2c301869f (diff)
downloadFreeBSD-src-8555f72de82d6002b93baecd7ae8f5476557788d.zip
FreeBSD-src-8555f72de82d6002b93baecd7ae8f5476557788d.tar.gz
Correct a resource leak introduced in recent accept locking changes:
when I reordered events in accept1() to allocate a file descriptor earlier, I didn't properly update use of goto on exit to unwind for cases where the file descriptor is now held, but wasn't previously. The result was that, in the event of accept() on a non-blocking socket, or in the event of a socket error, a file descriptor would be leaked. This ended up being non-fatal in many cases, as the file descriptor would be properly GC'd on process exit, so only showed up for processes that do a lot of non-blocking accept() calls, and also live for a long time (such as qmail). This change updates the use of goto targets to do additional unwinding. Eyes provided by: Brian Feldman <green@freebsd.org> Feet, hands provided by: Stefan Ehmann <shoesoft@gmx.net>, Dimitry Andric <dimitry@andric.com> Arjan van Leeuwen <avleeuwen@piwebs.com>
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/uipc_syscalls.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 8d54cae..cce7396 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -253,7 +253,7 @@ accept1(td, uap, compat)
{
struct filedesc *fdp;
struct file *nfp = NULL;
- struct sockaddr *sa;
+ struct sockaddr *sa = NULL;
socklen_t namelen;
int error;
struct socket *head, *so;
@@ -285,7 +285,7 @@ accept1(td, uap, compat)
if ((head->so_state & SS_NBIO) && TAILQ_EMPTY(&head->so_comp)) {
ACCEPT_UNLOCK();
error = EWOULDBLOCK;
- goto done;
+ goto noconnection;
}
while (TAILQ_EMPTY(&head->so_comp) && head->so_error == 0) {
if (head->so_state & SS_CANTRCVMORE) {
@@ -296,14 +296,14 @@ accept1(td, uap, compat)
"accept", 0);
if (error) {
ACCEPT_UNLOCK();
- goto done;
+ goto noconnection;
}
}
if (head->so_error) {
error = head->so_error;
head->so_error = 0;
ACCEPT_UNLOCK();
- goto done;
+ goto noconnection;
}
so = TAILQ_FIRST(&head->so_comp);
KASSERT(!(so->so_qstate & SQ_INCOMP), ("accept1: so SQ_INCOMP"));
OpenPOWER on IntegriCloud