From e57f9e15d08ed46b2fac2562d1027c6a2ba80dac Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 13 Jun 2016 09:30:25 -0700 Subject: [PATCH] s3: smbd: In reply_read_and_X() SMB1 server is overwriting part of the 'reserved' zero fields with reply data length. This occurred due to old code that used to do: SSVAL(smb_buf(req->outbuf),-2,nread); to set the reply length. This code was not needed, as srv_set_message() was already correctly setting the bcc length and was probably left from much earlier legacy code. However, in commit ddaa65ef6e049a185281c4d5deca4045e3b085e2 this was converted to do: SSVAL(req->outbuf,smb_vwv11,smb_maxcnt); This code actually overwrites the last 'reserved' field in the SMB_COM_READ_ANDX packet reply, but we never noticed as no client (or server code) looks at or checks vwv11 in a SMB_COM_READ_ANDX reply. [MS-SMB] shows for SMB_COM_READ_ANDX reply: SMB_Parameters { UCHAR WordCount; Words { UCHAR AndXCommand; UCHAR AndXReserved; USHORT AndXOffset; USHORT Available; USHORT DataCompactionMode; USHORT Reserved1; USHORT DataLength; USHORT DataOffset; USHORT DataLengthHigh; USHORT Reserved2[4]; } } SMB_Data { USHORT ByteCount; Bytes { UCHAR Pad[] (optional); UCHAR Data[variable]; } and indeed checking wireshark from Win2012R2 we find that smbd is writing the returned read length into smb_vwv11 and Windows leaves it as zeros (reserved). Also fix the same problem in the named pipes code. Torture test to ensure Reserved2[4] replies are zero to follow. https://bugzilla.samba.org/show_bug.cgi?id=11845 Signed-off-by: Jeremy Allison Reviewed-by: Alexander Bokovoy --- source3/smbd/pipes.c | 1 - source3/smbd/reply.c | 1 - 2 files changed, 2 deletions(-) diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 2c9516d0756..bdc5af0ef91 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -492,7 +492,6 @@ static void pipe_read_andx_done(struct tevent_req *subreq) + 12 * sizeof(uint16_t) /* vwv */ + 2 /* the buflen field */ + 1); /* padding byte */ - SSVAL(req->outbuf,smb_vwv11,state->smb_maxcnt); DEBUG(3,("readX-IPC min=%d max=%d nread=%d\n", state->smb_mincnt, state->smb_maxcnt, (int)nread)); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 559aab0185f..0b7a4fbd329 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3941,7 +3941,6 @@ int setup_readX_header(char *outbuf, size_t smb_maxcnt) + 2 /* the buflen field */ + 1); /* padding byte */ SSVAL(outbuf,smb_vwv7,(smb_maxcnt >> 16)); - SSVAL(outbuf,smb_vwv11,smb_maxcnt); SCVAL(smb_buf(outbuf), 0, 0); /* padding byte */ /* Reset the outgoing length, set_message truncates at 0x1FFFF. */ _smb_setlen_large(outbuf, -- 2.47.3