Nmap Development mailing list archives

Re: nsock_core.c:293 assertion failure (EPIPE, pipe broken)


From: doug () hcsw org
Date: Fri, 27 Feb 2009 03:56:48 +0000

On Fri, Feb 27, 2009 at 02:00:48AM +0000 or thereabouts, Brandon Enright wrote:
I was running Nmap in Valgrind at the time although no interesting
output was produce and I don't think Valgrind was the issue.
...
David did some searching and there is mention of EPIPE being returned on
send() calls when the remote host closes the connection unexpectedly.
The Nsock output though seems to indicate that EPIPE was broken during
a connect()

In unix there is a SIGPIPE signal to make implementing efficient
pipelines simpler. Take this pipeline:

cat billion-line-file.txt | head

After head is done slurping and printing the first 10 lines of the
file, it will exit, breaking the pipe. So when the cat process calls
write() again, unix will send it a SIGPIPE signal which kills it.

However, if a process ignores the SIGPIPE signal, the write will
return an EPIPE error instead and it is up to the application to
handle the problem gracefully.

You are right that connect() shouldn't return this error but check
the nsock code closely:

    /* First we want to determine whether the socket really is connected */
    if (getsockopt(iod->sd, SOL_SOCKET, SO_ERROR, (char *) &optval, &optlen) != 0)
      optval = socket_errno(); /* Stupid Solaris */

    ...

    switch(optval) {

    ...

    default:
      Snprintf(buf, sizeof(buf), "Strange connect error from %s (%d)", inet_ntop_ez(&iod->peer, iod->peerlen), optval);
      perror(buf);
      assert(0); /* I'd like for someone to report it */
      break;
    }

optval is from getsockopt(SOL_SOCKET, SO_ERROR) so it is the so_error
field of the socket, not an error from connect().

My guess is that the connect succeeded but the remote end closed the
connection before nmap got around to registering the connection as
successful, setting the socket's so_error to EPIPE for some reason.

If this is the case it should be fine to add EPIPE to the list of
errors that will register nse->status = NSE_STATUS_ERROR instead
of triggering the assertion, although it would be nice to know more
about under what conditions this happens.

BTW what OS were you using? Linux?

Hope this helps,

Doug

PS. DJB has some notes about the portability of getsockopt() etc:

http://cr.yp.to/docs/connect.html

I don't have my copy of Stevens' "Advanced programming in the UNIX environment"
with me but that book has more info about all of this.

Attachment: _bin
Description:


_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://SecLists.Org

Current thread: