From d3478a0f11f5ae14884033d8c7310ccaad6f46b1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 23 Aug 2013 13:57:03 +0000 Subject: [PATCH 1/9] torture3: add clipathinfo-bufsize Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison --- source3/torture/proto.h | 1 + source3/torture/test_buffersize.c | 56 +++++++++++++++++++++++++++++++++++++++ source3/torture/torture.c | 1 + source3/wscript_build | 1 + 4 files changed, 59 insertions(+) create mode 100644 source3/torture/test_buffersize.c diff --git a/source3/torture/proto.h b/source3/torture/proto.h index 4f4c9e2..f6453fd 100644 --- a/source3/torture/proto.h +++ b/source3/torture/proto.h @@ -111,5 +111,6 @@ bool run_notify_bench3(int dummy); bool run_dbwrap_watch1(int dummy); bool run_idmap_tdb_common_test(int dummy); bool run_local_dbwrap_ctdb(int dummy); +bool run_qpathinfo_bufsize(int dummy); #endif /* __TORTURE_H__ */ diff --git a/source3/torture/test_buffersize.c b/source3/torture/test_buffersize.c new file mode 100644 index 0000000..6e86374 --- /dev/null +++ b/source3/torture/test_buffersize.c @@ -0,0 +1,56 @@ +/* + Unix SMB/CIFS implementation. + Test buffer sizes in cli_qpathinfo + Copyright (C) Volker Lendecke 2012 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "torture/proto.h" +#include "libsmb/libsmb.h" +#include "libcli/security/dom_sid.h" +#include "libcli/security/secdesc.h" +#include "libcli/security/security.h" +#include "trans2.h" +#include "source3/libsmb/clirap.h" + +bool run_qpathinfo_bufsize(int dummy) +{ + struct cli_state *cli = NULL; + NTSTATUS status, status2; + bool ret = false; + int i; + + printf("Starting qpathinfo_bufsize\n"); + + if (!torture_open_connection(&cli, 0)) { + printf("torture_open_connection failed\n"); + goto fail; + } + + for (i=0; i<500; i++) { + uint8_t *rdata; + uint32_t num_rdata; + cli_qpathinfo(cli, cli, "\\", SMB_FILE_ALL_INFORMATION, + 0, i, &rdata, &num_rdata); + } + + ret = true; +fail: + if (cli != NULL) { + torture_close_connection(cli); + } + return ret; +} diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 4a8e3ed..359baa9 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -9579,6 +9579,7 @@ static struct { { "local-tdb-opener", run_local_tdb_opener, 0 }, { "local-tdb-writer", run_local_tdb_writer, 0 }, { "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb, 0 }, + { "qpathinfo-bufsize", run_qpathinfo_bufsize, 0 }, {NULL, NULL, 0}}; /* diff --git a/source3/wscript_build b/source3/wscript_build index e166b16..e4417ea 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -560,6 +560,7 @@ SMBTORTURE_SRC1 = '''torture/torture.c torture/nbio.c torture/scanner.c torture/ torture/test_dbwrap_watch.c torture/test_idmap_tdb_common.c torture/test_dbwrap_ctdb.c + torture/test_buffersize.c torture/t_strappend.c''' SMBTORTURE_SRC = '''${SMBTORTURE_SRC1} -- 1.8.4 From 6a86fd09be4a293931a32066b1be0fbe1b5f01f2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 27 Aug 2013 09:06:27 +0000 Subject: [PATCH 2/9] 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 --- 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 d618aea..6ccb57e 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -138,6 +138,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 4420f94..0d75c36 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -293,6 +293,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); @@ -380,6 +381,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 b6cb3cc..1d55dbe 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4388,6 +4388,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) { @@ -4528,6 +4529,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")); @@ -4674,6 +4677,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: @@ -4687,6 +4691,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: @@ -4696,6 +4701,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, estimate_ea_size(conn, fsp, smb_fname); DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n")); data_size = 4; + *fixed_portion = 4; SIVAL(pdata,0,ea_size); break; } @@ -4717,6 +4723,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, STR_UNICODE); data_size = 4 + len; SIVAL(pdata,0,len); + *fixed_portion = 8; break; } @@ -4780,6 +4787,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; } @@ -4817,6 +4825,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: @@ -4824,12 +4833,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: @@ -4847,24 +4858,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; /* @@ -4909,6 +4924,8 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, TALLOC_FREE(streams); + *fixed_portion = 32; + break; } case SMB_QUERY_COMPRESSION_INFO: @@ -4918,6 +4935,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: @@ -4931,6 +4949,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: @@ -4938,6 +4957,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, SIVAL(pdata,0,mode); SIVAL(pdata,4,0); data_size = 8; + *fixed_portion = 8; break; /* @@ -5211,6 +5231,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) { @@ -5570,6 +5591,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 402ef4e7f3152e3417d6f1d398ae28a09f61965f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 27 Aug 2013 09:06:27 +0000 Subject: [PATCH 3/9] 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 --- 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 6ccb57e..9ea5e25 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -156,6 +156,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 0d75c36..698e775 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -410,6 +410,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; @@ -418,6 +419,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 1d55dbe..37f578c 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3068,6 +3068,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) @@ -3124,6 +3125,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: { @@ -3222,6 +3225,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: @@ -3258,6 +3262,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 = 24; break; case SMB_QUERY_FS_SIZE_INFO: @@ -3290,6 +3295,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; } @@ -3323,6 +3329,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; } @@ -3337,6 +3344,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; } @@ -3645,6 +3653,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) { @@ -3670,6 +3679,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 eebb7d5593f808c7d842f93d30b913b13e8304b0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 27 Aug 2013 09:36:03 +0000 Subject: [PATCH 4/9] 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 --- 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 698e775..c6a1433 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -392,6 +392,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, @@ -434,6 +440,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 6400f350152fc777aa7a75da7f8215454bfd6450 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 27 Aug 2013 09:37:34 +0000 Subject: [PATCH 5/9] 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 --- 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 c6a1433..4111aa1 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -406,6 +406,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; @@ -454,6 +459,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 ff3762db058456c00703c15c14fff4ff119864db Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 27 Aug 2013 09:38:29 +0000 Subject: [PATCH 6/9] 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 --- 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 4111aa1..449aeb3 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -530,11 +530,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 296aecabfa766a0e5effe84cd34a114e3c4c19c9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 27 Aug 2013 09:39:17 +0000 Subject: [PATCH 7/9] 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 --- source3/smbd/trans2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 37f578c..576e289 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4243,6 +4243,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 ab2c6f14ae0b01e10eab81baa4848c565134cd73 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 27 Aug 2013 09:40:19 +0000 Subject: [PATCH 8/9] 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 --- source3/smbd/trans2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 576e289..aaf0e62 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -5611,6 +5611,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, NT_STATUS_OK, params, param_size, *ppdata, data_size, max_data_bytes); -- 1.8.4 From f60d4595e51868b18e3fdadc2e59b60f8980e6a1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 27 Aug 2013 09:41:13 +0000 Subject: [PATCH 9/9] torture: Add buffercheck tests Make sure we get the smb2 infolevel fixed portions right I could not find correct #defines for the infolevels Bug: https://bugzilla.samba.org/show_bug.cgi?id=10106 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison --- selftest/knownfail | 3 + source4/torture/smb2/getinfo.c | 244 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 229 insertions(+), 18 deletions(-) diff --git a/selftest/knownfail b/selftest/knownfail index dd536df..6fe7ce5 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -171,6 +171,9 @@ ^samba4.smb2.oplock.batch20\(.*\)$ # samba 4 oplocks are a mess ^samba4.smb2.oplock.stream1 # samba 4 oplocks are a mess ^samba4.smb2.getinfo.complex # streams on directories does not work +^samba4.smb2.getinfo.qfs_buffercheck # S4 does not do the INFO_LENGTH_MISMATCH/BUFFER_OVERFLOW thingy +^samba4.smb2.getinfo.qfile_buffercheck # S4 does not do the INFO_LENGTH_MISMATCH/BUFFER_OVERFLOW thingy +^samba4.smb2.getinfo.qsec_buffercheck # S4 does not do the BUFFER_TOO_SMALL thingy ^samba4.ntvfs.cifs.krb5.base.createx_access.createx_access\(.*\)$ ^samba4.rpc.lsa.forest.trust #Not fully provided by Samba4 ^samba4.blackbox.kinit\(.*\).kinit with user password for expired password\(.*\) # We need to work out why this fails only during the pw change diff --git a/source4/torture/smb2/getinfo.c b/source4/torture/smb2/getinfo.c index 10dd550..fafc36c 100644 --- a/source4/torture/smb2/getinfo.c +++ b/source4/torture/smb2/getinfo.c @@ -22,9 +22,11 @@ #include "includes.h" #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" +#include "libcli/smb/smbXcli_base.h" #include "torture/torture.h" #include "torture/smb2/proto.h" +#include "torture/util.h" static struct { const char *name; @@ -154,41 +156,243 @@ static bool torture_smb2_fsinfo(struct torture_context *tctx) return true; } +static bool torture_smb2_buffercheck_err(struct torture_context *tctx, + struct smb2_tree *tree, + struct smb2_getinfo *b, + size_t fixed, + DATA_BLOB full) +{ + size_t i; -/* - test for buffer size handling -*/ -static bool torture_smb2_buffercheck(struct torture_context *tctx) + for (i=0; i<=full.length; i++) { + NTSTATUS status; + + b->in.output_buffer_length = i; + + status = smb2_getinfo(tree, tree, b); + + if (i < fixed) { + torture_assert_ntstatus_equal( + tctx, status, NT_STATUS_INFO_LENGTH_MISMATCH, + "Wrong error code small buffer"); + continue; + } + + if (iout.blob.data); + continue; + } + + torture_assert_ntstatus_equal( + tctx, status, NT_STATUS_OK, + "Wrong error code for right sized buffer"); + } + + return true; +} + +struct level_buffersize { + int level; + size_t fixed; +}; + +static bool torture_smb2_qfs_buffercheck(struct torture_context *tctx) { bool ret; struct smb2_tree *tree; NTSTATUS status; struct smb2_handle handle; - struct smb2_getinfo b; + int i; + + struct level_buffersize levels[] = { + { 1, 24 }, /* We don't have proper defines here */ + { 3, 24 }, + { 4, 8 }, + { 5, 16 }, + { 6, 48 }, + { 7, 32 }, + { 11, 28 }, + }; - printf("Testing buffer size handling\n"); + printf("Testing SMB2_GETINFO_FS buffer sizes\n"); ret = torture_smb2_connection(tctx, &tree); torture_assert(tctx, ret, "connection failed"); status = smb2_util_roothandle(tree, &handle); - torture_assert_ntstatus_ok(tctx, status, "Unable to create root handle"); + torture_assert_ntstatus_ok( + tctx, status, "Unable to create root handle"); + + for (i=0; i