[Samba] Re: Test Failure for RW1 with samba-3.0.30, Solaris 9

Jeremy Allison jra at samba.org
Tue Jun 3 01:29:47 GMT 2008


On Mon, Jun 02, 2008 at 07:22:09PM -0400, David Eisner wrote:
> Hmm, I wonder if this isn't a bug with the fix for CVE-2008-1105.
> 
> I'll add a bug (to the 717 [1] "NEW" bugs for Samba 3.0 ...), but
> here's what seems to be going on at a low level:
> 
> When the client state is setup in run_readwritetest() by way of
> torture_open_connection(), cli_state->bufsize gets set to
> CLI_SAMBA_MAX_LARGE_READX_SIZE, which is defined to be 127*1024 ==
> 130048.
> 
> During the rw_torture2 iteration that breaks the test,
> send_file_readX() in smbd/reply.c calculates the packet length to
> send:
> 
>     nread = read_file(fsp,data,startpos,smb_maxcnt);
>     // ...
> 
>     outsize = set_message(outbuf,12,nread,False);
>     // ...
> 
>     /* Returning the number of bytes we want to send back - including header. */
>     return outsize;
> }
> 
> When RW1 fails, nread == 130048 (which is
> CLI_SAMBA_MAX_LARGE_READX_SIZE), and outsize is set by set_message()
> to be 39 + 2x12 + nread == 130111.
> 
> Later on, construct_reply reduces this by 4, and I think this becomes
> the length of the reply packet:
> 
>   static int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
>   {
>       // ...
>       if(outsize > 4)
>           smb_setlen(outbuf,outsize - 4);
>       return(outsize);
>   }
> 
> Now the length stored in the packet is 130111 - 4 == 130107
> 
> Back on the client side, receive_smb_raw()  (in lib/util_sock.c) is unhappy:
> 
>   BOOL receive_smb_raw(int fd, char *buffer, size_t buflen, unsigned
> int timeout)
>   {
>       // ...
>       len = read_smb_length_return_keepalive(fd,buffer,timeout);
>       // ...
>       if (len > buflen) {
>           DEBUG(0,("Invalid packet length! (%lu bytes).\n",(unsigned long)len));
>       //...
> 
> And here's the output (I added a debugging statement to also print buflen:
> 
> ##DRE: receive_smb_raw: Invalid packet length! len == (130107 bytes),
> buflen == (130048).
> 
> That is, it's complaining because 130107, the length reported in the
> reply packet header (I think), is larger than bufsize for the client
> state.  As to where the real problem is (i.e. does receive_smb_raw()
> need to do something with len before comparing it with buflen), I
> can't say.

Ah, I see the problem. CLI_SAMBA_MAX_LARGE_READX_SIZE is 127k
on the client, the server buffer size is 128k. For client large
readx/writex I should be allocating CLI_SAMBA_MAX_LARGE_READX_SIZE
+ LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN, not just
CLI_SAMBA_MAX_LARGE_READX_SIZE + SAFETY_MARGIN. It's safe as the
"safety margin" protects us but the client buffer detection
complains.

Try this patch against 3.0.x - should fix the problem.

Jeremy.
-------------- next part --------------
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c
index 3b97beb..632d910 100644
--- a/source/libsmb/cliconnect.c
+++ b/source/libsmb/cliconnect.c
@@ -1353,9 +1353,9 @@ bool cli_negprot(struct cli_state *cli)
 		if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
 			SAFE_FREE(cli->outbuf);
 			SAFE_FREE(cli->inbuf);
-			cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+SAFETY_MARGIN);
-			cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+SAFETY_MARGIN);
-			cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE;
+			cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
+			cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
+			cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE;
 		}
 
 	} else if (cli->protocol >= PROTOCOL_LANMAN1) {


More information about the samba mailing list