From 20cc8ccc9e2906d272083d58059d3992a8a641eb Mon Sep 17 00:00:00 2001 From: Ralph Wuerthner Date: Wed, 10 Jul 2013 08:59:58 +0200 Subject: [PATCH 01/13] s3:smbd: return NT_STATUS_INFO_LENGTH_MISMATCH for GetInfo in case output_buffer_length is too small Reviewed-by: Jeremy Allison Reviewed-by: Volker Lendecke (cherry picked from commit a93f9c3d33e442c84d0c9da7eb5d25ca4b54fc33) --- source3/smbd/smb2_getinfo.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index 55071e8..30daaad 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -485,6 +485,11 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } + if (state->out_output_buffer.length > in_output_buffer_length) { + tevent_req_nterror(req, NT_STATUS_INFO_LENGTH_MISMATCH); + return tevent_req_post(req, ev); + } + tevent_req_done(req); return tevent_req_post(req, ev); } -- 1.8.4 From 8d964b6b2526fd65f5e84c68cbde2ee8fa2b2a6f Mon Sep 17 00:00:00 2001 From: Ralph Wuerthner Date: Fri, 5 Jul 2013 11:03:16 +0200 Subject: [PATCH 02/13] s3:smbd: allow GetInfo responses with STATUS_BUFFER_OVERFLOW to return partial, but valid data Reviewed-by: Jeremy Allison Reviewed-by: Volker Lendecke (cherry picked from commit a91d2b05bab329a8a9772c2c79a3b1e02933182e) --- source3/smbd/smb2_getinfo.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index 30daaad..2a74f30 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -148,7 +148,10 @@ static void smbd_smb2_request_getinfo_done(struct tevent_req *subreq) return; } - if (!NT_STATUS_IS_OK(call_status)) { + /* some GetInfo responses set STATUS_BUFFER_OVERFLOW and return partial, + but valid data */ + if (!(NT_STATUS_IS_OK(call_status) || + NT_STATUS_EQUAL(call_status, STATUS_BUFFER_OVERFLOW))) { /* Return a specific error with data. */ error = smbd_smb2_request_error_ex(req, call_status, @@ -185,7 +188,7 @@ static void smbd_smb2_request_getinfo_done(struct tevent_req *subreq) outdyn = out_output_buffer; - error = smbd_smb2_request_done(req, outbody, &outdyn); + error = smbd_smb2_request_done_ex(req, call_status, outbody, &outdyn, __location__); if (!NT_STATUS_IS_OK(error)) { smbd_server_connection_terminate(req->sconn, nt_errstr(error)); @@ -407,7 +410,10 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, fsp->fsp_name, &data, &data_size); - if (!NT_STATUS_IS_OK(status)) { + /* some responses set STATUS_BUFFER_OVERFLOW and return + partial, but valid data */ + if (!(NT_STATUS_IS_OK(status) || + NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW))) { SAFE_FREE(data); if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) { status = NT_STATUS_INVALID_INFO_CLASS; @@ -490,6 +496,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } + state->status = status; tevent_req_done(req); return tevent_req_post(req, ev); } -- 1.8.4 From 96e0bc1fb1acd98fa62691999f58e4446a7a6fa5 Mon Sep 17 00:00:00 2001 From: Ralph Wuerthner Date: Fri, 5 Jul 2013 11:32:27 +0200 Subject: [PATCH 03/13] s3:smbd: allow status code in smbd_do_qfsinfo() to be set by information class handler Reviewed-by: Jeremy Allison Reviewed-by: Volker Lendecke (cherry picked from commit 616777f029e462f53c5118d79de8c6405a5fb7c1) --- source3/smbd/trans2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index ccce7b8..20d42f7 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2984,6 +2984,7 @@ NTSTATUS smbd_do_qfsinfo(connection_struct *conn, uint32 additional_flags = 0; struct smb_filename smb_fname; SMB_STRUCT_STAT st; + NTSTATUS status = NT_STATUS_OK; if (fname == NULL || fname->base_name == NULL) { filename = "."; @@ -3526,7 +3527,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned } *ret_data_len = data_len; - return NT_STATUS_OK; + return status; } /**************************************************************************** -- 1.8.4 From 761546e6670370b2e5aed30c72373b0a8c25f6ca Mon Sep 17 00:00:00 2001 From: Ralph Wuerthner Date: Wed, 10 Jul 2013 15:52:06 +0200 Subject: [PATCH 04/13] s3:smbd: allow info class SMB_QUERY_FS_VOLUME_INFO to return partial data Reviewed-by: Jeremy Allison Reviewed-by: Volker Lendecke (cherry picked from commit ec46f6b91941e38dd92f8e0fb0f278592e3157b6) --- source3/smbd/trans2.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 20d42f7..575f96e 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3144,6 +3144,13 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n", (int)strlen(vname),vname, lp_servicename(snum))); + if (max_data_bytes >= 24 && data_len > max_data_bytes) { + /* the client only requested a portion of the + volume label */ + data_len = max_data_bytes; + status = STATUS_BUFFER_OVERFLOW; + } + break; case SMB_QUERY_FS_SIZE_INFO: -- 1.8.4 From 52f1f6e0a8c6112bc23b3effa3fb8e4e4c3d9295 Mon Sep 17 00:00:00 2001 From: Ralph Wuerthner Date: Wed, 10 Jul 2013 16:43:39 +0200 Subject: [PATCH 05/13] s3:smbd: allow info class SMB_QUERY_FS_ATTRIBUTE_INFO to return partial data Reviewed-by: Jeremy Allison Reviewed-by: Volker Lendecke (cherry picked from commit 270d29a743a030653037cb176f3764bec3c79b6c) --- source3/smbd/trans2.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 575f96e..fda962c 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3115,6 +3115,12 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u STR_UNICODE); SIVAL(pdata,8,len); data_len = 12 + len; + if (max_data_bytes >= 16 && data_len > max_data_bytes) { + /* the client only requested a portion of the + file system name */ + data_len = max_data_bytes; + status = STATUS_BUFFER_OVERFLOW; + } break; case SMB_QUERY_FS_LABEL_INFO: -- 1.8.4 From d9513399ff881bbb110996c61dd10caf0166d38e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 26 Aug 2013 08:36:14 +0000 Subject: [PATCH 06/13] smbd: Use #defines in smb2_getinfo_send Signed-off-by: Volker Lendecke Reviewed-by: David Disseldorp Autobuild-User(master): David Disseldorp Autobuild-Date(master): Tue Aug 27 15:08:08 CEST 2013 on sn-devel-104 (cherry picked from commit 323cccd35d06c7327c19dc5cb891043507624d7d) --- source3/smbd/smb2_getinfo.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index 2a74f30..36b5140 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -273,7 +273,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, } switch (in_info_type) { - case 0x01:/* SMB2_GETINFO_FILE */ + case SMB2_GETINFO_FILE: { uint16_t file_info_level; char *data = NULL; @@ -394,7 +394,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, break; } - case 0x02:/* SMB2_GETINFO_FS */ + case SMB2_GETINFO_FS: { uint16_t file_info_level; char *data = NULL; @@ -434,7 +434,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, break; } - case 0x03:/* SMB2_GETINFO_SEC */ + case SMB2_GETINFO_SECURITY: { uint8_t *p_marshalled_sd = NULL; size_t sd_size = 0; -- 1.8.4 From a3bc272f3368c3626d1fe9dd7fc0e9ee25dd874c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 27 Aug 2013 09:06:27 +0000 Subject: [PATCH 07/13] smbd: qfilepathinfo has fixed/variable buffers The error message will have to change depending whether the buffer is too small for the fixed or variable buffers Bug: https://bugzilla.samba.org/show_bug.cgi?id=10106 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 53123996033594f68a3fc9037474aada3aef0750) --- source3/smbd/globals.h | 1 + source3/smbd/smb2_getinfo.c | 2 ++ source3/smbd/trans2.c | 22 ++++++++++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index ce5b18d..7fbe608 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -162,6 +162,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, char *lock_data, uint16_t flags2, unsigned int max_data_bytes, + size_t *fixed_portion, char **ppdata, unsigned int *pdata_size); diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index 36b5140..b991152 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -284,6 +284,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, struct ea_list *ea_list = NULL; int lock_data_count = 0; char *lock_data = NULL; + size_t fixed_portion; ZERO_STRUCT(write_time_ts); @@ -371,6 +372,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, lock_data, STR_UNICODE, in_output_buffer_length, + &fixed_portion, &data, &data_size); if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index fda962c..f1da13e 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4286,6 +4286,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, char *lock_data, uint16_t flags2, unsigned int max_data_bytes, + size_t *fixed_portion, char **ppdata, unsigned int *pdata_size) { @@ -4421,6 +4422,8 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, BasicFileInformationTest. -tpot */ file_index = get_FileIndex(conn, psbuf); + *fixed_portion = 0; + switch (info_level) { case SMB_INFO_STANDARD: DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n")); @@ -4558,6 +4561,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, DEBUG(5,("write: %s ", ctime(&mtime))); DEBUG(5,("change: %s ", ctime(&c_time))); DEBUG(5,("mode: %x\n", mode)); + *fixed_portion = data_size; break; case SMB_FILE_STANDARD_INFORMATION: @@ -4571,6 +4575,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, SCVAL(pdata,20,delete_pending?1:0); SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0); SSVAL(pdata,22,0); /* Padding. */ + *fixed_portion = 24; break; case SMB_FILE_EA_INFORMATION: @@ -4580,6 +4585,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, estimate_ea_size(conn, fsp, smb_fname->base_name); DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n")); data_size = 4; + *fixed_portion = 4; SIVAL(pdata,0,ea_size); break; } @@ -4601,6 +4607,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, STR_UNICODE); data_size = 4 + len; SIVAL(pdata,0,len); + *fixed_portion = 8; break; } @@ -4664,6 +4671,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, SIVAL(pdata,0,len); pdata += 4 + len; data_size = PTR_DIFF(pdata,(*ppdata)); + *fixed_portion = 10; break; } @@ -4701,6 +4709,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, SIVAL(pdata,0,len); pdata += 4 + len; data_size = PTR_DIFF(pdata,(*ppdata)); + *fixed_portion = 104; break; } case SMB_FILE_INTERNAL_INFORMATION: @@ -4708,12 +4717,14 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n")); SBVAL(pdata, 0, file_index); data_size = 8; + *fixed_portion = 8; break; case SMB_FILE_ACCESS_INFORMATION: DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n")); SIVAL(pdata, 0, access_mask); data_size = 4; + *fixed_portion = 4; break; case SMB_FILE_NAME_INFORMATION: @@ -4731,24 +4742,28 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n")); data_size = 1; SCVAL(pdata,0,delete_pending); + *fixed_portion = 1; break; case SMB_FILE_POSITION_INFORMATION: DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n")); data_size = 8; SOFF_T(pdata,0,pos); + *fixed_portion = 8; break; case SMB_FILE_MODE_INFORMATION: DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n")); SIVAL(pdata,0,mode); data_size = 4; + *fixed_portion = 4; break; case SMB_FILE_ALIGNMENT_INFORMATION: DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n")); SIVAL(pdata,0,0); /* No alignment needed. */ data_size = 4; + *fixed_portion = 4; break; /* @@ -4793,6 +4808,8 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, TALLOC_FREE(streams); + *fixed_portion = 32; + break; } case SMB_QUERY_COMPRESSION_INFO: @@ -4802,6 +4819,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, SIVAL(pdata,8,0); /* ??? */ SIVAL(pdata,12,0); /* ??? */ data_size = 16; + *fixed_portion = 16; break; case SMB_FILE_NETWORK_OPEN_INFORMATION: @@ -4815,6 +4833,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, SIVAL(pdata,48,mode); SIVAL(pdata,52,0); /* ??? */ data_size = 56; + *fixed_portion = 56; break; case SMB_FILE_ATTRIBUTE_TAG_INFORMATION: @@ -4822,6 +4841,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, SIVAL(pdata,0,mode); SIVAL(pdata,4,0); data_size = 8; + *fixed_portion = 8; break; /* @@ -5091,6 +5111,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, struct ea_list *ea_list = NULL; int lock_data_count = 0; char *lock_data = NULL; + size_t fixed_portion; NTSTATUS status = NT_STATUS_OK; if (!params) { @@ -5452,6 +5473,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd ea_list, lock_data_count, lock_data, req->flags2, max_data_bytes, + &fixed_portion, ppdata, &data_size); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); -- 1.8.4 From a880e8ffc81ee2e7fd22e2f26fd5462171767d62 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 27 Aug 2013 09:06:27 +0000 Subject: [PATCH 08/13] smbd: qfsinfo has fixed/variable buffers The error message will have to change depending whether the buffer is too small for the fixed or variable buffers Bug: https://bugzilla.samba.org/show_bug.cgi?id=10106 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit ac41df91a5a425633fc716ca02187e753879d795) --- source3/smbd/globals.h | 1 + source3/smbd/smb2_getinfo.c | 2 ++ source3/smbd/trans2.c | 10 ++++++++++ 3 files changed, 13 insertions(+) diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 7fbe608..8cec74c 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -180,6 +180,7 @@ NTSTATUS smbd_do_qfsinfo(connection_struct *conn, uint16_t info_level, uint16_t flags2, unsigned int max_data_bytes, + size_t *fixed_portion, struct smb_filename *smb_fname, char **ppdata, int *ret_data_len); diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index b991152..91595d5 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -401,6 +401,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, uint16_t file_info_level; char *data = NULL; int data_size = 0; + size_t fixed_portion; /* the levels directly map to the passthru levels */ file_info_level = in_file_info_class + 1000; @@ -409,6 +410,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, file_info_level, STR_UNICODE, in_output_buffer_length, + &fixed_portion, fsp->fsp_name, &data, &data_size); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index f1da13e..2f840b7 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2971,6 +2971,7 @@ NTSTATUS smbd_do_qfsinfo(connection_struct *conn, uint16_t info_level, uint16_t flags2, unsigned int max_data_bytes, + size_t *fixed_portion, struct smb_filename *fname, char **ppdata, int *ret_data_len) @@ -3023,6 +3024,8 @@ NTSTATUS smbd_do_qfsinfo(connection_struct *conn, memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); end_data = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1; + *fixed_portion = 0; + switch (info_level) { case SMB_INFO_ALLOCATION: { @@ -3121,6 +3124,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u data_len = max_data_bytes; status = STATUS_BUFFER_OVERFLOW; } + *fixed_portion = 16; break; case SMB_QUERY_FS_LABEL_INFO: @@ -3189,6 +3193,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned SBIG_UINT(pdata,8,dfree); SIVAL(pdata,16,sectors_per_unit); SIVAL(pdata,20,bytes_per_sector); + *fixed_portion = 24; break; } @@ -3222,6 +3227,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */ SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */ SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */ + *fixed_portion = 32; break; } @@ -3236,6 +3242,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned data_len = 8; SIVAL(pdata,0,FILE_DEVICE_DISK); /* dev type */ SIVAL(pdata,4,characteristics); + *fixed_portion = 8; break; } @@ -3410,6 +3417,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn)))); return NT_STATUS_DOS(ERRSRV, ERRerror); } + *fixed_portion = 24; break; } @@ -3556,6 +3564,7 @@ static void call_trans2qfsinfo(connection_struct *conn, char *params = *pparams; uint16_t info_level; int data_len = 0; + size_t fixed_portion; NTSTATUS status; if (total_params < 2) { @@ -3582,6 +3591,7 @@ static void call_trans2qfsinfo(connection_struct *conn, info_level, req->flags2, max_data_bytes, + &fixed_portion, NULL, ppdata, &data_len); if (!NT_STATUS_IS_OK(status)) { -- 1.8.4 From 944a8d5ee03357979e7fe5e7105cffb03cd9d5de Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 27 Aug 2013 09:36:03 +0000 Subject: [PATCH 09/13] smbd: Correctly return INFO_LENGTH_MISMATCH in smb2_getinfo We have to return this error if the client offered less than the fixed portion of the infolevel data requires Bug: https://bugzilla.samba.org/show_bug.cgi?id=10106 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 91939614760837b2ac2c6bb8b5daac108a4f4670) --- source3/smbd/smb2_getinfo.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index 91595d5..714a6bd 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -383,6 +383,12 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, tevent_req_nterror(req, status); return tevent_req_post(req, ev); } + if (in_output_buffer_length < fixed_portion) { + SAFE_FREE(data); + tevent_req_nterror( + req, NT_STATUS_INFO_LENGTH_MISMATCH); + return tevent_req_post(req, ev); + } if (data_size > 0) { state->out_output_buffer = data_blob_talloc(state, data, @@ -425,6 +431,12 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, tevent_req_nterror(req, status); return tevent_req_post(req, ev); } + if (in_output_buffer_length < fixed_portion) { + SAFE_FREE(data); + tevent_req_nterror( + req, NT_STATUS_INFO_LENGTH_MISMATCH); + return tevent_req_post(req, ev); + } if (data_size > 0) { state->out_output_buffer = data_blob_talloc(state, data, -- 1.8.4 From a48f21ab072cc2b5983f167336e3dfac36aae96c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 27 Aug 2013 09:37:34 +0000 Subject: [PATCH 10/13] smbd: Correctly return BUFFER_OVERFLOW in smb2_getinfo Also, don't overflow the client buffer Bug: https://bugzilla.samba.org/show_bug.cgi?id=10106 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 40f60024ca19e33cbbe9825b42692f386a8f1dd9) --- source3/smbd/smb2_getinfo.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index 714a6bd..6f901e3 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -397,6 +397,11 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, if (tevent_req_nomem(state->out_output_buffer.data, req)) { return tevent_req_post(req, ev); } + if (data_size > in_output_buffer_length) { + state->out_output_buffer.length = + in_output_buffer_length; + status = STATUS_BUFFER_OVERFLOW; + } } SAFE_FREE(data); break; @@ -445,6 +450,11 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, if (tevent_req_nomem(state->out_output_buffer.data, req)) { return tevent_req_post(req, ev); } + if (data_size > in_output_buffer_length) { + state->out_output_buffer.length = + in_output_buffer_length; + status = STATUS_BUFFER_OVERFLOW; + } } SAFE_FREE(data); break; -- 1.8.4 From 8399216dff596bee1b9c97714d4a9d588abc089c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 27 Aug 2013 09:38:29 +0000 Subject: [PATCH 11/13] smbd: Revert a93f9c3 This was too broad and has been replaced by finer-grained error checks Bug: https://bugzilla.samba.org/show_bug.cgi?id=10106 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit b37edda32930fec372d6467d442f67532c3fbd33) --- source3/smbd/smb2_getinfo.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index 6f901e3..9ad2847 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -517,11 +517,6 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - if (state->out_output_buffer.length > in_output_buffer_length) { - tevent_req_nterror(req, NT_STATUS_INFO_LENGTH_MISMATCH); - return tevent_req_post(req, ev); - } - state->status = status; tevent_req_done(req); return tevent_req_post(req, ev); -- 1.8.4 From 1990d2654b209cfad9c3f546737b5811dae1ab97 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 27 Aug 2013 09:39:17 +0000 Subject: [PATCH 12/13] smbd: Fix error return for STREAM_INFO The stream_info marshalling follows its own rules. This needs unifying eventually... Bug: https://bugzilla.samba.org/show_bug.cgi?id=10106 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 5634f240fd4273cb7327111140ccbea0fd41e3fc) --- source3/smbd/trans2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 2f840b7..3c8c06f 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4145,6 +4145,10 @@ static NTSTATUS marshall_stream_info(unsigned int num_streams, unsigned int i; unsigned int ofs = 0; + if (max_data_bytes < 32) { + return NT_STATUS_INFO_LENGTH_MISMATCH; + } + for (i = 0; i < num_streams; i++) { unsigned int next_offset; size_t namelen; -- 1.8.4 From b52a0d37d95e8ab272f33855023b8189ae4c8015 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 27 Aug 2013 09:40:19 +0000 Subject: [PATCH 13/13] smbd: Correctly return INFO_LENGTH_MISMATCH for smb1 This is required if the client offered less buffer than the fixed portion of the info level data requires Bug: https://bugzilla.samba.org/show_bug.cgi?id=10106 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 1b1935b876a14154ef74e447bf53eb7cd0a5dde9) --- source3/smbd/trans2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 3c8c06f..26b6523 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -5493,6 +5493,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd reply_nterror(req, status); return; } + if (fixed_portion > max_data_bytes) { + reply_nterror(req, NT_STATUS_INFO_LENGTH_MISMATCH); + return; + } send_trans2_replies(conn, req, params, param_size, *ppdata, data_size, max_data_bytes); -- 1.8.4