From 99a59a63db9b7324da1ddbf3d4a91c338ac5075c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 19 Sep 2012 08:11:23 +0200 Subject: [PATCH 1/2] libcli/smb: fix padding in smb2_create_blob* metze (cherry picked from commit aa5caf1fe92b159eae00c7b11499e9ec697cf9ae) --- libcli/smb/smb2_create_blob.c | 41 ++++++++++++++++++++++++++++++----------- 1 files changed, 30 insertions(+), 11 deletions(-) diff --git a/libcli/smb/smb2_create_blob.c b/libcli/smb/smb2_create_blob.c index 2175a0c..189bcd1 100644 --- a/libcli/smb/smb2_create_blob.c +++ b/libcli/smb/smb2_create_blob.c @@ -61,10 +61,10 @@ NTSTATUS smb2_create_blob_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB buffer, if ((next & 0x7) != 0 || next > remaining || - name_offset < 16 || - name_offset > remaining || - name_length != 4 || /* windows enforces this */ + name_offset != 16 || + name_length < 4 || name_offset + name_length > remaining || + (data_offset & 0x7) != 0 || (data_offset && (data_offset < name_offset + name_length)) || (data_offset && (data_offset > remaining)) || (data_offset && data_length && @@ -108,25 +108,44 @@ static NTSTATUS smb2_create_blob_push_one(TALLOC_CTX *mem_ctx, DATA_BLOB *buffer { uint32_t ofs = buffer->length; size_t tag_length = strlen(blob->tag); - uint8_t pad = smb2_create_blob_padding(blob->data.length+tag_length, 4); + size_t blob_offset = 0; + size_t blob_pad = 0; + size_t next_offset = 0; + size_t next_pad = 0; + bool ok; + + blob_offset = 0x14 + tag_length; + blob_pad = smb2_create_blob_padding(blob_offset, 8); + next_offset = blob_offset + blob_pad + blob->data.length; + if (!last) { + next_pad = smb2_create_blob_padding(next_offset, 8); + } - if (!data_blob_realloc(mem_ctx, buffer, - buffer->length + 0x14 + tag_length + blob->data.length + pad)) + ok = data_blob_realloc(mem_ctx, buffer, + buffer->length + next_offset + next_pad); + if (!ok) { return NT_STATUS_NO_MEMORY; + } if (last) { SIVAL(buffer->data, ofs+0x00, 0); } else { - SIVAL(buffer->data, ofs+0x00, 0x14 + tag_length + blob->data.length + pad); + SIVAL(buffer->data, ofs+0x00, next_offset + next_pad); } SSVAL(buffer->data, ofs+0x04, 0x10); /* offset of tag */ SIVAL(buffer->data, ofs+0x06, tag_length); /* tag length */ - SSVAL(buffer->data, ofs+0x0A, 0x14 + tag_length); /* offset of data */ + SSVAL(buffer->data, ofs+0x0A, blob_offset + blob_pad); /* offset of data */ SIVAL(buffer->data, ofs+0x0C, blob->data.length); memcpy(buffer->data+ofs+0x10, blob->tag, tag_length); - SIVAL(buffer->data, ofs+0x10+tag_length, 0); /* pad? */ - memcpy(buffer->data+ofs+0x14+tag_length, blob->data.data, blob->data.length); - memset(buffer->data+ofs+0x14+tag_length+blob->data.length, 0, pad); + if (blob_pad > 0) { + memset(buffer->data+ofs+blob_offset, 0, blob_pad); + blob_offset += blob_pad; + } + memcpy(buffer->data+ofs+blob_offset, blob->data.data, blob->data.length); + if (next_pad > 0) { + memset(buffer->data+ofs+next_offset, 0, next_pad); + next_offset += next_pad; + } return NT_STATUS_OK; } -- 1.7.7.3 From ba2a1a92a662beb9285647ed36236e0a83104f1d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 26 Sep 2012 16:58:58 -0700 Subject: [PATCH 2/2] Fix bug #9209 - Parse of invalid SMB2 create blob can cause smbd crash. Ensure we correctly protect against blobs with data_offset==0 and data_length != 0. Jeremy. Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Thu Sep 27 22:07:02 CEST 2012 on sn-devel-104 (cherry picked from commit 322e3d42f65dadabeccf8813fcb0e9b7d353ffb2) --- libcli/smb/smb2_create_blob.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/libcli/smb/smb2_create_blob.c b/libcli/smb/smb2_create_blob.c index 189bcd1..92387db 100644 --- a/libcli/smb/smb2_create_blob.c +++ b/libcli/smb/smb2_create_blob.c @@ -66,9 +66,8 @@ NTSTATUS smb2_create_blob_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB buffer, name_offset + name_length > remaining || (data_offset & 0x7) != 0 || (data_offset && (data_offset < name_offset + name_length)) || - (data_offset && (data_offset > remaining)) || - (data_offset && data_length && - (data_offset + (uint64_t)data_length > remaining))) { + (data_offset > remaining) || + (data_offset + (uint64_t)data_length > remaining)) { return NT_STATUS_INVALID_PARAMETER; } -- 1.7.7.3