[jcifs] Potential concurrency problem

Michael B Allen ioplex at gmail.com
Tue Sep 30 14:44:17 GMT 2008


On Tue, Sep 30, 2008 at 6:56 AM, Ronny Schuetz <Usenet.r96 at gishpuppy.com> wrote:
> Hi,
>
> jCIFS version is 1.2.19. Just ran into an ArrayIndexOutOfBoundsException
> in NbtAddress#getWINSAddress(). NbtAddress#NBNS contains 4 entries, Java
> failed to access index 4.
>
> The only reason why the index was incremented to 4 is - as it looks like
> - that NbtAddress#switchWINS() (at least the part incrementing
> nbnsIndex) isn't synchronized, i.e. it could happen that it gets
> incremented to a value outside the array bounds if executed by multiple
> threads in parallel.
>
> This can be verified by using multiple threads calling
> UniAddress#getByName() in loops in parallel (with
> jcifs.netbios.cachePolicy set to 0 and all netbios timeouts set 1 to
> enforce the switching) and replacing the line (NbtAddress#switchWINS()):
>
> nbnsIndex = (nbnsIndex + 1) < NBNS.length ? nbnsIndex + 1 : 0;
>
> by equivalent code that includes some sleeps at the right place
>
> if((nbnsIndex + 1) < NBNS.length)
> {
>  try { Thread.sleep(1000); } catch(InterruptedException e) {}
>  nbnsIndex = nbnsIndex + 1;
> }
> else
> {
>  try { Thread.sleep(1000); } catch(InterruptedException e) {}
>  nbnsIndex = 0;
> }
>
> Synchronizing the method NbtAddress#switchWINS() in general or just the
> line changing the index on the class object seems to help.

Yup. This is a concurrency error (albeit one that will only occur if
you have an unresponsive WINS server and rarely at that).

However, synchronizing switchWINS is not a good solution as it will
still leave the possibility for concurrency problems.

You should use the NameServiceClient.java lock where it is calling
switchWINS. Meaning add a synchronized (LOCK) { } around that WINS
manipulation like:

261                 synchronized (LOCK) {
262                     if (NbtAddress.isWINS( request.addr ) == false)
263                         break;
264
265                                     /* Message was sent to WINS but
266                                      * failed to receive response.
267                                      * Try a different WINS server.
268                                      */
269                     if (request.addr == NbtAddress.getWINSAddress())
270                         NbtAddress.switchWINS();
271                     request.addr = NbtAddress.getWINSAddress();
272                 }

Please try this and let me know. If it works OK I'll incorporate the fix.

Mike

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


More information about the jcifs mailing list