Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Feb 2001 19:40:58 -0600
From:      Jonathan Lemon <jlemon@flugsvamp.com>
To:        Archie Cobbs <archie@dellroad.org>
Cc:        Jonathan Lemon <jlemon@flugsvamp.com>, kris@obsecurity.org, net@freebsd.org
Subject:   Re: [itojun@iijlab.net: accept(2) behavior with tcp RST right after handshake]
Message-ID:  <20010212194058.A1479@prism.flugsvamp.com>
In-Reply-To: <200102130051.QAA72498@curve.dellroad.org>
References:  <20010212122855.A92213@prism.flugsvamp.com> <200102130051.QAA72498@curve.dellroad.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Feb 12, 2001 at 04:51:48PM -0800, Archie Cobbs wrote:
> Jonathan Lemon writes:
> > > > Did you guys agree on a commit-worthy fix yet?
> > > 
> > > I wasn't party to the issue that generated this thread in the first
> > > place, but..  I think the concensus is that if accept(2) returns
> > > an error then this will break some applications, so instead it
> > > should return a socket which will itself return an error on the
> > > first operation. Somebody correct me if I'm wrong.
> > 
> > No, as this is the current behavior.  The change will be for accept
> > to return an error, on the basis that 1) most apps already do the 
> > wrong thing now anyway, and 2) it brings us closer to a 'standard',
> > e.g.: what other systems are doing as well.
> 
> I don't understand then.
> 
> What is the problem with the current behavior? Is this just an
> optimization or a real bug fix? I'd say it's not worth changing
> if it's just an optimization, because too many things will break.
> Several apps have already been pointed out.
> 
> And what do you mean by ``most apps already do the wrong thing now''?

Consider the following bit of "canonical" code, of which some variant
is probably found in almost all network programs: 

	struct sockaddr_in sin;

	len = sizeof(sin);
	fd = accept(s, (struct sockaddr *)&sin, &len);
	if (fd == -1)
		err(1, "accept");
	printf("peer address: %s\n", inet_ntoa(sin.sin_addr));

The bug with this code is that it blindly uses ``sin'' after accept
returns, since the usage of the returned sockaddr must first be qualified
by checking the returned value of len.  Current behavior is for accept
to return a valid fd, and set len to 0.

To my knowledge, most applications (certainly those I inspected) do not
bother to check 'len' before using 'sin', and thus do the wrong thing;
this is the bug that BIND ran into.  (just to be clear, this is a bug
in the application code, not the kernel; although you could make the
case that it is a documentation bug as well).

It seems that other systems (and maybe the SuS?) expect accept to return
ECONNABORTED in this case.   Both BIND and Apache expect this, at least.

It seems to me that the odds of an application being able to correctly
handle an error return from accept() are far greater than the odds that
the code  correctly checks 'len' upon return from accept.  This, combined
with the standard, seems to be rationale enough to make the change.
--
Jonathan


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010212194058.A1479>