[jcifs] SmbComWriteAndX writes corrupt offset to wire

Richard Heap richardheap at beeb.net
Tue Apr 13 14:01:04 GMT 2004


We observe a peculiar problem when using SmbFileOutputStream. Our 
application is a long running multi-threaded server, that accesses a 
share on a Windows 2000 server. A single thread is responsible for 
copying files up to the share (it reads from a FileInputStream and 
writes to a SmbFileOutputStream) - maybe one file every few seconds. 
Other threads (very infrequently) copy files back from the share (using 
SmbFileInputStream and FileOutputStream).

After the server has been running for a few 10s of minutes we notice 
that the files written to the share are corrupt. It seems that files are 
initially copied ok, and then something 'breaks'. An ethereal trace 
shows that the offset of the server-bound WriteAndX messages is corrupt.
The following code...
byte[] buffer = new byte[4000];
while ((int length = in.read(buffer)) > 0) {
  out.write(buffer, 0, length);
}
produces WriteAndX messages with the following offsets...
0, 3840, 7936, etc (instead of 0, 4000, 8000)
in hex these values are: 0x0F00 and 0x1F00 (should be 0x0FA0 and 0x1F40 
- i.e. it appears that the bottom byte is being squashed to zero)

This appears to be confirmed by the following ALL level log:
Apr 9 12:25:53.107 - smb sent
SmbComWriteAndX[command=SMB_COM_WRITE_ANDX,received=false,
errorCode=0x00000000,flags=0x0018,flags2=0x8003,tid=28677,pid=22517,
uid=57345,mid=2957,wordCount=14,byteCount=4000,andxCommand=0xFF,
andxOffset=0,fid=9,offset=4000,writeMode=0,remaining=0,dataLength=4000,
dataOffset=63]
Apr 9 12:25:53.107 - smb sent
00000: FF 53 4D 42 2F 00 00 00 00 18 03 80 00 00 00 00  |ÿSMB/...........|
00010: 00 00 00 00 00 00 00 00 05 70 F5 57 01 E0 8D 0B  |.........põW.à..|
00020: 0E FF 00 00 00 09 00 00 0F 00 00 00 00 00 00 00  |.ÿ..............|
00030: 00 00 00 00 00 A0 0F 3F 00 00 00 00 00 A0 0F 58  |..... .?..... .X|
00040: B6 2A 48 40 5A CE 16 8A 6F 2A 97 BF 72 DC 00 77  |¶*H at ZÎ..o*.¿rÜ.w|
00050: 56 36 F9 28 26 38 08 59 36 24 A2 B2 0F 2E 0E FD  |V6ù(&8.Y6$¢²...ý|
00060: B6 10 B1 DE 36 3F 16 91 B5 AF 85 15 AA A5 D2 C4  |¶.±Þ6?..µ¯..ª¥ÒÄ|
00070: D6 D8 29 53 63 79 53 20 55 6E CD 91 A4 F8 BE 3E  |ÖØ)ScyS UnÍ.¤ø¾>|
00080: 92 29 99 2C 97 31 DA 3D C2 65 22 69 8A 35 66 7B  |.).,.1Ú=Âe"i.5f{|
00090: B0 C4 82 6C 83 2C 97 D7 97 CF 06 71 FF 09 A3 6B  |°Ä.l.,.×.Ï.qÿ.£k|
000A0: F4 FE 87 14 BA A2 98 79 31 AD 20 D4 31 13 82 21  |ôþ..º¢.y1­ Ô1..!|
000B0: C9 71 15 2D FB AC B7 4A 61 A9 FA 65 3F 6B F9 57  |Éq.-û¬·Ja©úe?kùW|
000C0: C7 3A 68 D6 7A 37 4A AD B1 B2 57 77 97 4B 38 05  |Ç:hÖz7J­±²Ww.K8.
etc etc

What is interesting is that the toString() of the SmbComWriteAndX still 
shows 4000, yet the hex dump shows 00 0F 00 00 (decimal 3840)

There seems so little time/space for this to go wrong!
SmbTransport.send seems to write to wire and send...
synchronized( snd_buf ) {
                    int length = request.writeWireFormat(snd_buf, 0);
                    if( useSigning ) {
                        response.verifySequence = signSequence + 1;
                        sign(snd_buf, 0, length);
                    }
                    out.write(snd_buf, 0, length);
... all nicely synchronised
Could the signing be going wrong - don't think so - we don't think we 
are using this and, anyway it would do an arraycopy of 8 bytes

writeWireFormat just calls writeHeader and writeAndXWireFormat which 
seem simple enough...

there does not seem to be batching going on...

Any ideas?
By the way....
environment is Linux 2.4.20 kernel - java 1.4.2_01
seems to happen with 0.7.11, 0.7.19 and 0.8.2
(as yet I am unable to reproduce this with a test harness, only with the 
application itself)

Many thanks
Richard
-------------- next part --------------
HTML attachment scrubbed and removed


More information about the jcifs mailing list