innfeed segfaults on NULL buffer in getBanner() - mine too..

Russ Allbery rra at stanford.edu
Mon Aug 6 18:37:07 UTC 2007


Julien ÉLIE <julien at trigofacile.com> writes:

> I tried to compile from source last STABLE there.
> There are lots of warnings, though.  For instance:

> interface.c:454: warning: passing arg 2 of `SMseterror' discards qualifiers from pointer target type
> interface.c:455: warning: implicit declaration of function `warn'
> interface.c:455: warning: nested extern declaration of `warn'
> interface.c:480: warning: passing arg 2 of `SMseterror' discards qualifiers from pointer target type
> chan.c:51: warning: missing initializer
> chan.c:51: warning: (near initialization for `CHANnull.Skip')
> nc.c: In function `NCproc':
> nc.c:771: warning: comparison between signed and unsigned
> nc.c:772: warning: comparison between signed and unsigned
> nc.c:905: warning: int format, different type arg (arg 4)

> Is it normal? (with 'make warnings')

Yes.  I only quashed all the warnings in trunk; the changes to STABLE were
too invasive and without obvious benefit.

> As for the problem with innfeed, it segfaults as soon as it is started
> via newsfeeds (innfeed! entry with startinnfeed) and if a peer is set up
> in innfeed.conf.  The same occurs with a CURRENT version (innfeed! entry
> with directly innfeed).

Does this happen on all platforms or only on FreeBSD?

My comments in:

    http://lists.litech.org/pipermail/inn-workers/2007q1/013637.html

are unfortunately still true; I don't see how this situation could exist.
It means that ep->inBuffer is an empty buffer list, which causes doRead to
just abort.

prepareRead is responsible for setting up the buffers for the endpoint.
It sets the buffers to the passed value of buffers.  Since inBuffer isn't
NULL, this must have happened at some point.

connectionDone is presumably what set up the buffers for the getBanner
call.  It calls:

      readBuffers = makeBufferArray (bufferTakeRef (cxn->respBuffer), NULL) ;
      if ( !prepareRead (e, readBuffers, getBanner, cxn, 1) ) /* ... */

so the buffers we're using should be coming from cxn->respBuffer.  Or,
alternately, if it got a short read, it may be getBanner itself that set
things up with a new buffer.

The behavior is consistent with bufferTakeRef returning NULL, which it
will do if cxn->respBuffer is NULL.  However, that's set up in
newConnection:

  cxn->respBuffer = newBuffer (BUFFER_SIZE) ;
  ASSERT (cxn->respBuffer != NULL) ;

It would also be consistent with expandBuffer returning NULL, but I don't
see how that could happen either.

I think the only way to track down what's going on here is to walk through
innfeed in gdb and set a lot of breakpoints and try to figure out where
the buffer initialization is going wrong.

-- 
Russ Allbery (rra at stanford.edu)             <http://www.eyrie.org/~eagle/>

    Please send questions to the list rather than mailing me directly.
     <http://www.eyrie.org/~eagle/faqs/questions.html> explains why.


More information about the inn-workers mailing list