[jcifs] Endless loop while contacting WINS if none of the servers

Michael B Allen mba2000 at ioplex.com
Wed Nov 1 03:05:03 GMT 2006


On Mon, 30 Oct 2006 17:01:44 +0100
"Dominique Laurent" <lauredo at gmail.com> wrote:

> Hello Stefan,
> 
> We observed the same behaviour. Actually it caused a Denial of
> Services on our production servers, because we had two WINS servers
> configured and they were not available at that time => all threads
> became endlessly looping => no more thread and file handles available
> => DoS
> 
> Could one of the jcifs committers add the patch into the repository?

There is no repository. But this is a serious flaw so I'll put it at
the top of The List.

Mike

> Also there seems to be something strange in the condition
> NbtAddress.isWINS( request.addr ) which in the loop is always true
> unless NBNS is empty.
> 
> Thanks in advance,
> Dominique.
> 
> P.S. Hereunder is a slightly modified version of the method (same
> logic but less lines):
> 
> 
>     void send( NameServicePacket request, NameServicePacket response,
>                int timeout ) throws IOException {
>         Integer nid = null;
>         int count = NbtAddress.NBNS.length;
> 
>         synchronized( response ) {
>             do {
>                 try {
>                     synchronized( LOCK ) {
>                         request.nameTrnId = getNextNameTrnId();
>                         nid = new Integer( request.nameTrnId );
> 
>                         out.setAddress( request.addr );
>                         out.setLength( request.writeWireFormat( snd_buf, 0 ));
>                         response.received = false;
> 
>                         responseTable.put( nid, response );
>                         ensureOpen( timeout + 1000 );
>                         socket.send( out );
> 
>                         if( log.level > 3 ) {
>                             log.println( request );
>                             Hexdump.hexdump( log, snd_buf, 0, out.getLength() );
>                         }
>                     }
> 
>                     response.wait( timeout );
> 
>                 } catch( InterruptedException ie ) {
>                 } finally {
>                     responseTable.remove( nid );
>                 }
>                 if( !response.received &&
>                         --count > 0 &&
>                         NbtAddress.isWINS( request.addr )) {
>                     /* Message was sent to WINS but
>                     * failed to receive response.
>                     * Try a different WINS server.
>                     */
>                     request.addr = NbtAddress.switchWINS();
>                 } else {
>                     break;
>                 }
>             } while( true );
>         }
>     }
> 
> 
> 
> 
> 
> -------------------------------------------------
> > Hi,
> >
> > we configured two WINS servers for jcifs (version 1.2.9) HTTP NTLM authentication. We discovered that jcifs hangs in an endless loop if none of the servers is reachable, i.e. the IP-addresses point to non-existing servers.
> > I supposed that jcifs would return an error or throw an exception after the configured timeout, but apparently it didn't return at all.
> >
> > So I investigated the code and I found a problem in the class    jcifs.netbios.NameServiceClient .
> > In method
> >   void send( NameServicePacket request, NameServicePacket response, int timeout)
> > the loop trying all WINS servers is not correctly terminated. It tries the first server, then the second and then (in case you configured two servers) first again and so on. So as long > as none of the servers gives an answer the method will not be left although the timeouts occur. I suppose that is not desired.
> >
> > I fixed it in our local copy of jcifs and I would appreciate if someone could tell me if I misunderstood something.
> > You will find my version of the method later on.
> >
> > Thx for your help,
> > Stefan
> >
> > ----
> >     void send( NameServicePacket request, NameServicePacket response,
> >                                             int timeout ) throws IOException {
> >         Integer nid = null;
> >         int count = NbtAddress.NBNS.length;
> >
> >         synchronized( response ) {
> >             do {
> >                 try {
> >                     synchronized( LOCK ) {
> >                         request.nameTrnId = getNextNameTrnId();
> >                         nid = new Integer( request.nameTrnId );
> >
> >                         out.setAddress( request.addr );
> >                         out.setLength( request.writeWireFormat( snd_buf, 0 ));
> >                         response.received = false;
> >
> >                         responseTable.put( nid, response );
> >                         ensureOpen( timeout + 1000 );
> >                         socket.send( out );
> >
> >                         if( log.level > 3 ) {
> >                             log.println( request );
> >                             Hexdump.hexdump( log, snd_buf, 0, out.getLength() );
> >                         }
> >                     }
> >
> >                     response.wait( timeout );
> >
> >                 } catch( InterruptedException ie ) {
> >                 } finally {
> >                     responseTable.remove( nid );
> >                 }
> >
> >                 if( !response.received &&
> >                             NbtAddress.NBNS.length > 1 &&
> >                             NbtAddress.isWINS( request.addr )) {
> >                                 /* Message was sent to WINS but
> >                                  * failed to receive response.
> >                                  * Try a different WINS server.
> >                                  */
> >                     count--;
> >                     if (count > 0) {
> >                       request.addr = NbtAddress.switchWINS();
> >                     } else {
> >                       break;
> >                     }
> >                 } else {
> >                   break;
> >                 }
> >             } while( true );
> >         }
> >     }
> 


-- 
Michael B Allen
PHP Active Directory SSO
http://www.ioplex.com/


More information about the jcifs mailing list