[jcifs] NullPointerException in SmbFile.resolveDfs()

Brett Johnson brett.michael.johnson at gmail.com
Mon Oct 15 16:09:20 MDT 2012


One of our customers have encountered a NullPointerException
thrown from deep within jCIFS while closing an input stream:

From a customer log:
Exception in thread "..." java.lang.NullPointerException
at jcifs.smb.SmbFile.resolveDfs(SmbFile.java:668)
at jcifs.smb.SmbFile.send(SmbFile.java:770)
at jcifs.smb.SmbFile.close(SmbFile.java:1018)
at jcifs.smb.SmbFile.close(SmbFile.java:1024)
at jcifs.smb.SmbFile.close(SmbFile.java:1028)
at jcifs.smb.SmbFileInputStream.close(SmbFileInputStream.java:104)
at java.io.BufferedInputStream.close(Unknown Source)
at com.google.enterprise.connector.filesystem.SmbInputStream.close(SmbInputStream.java:64)
at com.google.enterprise.connector.util.BasicChecksumGenerator.getDigest(BasicChecksumGenerator.java:117)
at com.google.enterprise.connector.util.BasicChecksumGenerator.getChecksum(BasicChecksumGenerator.java:131)
at com.google.enterprise.connector.filesystem.FileInfoCache.getChecksum(FileInfoCache.java:59)
at com.google.enterprise.connector.filesystem.FileDocumentSnapshot$GetUpdateSupport.getUpdate(FileDocumentSnapshot.java:384)
at com.google.enterprise.connector.filesystem.FileDocumentSnapshot.getUpdate(FileDocumentSnapshot.java:141)
at com.google.enterprise.connector.filesystem.FileDocumentSnapshot.getUpdate(FileDocumentSnapshot.java:35)

Looking more closely at SmbFile, the NPE is thrown from this statement:
   DfsReferral dr = dfs.resolve(
       tree.session.transport.tconHostName,
       tree.share,
       unc,
       auth);

I know dfs itself is not null, since it is statically initialized.
So the suspects are tree, tree.session, tree.session.transport.
Immediately before this statement is a call to connect0.  Examining
that code, tree starts out null but I don't think tree can be null after
a successful call to connect().

So that leaves tree.session and tree.session.transport.  Since 
session is a constructor arg for SmbTree, that probably is not
null.  That leaves only SmbSession.transport.  When I read SmbSession,
transport is initialized lazily and is always fetched via the 
SmbSession.transport() method.  I think that is the problem here.
I think JCIFS could be patched as follows (note transport() method call):

        DfsReferral dr = dfs.resolve(
                    tree.session.transport().tconHostName,
                    tree.share,
                    unc,
                    auth);

However, even after this, tconHostName is very likely to be null in the
current failure case, since it is populated by a call to transport.doConnect().
If domain is null, dfs.resolve() will throw NPE when it dereferences 
domain (which it does several times).  At this point, I don't know
enough about DFS and JCIFS to know how to fix the bug, so I modified
com.google.enterprise.connector.filesystem.SmbInputStream.close() to 
catch NullPointerException and rethrow as IOException.

--
Brett M. Johnson






More information about the jCIFS mailing list