The Samba-Bugzilla – Attachment 16685 Details for
Bug 14607
tree connect failed: NT_STATUS_INVALID_PARAMETER
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
Additional patches for v4-15-test
tmp415.diff.txt (text/plain), 23.15 KB, created by
Stefan Metzmacher
on 2021-07-16 12:54:58 UTC
(
hide
)
Description:
Additional patches for v4-15-test
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2021-07-16 12:54:58 UTC
Size:
23.15 KB
patch
obsolete
>From a6a80e46282ee284396b60defff32215d34ee197 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 6 Jul 2021 16:24:59 +0200 >Subject: [PATCH 1/5] s4:torture/smb2: add smb2.read.bug14607 test > >This test will use a FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8 >in order to change the server behavior of READ responses regarding >the data offset. > >It will demonstrate the problem in smb2cli_read*() triggered >by NetApp Ontap servers. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit b3c9823d907b91632679e6f0ffce1b7192e4b9b6) >--- > libcli/smb/smb_constants.h | 2 + > source4/torture/smb2/read.c | 136 ++++++++++++++++++++++++++++++++++++ > 2 files changed, 138 insertions(+) > >diff --git a/libcli/smb/smb_constants.h b/libcli/smb/smb_constants.h >index e58e5f35f25f..a12086e602ba 100644 >--- a/libcli/smb/smb_constants.h >+++ b/libcli/smb/smb_constants.h >@@ -597,6 +597,8 @@ enum csc_policy { > (FSCTL_SMBTORTURE | FSCTL_ACCESS_WRITE | 0x0000 | FSCTL_METHOD_NEITHER) > #define FSCTL_SMBTORTURE_IOCTL_RESPONSE_BODY_PADDING8 \ > (FSCTL_SMBTORTURE | FSCTL_ACCESS_WRITE | 0x0010 | FSCTL_METHOD_NEITHER) >+#define FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8 \ >+ (FSCTL_SMBTORTURE | FSCTL_ACCESS_WRITE | 0x0020 | FSCTL_METHOD_NEITHER) > > /* > * A few values from [MS-FSCC] 2.1.2.1 Reparse Tags >diff --git a/source4/torture/smb2/read.c b/source4/torture/smb2/read.c >index 2899a491663b..2bc0dc98bbac 100644 >--- a/source4/torture/smb2/read.c >+++ b/source4/torture/smb2/read.c >@@ -26,6 +26,8 @@ > > #include "torture/torture.h" > #include "torture/smb2/proto.h" >+#include "../libcli/smb/smbXcli_base.h" >+#include "librpc/gen_ndr/ndr_ioctl.h" > > > #define CHECK_STATUS(_status, _expected) \ >@@ -303,6 +305,138 @@ done: > return ret; > } > >+/* >+ basic regression test for BUG 14607 >+ https://bugzilla.samba.org/show_bug.cgi?id=14607 >+*/ >+static bool test_read_bug14607(struct torture_context *torture, >+ struct smb2_tree *tree) >+{ >+ bool ret = true; >+ NTSTATUS status; >+ struct smb2_handle h; >+ uint8_t buf[64 * 1024]; >+ struct smb2_read rd; >+ uint32_t timeout_msec; >+ DATA_BLOB out_input_buffer = data_blob_null; >+ DATA_BLOB out_output_buffer = data_blob_null; >+ TALLOC_CTX *tmp_ctx = talloc_new(tree); >+ uint8_t *data = NULL; >+ uint32_t data_length = 0; >+ >+ memset(buf, 0x1f, ARRAY_SIZE(buf)); >+ >+ /* create a file */ >+ smb2_util_unlink(tree, FNAME); >+ >+ status = torture_smb2_testfile(tree, FNAME, &h); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf)); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ ZERO_STRUCT(rd); >+ rd.in.file.handle = h; >+ rd.in.length = ARRAY_SIZE(buf); >+ rd.in.offset = 0; >+ status = smb2_read(tree, tree, &rd); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ CHECK_VALUE(rd.out.data.length, ARRAY_SIZE(buf)); >+ torture_assert_mem_equal_goto(torture, rd.out.data.data, >+ buf, ARRAY_SIZE(buf), >+ ret, done, >+ "Invalid content smb2_read"); >+ >+ timeout_msec = tree->session->transport->options.request_timeout * 1000; >+ >+ status = smb2cli_read(tree->session->transport->conn, >+ timeout_msec, >+ tree->session->smbXcli, >+ tree->smbXcli, >+ rd.in.length, >+ rd.in.offset, >+ h.data[0], >+ h.data[1], >+ rd.in.min_count, >+ rd.in.remaining, >+ tmp_ctx, >+ &data, &data_length); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ CHECK_VALUE(data_length, ARRAY_SIZE(buf)); >+ torture_assert_mem_equal_goto(torture, data, >+ buf, ARRAY_SIZE(buf), >+ ret, done, >+ "Invalid content smb2cli_read"); >+ >+ status = smb2cli_ioctl(tree->session->transport->conn, >+ timeout_msec, >+ tree->session->smbXcli, >+ tree->smbXcli, >+ UINT64_MAX, /* in_fid_persistent */ >+ UINT64_MAX, /* in_fid_volatile */ >+ FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8, >+ 0, /* in_max_input_length */ >+ NULL, /* in_input_buffer */ >+ 1, /* in_max_output_length */ >+ NULL, /* in_output_buffer */ >+ SMB2_IOCTL_FLAG_IS_FSCTL, >+ tmp_ctx, >+ &out_input_buffer, >+ &out_output_buffer); >+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED) || >+ NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) || >+ NT_STATUS_EQUAL(status, NT_STATUS_FS_DRIVER_REQUIRED) || >+ NT_STATUS_EQUAL(status, NT_STATUS_INVALID_DEVICE_REQUEST)) >+ { >+ torture_comment(torture, >+ "FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8: %s\n", >+ nt_errstr(status)); >+ torture_skip(torture, "server doesn't support FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8\n"); >+ } >+ torture_assert_ntstatus_ok(torture, status, "FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8"); >+ >+ torture_assert_int_equal(torture, out_output_buffer.length, 0, >+ "output length"); >+ >+ ZERO_STRUCT(rd); >+ rd.in.file.handle = h; >+ rd.in.length = ARRAY_SIZE(buf); >+ rd.in.offset = 0; >+ status = smb2_read(tree, tree, &rd); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ CHECK_VALUE(rd.out.data.length, ARRAY_SIZE(buf)); >+ torture_assert_mem_equal_goto(torture, rd.out.data.data, >+ buf, ARRAY_SIZE(buf), >+ ret, done, >+ "Invalid content after padding smb2_read"); >+ >+ status = smb2cli_read(tree->session->transport->conn, >+ timeout_msec, >+ tree->session->smbXcli, >+ tree->smbXcli, >+ rd.in.length, >+ rd.in.offset, >+ h.data[0], >+ h.data[1], >+ rd.in.min_count, >+ rd.in.remaining, >+ tmp_ctx, >+ &data, &data_length); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ CHECK_VALUE(data_length, ARRAY_SIZE(buf)); >+ torture_assert_mem_equal_goto(torture, data, >+ buf, ARRAY_SIZE(buf), >+ ret, done, >+ "Invalid content after padding smb2cli_read"); >+ >+ status = smb2_util_close(tree, h); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+done: >+ talloc_free(tmp_ctx); >+ return ret; >+} >+ > /* > basic testing of SMB2 read > */ >@@ -314,6 +448,8 @@ struct torture_suite *torture_smb2_read_init(TALLOC_CTX *ctx) > torture_suite_add_1smb2_test(suite, "position", test_read_position); > torture_suite_add_1smb2_test(suite, "dir", test_read_dir); > torture_suite_add_1smb2_test(suite, "access", test_read_access); >+ torture_suite_add_1smb2_test(suite, "bug14607", >+ test_read_bug14607); > > suite->description = talloc_strdup(suite, "SMB2-READ tests"); > >-- >2.25.1 > > >From db1826714d1a08c73d443517f8c80ce5fae89bf5 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 5 Jul 2021 17:49:00 +0200 >Subject: [PATCH 2/5] s3:smbd: introduce a body_size variable in > smbd_smb2_request_read_done > >This will simplify the following changes. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 5ecac656fde4e81aa6e51e7b3134ea3fb75f564a) >--- > source3/smbd/smb2_read.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > >diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c >index cd590a52c951..8372188f58d7 100644 >--- a/source3/smbd/smb2_read.c >+++ b/source3/smbd/smb2_read.c >@@ -116,6 +116,7 @@ static void smbd_smb2_request_read_done(struct tevent_req *subreq) > { > struct smbd_smb2_request *req = tevent_req_callback_data(subreq, > struct smbd_smb2_request); >+ uint16_t body_size; > DATA_BLOB outbody; > DATA_BLOB outdyn; > uint8_t out_data_offset; >@@ -139,9 +140,10 @@ static void smbd_smb2_request_read_done(struct tevent_req *subreq) > return; > } > >- out_data_offset = SMB2_HDR_BODY + 0x10; >+ body_size = 0x10; >+ out_data_offset = SMB2_HDR_BODY + body_size; > >- outbody = smbd_smb2_generate_outbody(req, 0x10); >+ outbody = smbd_smb2_generate_outbody(req, body_size); > if (outbody.data == NULL) { > error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); > if (!NT_STATUS_IS_OK(error)) { >-- >2.25.1 > > >From 0007c01a639e60e2ba47125695a9392c67382592 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 5 Jul 2021 17:49:00 +0200 >Subject: [PATCH 3/5] s3:smbd: implement > FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8 > >This turns the 'smb2.read.bug14607' test from 'skip' into 'xfailure', >as the 2nd smb2cli_read() function will now return >NT_STATUS_INVALID_NETWORK_RESPONSE. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit ef57fba5dbf359b204ba952451e1e33ed68f1c91) >--- > selftest/knownfail.d/smb2-read-bug14607 | 1 + > source3/smbd/globals.h | 4 ++++ > source3/smbd/smb2_ioctl.c | 10 ++++++++++ > source3/smbd/smb2_read.c | 10 +++++++++- > 4 files changed, 24 insertions(+), 1 deletion(-) > create mode 100644 selftest/knownfail.d/smb2-read-bug14607 > >diff --git a/selftest/knownfail.d/smb2-read-bug14607 b/selftest/knownfail.d/smb2-read-bug14607 >new file mode 100644 >index 000000000000..05b8adfa8cd9 >--- /dev/null >+++ b/selftest/knownfail.d/smb2-read-bug14607 >@@ -0,0 +1 @@ >+samba3.smb2.read.bug14607 >diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h >index e1a520c1977b..3215a5a8c2ea 100644 >--- a/source3/smbd/globals.h >+++ b/source3/smbd/globals.h >@@ -538,6 +538,10 @@ struct smbXsrv_connection { > struct smbXsrv_preauth preauth; > > struct smbd_smb2_request *requests; >+ >+ struct { >+ uint8_t read_body_padding; >+ } smbtorture; > } smb2; > }; > >diff --git a/source3/smbd/smb2_ioctl.c b/source3/smbd/smb2_ioctl.c >index 8b65a6916386..d29ff5d0303b 100644 >--- a/source3/smbd/smb2_ioctl.c >+++ b/source3/smbd/smb2_ioctl.c >@@ -197,6 +197,7 @@ NTSTATUS smbd_smb2_request_process_ioctl(struct smbd_smb2_request *req) > case FSCTL_QUERY_NETWORK_INTERFACE_INFO: > case FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT: > case FSCTL_SMBTORTURE_IOCTL_RESPONSE_BODY_PADDING8: >+ case FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8: > /* > * Some SMB2 specific CtlCodes like FSCTL_DFS_GET_REFERRALS or > * FSCTL_PIPE_WAIT does not take a file handle. >@@ -424,6 +425,15 @@ static struct tevent_req *smb2_ioctl_smbtorture(uint32_t ctl_code, > tevent_req_done(req); > return tevent_req_post(req, ev); > >+ case FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8: >+ if (state->in_input.length != 0) { >+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); >+ return tevent_req_post(req, ev); >+ } >+ >+ state->smb2req->xconn->smb2.smbtorture.read_body_padding = 8; >+ tevent_req_done(req); >+ return tevent_req_post(req, ev); > default: > goto not_supported; > } >diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c >index 8372188f58d7..a846215b0eca 100644 >--- a/source3/smbd/smb2_read.c >+++ b/source3/smbd/smb2_read.c >@@ -117,6 +117,7 @@ static void smbd_smb2_request_read_done(struct tevent_req *subreq) > struct smbd_smb2_request *req = tevent_req_callback_data(subreq, > struct smbd_smb2_request); > uint16_t body_size; >+ uint8_t body_padding = req->xconn->smb2.smbtorture.read_body_padding; > DATA_BLOB outbody; > DATA_BLOB outdyn; > uint8_t out_data_offset; >@@ -140,7 +141,11 @@ static void smbd_smb2_request_read_done(struct tevent_req *subreq) > return; > } > >- body_size = 0x10; >+ /* >+ * Only FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8 >+ * sets body_padding to a value different from 0. >+ */ >+ body_size = 0x10 + body_padding; > out_data_offset = SMB2_HDR_BODY + body_size; > > outbody = smbd_smb2_generate_outbody(req, body_size); >@@ -163,6 +168,9 @@ static void smbd_smb2_request_read_done(struct tevent_req *subreq) > SIVAL(outbody.data, 0x08, > out_data_remaining); /* data remaining */ > SIVAL(outbody.data, 0x0C, 0); /* reserved */ >+ if (body_padding != 0) { >+ memset(outbody.data + 0x10, 0, body_padding); >+ } > > outdyn = out_data_buffer; > >-- >2.25.1 > > >From 27294cdf8735a137e709628af5f6bced843b2087 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 29 Jun 2021 15:24:13 +0200 >Subject: [PATCH 4/5] libcli/smb: make smb2cli_ioctl_parse_buffer() available > as smb2cli_parse_dyn_buffer() > >It will be used in smb2cli_read.c soon... > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 1faf15b3d0f41fa8a94b76d1616a4460ce0c6fa4) >--- > libcli/smb/smb2cli_ioctl.c | 123 +++++-------------------------------- > libcli/smb/smbXcli_base.c | 91 +++++++++++++++++++++++++++ > libcli/smb/smbXcli_base.h | 9 +++ > 3 files changed, 116 insertions(+), 107 deletions(-) > >diff --git a/libcli/smb/smb2cli_ioctl.c b/libcli/smb/smb2cli_ioctl.c >index f9abcc57bab3..d638b2816780 100644 >--- a/libcli/smb/smb2cli_ioctl.c >+++ b/libcli/smb/smb2cli_ioctl.c >@@ -160,97 +160,6 @@ struct tevent_req *smb2cli_ioctl_send(TALLOC_CTX *mem_ctx, > return req; > } > >-static NTSTATUS smb2cli_ioctl_parse_buffer(uint32_t dyn_offset, >- const DATA_BLOB dyn_buffer, >- uint32_t min_offset, >- uint32_t buffer_offset, >- uint32_t buffer_length, >- uint32_t max_length, >- uint32_t *next_offset, >- DATA_BLOB *buffer) >-{ >- uint32_t offset; >- bool oob; >- >- *buffer = data_blob_null; >- *next_offset = dyn_offset; >- >- if (buffer_offset == 0) { >- /* >- * If the offset is 0, we better ignore >- * the buffer_length field. >- */ >- return NT_STATUS_OK; >- } >- >- if (buffer_length == 0) { >- /* >- * If the length is 0, we better ignore >- * the buffer_offset field. >- */ >- return NT_STATUS_OK; >- } >- >- if ((buffer_offset % 8) != 0) { >- /* >- * The offset needs to be 8 byte aligned. >- */ >- return NT_STATUS_INVALID_NETWORK_RESPONSE; >- } >- >- /* >- * We used to enforce buffer_offset to be >- * an exact match of the expected minimum, >- * but the NetApp Ontap 7.3.7 SMB server >- * gets the padding wrong and aligns the >- * input_buffer_offset by a value of 8. >- * >- * So we just enforce that the offset is >- * not lower than the expected value. >- */ >- SMB_ASSERT(min_offset >= dyn_offset); >- if (buffer_offset < min_offset) { >- return NT_STATUS_INVALID_NETWORK_RESPONSE; >- } >- >- /* >- * Make [input|output]_buffer_offset relative to "dyn_buffer" >- */ >- offset = buffer_offset - dyn_offset; >- oob = smb_buffer_oob(dyn_buffer.length, offset, buffer_length); >- if (oob) { >- return NT_STATUS_INVALID_NETWORK_RESPONSE; >- } >- >- /* >- * Give the caller a hint what we consumed, >- * the caller may need to add possible padding. >- */ >- *next_offset = buffer_offset + buffer_length; >- >- if (max_length == 0) { >- /* >- * If max_input_length is 0 we ignore the >- * input_buffer_length, because Windows 2008 echos the >- * DCERPC request from the requested input_buffer to >- * the response input_buffer. >- * >- * We just use the same logic also for max_output_length... >- */ >- buffer_length = 0; >- } >- >- if (buffer_length > max_length) { >- return NT_STATUS_INVALID_NETWORK_RESPONSE; >- } >- >- *buffer = (DATA_BLOB) { >- .data = dyn_buffer.data + offset, >- .length = buffer_length, >- }; >- return NT_STATUS_OK; >-} >- > static void smb2cli_ioctl_done(struct tevent_req *subreq) > { > struct tevent_req *req = >@@ -352,14 +261,14 @@ static void smb2cli_ioctl_done(struct tevent_req *subreq) > > input_min_offset = dyn_ofs; > input_next_offset = dyn_ofs; >- error = smb2cli_ioctl_parse_buffer(dyn_ofs, >- dyn_buffer, >- input_min_offset, >- input_buffer_offset, >- input_buffer_length, >- state->max_input_length, >- &input_next_offset, >- &state->out_input_buffer); >+ error = smb2cli_parse_dyn_buffer(dyn_ofs, >+ dyn_buffer, >+ input_min_offset, >+ input_buffer_offset, >+ input_buffer_length, >+ state->max_input_length, >+ &input_next_offset, >+ &state->out_input_buffer); > if (tevent_req_nterror(req, error)) { > return; > } >@@ -370,14 +279,14 @@ static void smb2cli_ioctl_done(struct tevent_req *subreq) > */ > output_min_offset = NDR_ROUND(input_next_offset, 8); > output_next_offset = 0; /* this variable is completely ignored */ >- error = smb2cli_ioctl_parse_buffer(dyn_ofs, >- dyn_buffer, >- output_min_offset, >- output_buffer_offset, >- output_buffer_length, >- state->max_output_length, >- &output_next_offset, >- &state->out_output_buffer); >+ error = smb2cli_parse_dyn_buffer(dyn_ofs, >+ dyn_buffer, >+ output_min_offset, >+ output_buffer_offset, >+ output_buffer_length, >+ state->max_output_length, >+ &output_next_offset, >+ &state->out_output_buffer); > if (tevent_req_nterror(req, error)) { > return; > } >diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c >index 341a371d8b81..3fb51e33ffe3 100644 >--- a/libcli/smb/smbXcli_base.c >+++ b/libcli/smb/smbXcli_base.c >@@ -6823,3 +6823,94 @@ uint64_t smb2cli_conn_get_mid(struct smbXcli_conn *conn) > { > return conn->smb2.mid; > } >+ >+NTSTATUS smb2cli_parse_dyn_buffer(uint32_t dyn_offset, >+ const DATA_BLOB dyn_buffer, >+ uint32_t min_offset, >+ uint32_t buffer_offset, >+ uint32_t buffer_length, >+ uint32_t max_length, >+ uint32_t *next_offset, >+ DATA_BLOB *buffer) >+{ >+ uint32_t offset; >+ bool oob; >+ >+ *buffer = data_blob_null; >+ *next_offset = dyn_offset; >+ >+ if (buffer_offset == 0) { >+ /* >+ * If the offset is 0, we better ignore >+ * the buffer_length field. >+ */ >+ return NT_STATUS_OK; >+ } >+ >+ if (buffer_length == 0) { >+ /* >+ * If the length is 0, we better ignore >+ * the buffer_offset field. >+ */ >+ return NT_STATUS_OK; >+ } >+ >+ if ((buffer_offset % 8) != 0) { >+ /* >+ * The offset needs to be 8 byte aligned. >+ */ >+ return NT_STATUS_INVALID_NETWORK_RESPONSE; >+ } >+ >+ /* >+ * We used to enforce buffer_offset to be >+ * an exact match of the expected minimum, >+ * but the NetApp Ontap 7.3.7 SMB server >+ * gets the padding wrong and aligns the >+ * input_buffer_offset by a value of 8. >+ * >+ * So we just enforce that the offset is >+ * not lower than the expected value. >+ */ >+ SMB_ASSERT(min_offset >= dyn_offset); >+ if (buffer_offset < min_offset) { >+ return NT_STATUS_INVALID_NETWORK_RESPONSE; >+ } >+ >+ /* >+ * Make [input|output]_buffer_offset relative to "dyn_buffer" >+ */ >+ offset = buffer_offset - dyn_offset; >+ oob = smb_buffer_oob(dyn_buffer.length, offset, buffer_length); >+ if (oob) { >+ return NT_STATUS_INVALID_NETWORK_RESPONSE; >+ } >+ >+ /* >+ * Give the caller a hint what we consumed, >+ * the caller may need to add possible padding. >+ */ >+ *next_offset = buffer_offset + buffer_length; >+ >+ if (max_length == 0) { >+ /* >+ * If max_input_length is 0 we ignore the >+ * input_buffer_length, because Windows 2008 echos the >+ * DCERPC request from the requested input_buffer to >+ * the response input_buffer. >+ * >+ * We just use the same logic also for max_output_length... >+ */ >+ buffer_length = 0; >+ } >+ >+ if (buffer_length > max_length) { >+ return NT_STATUS_INVALID_NETWORK_RESPONSE; >+ } >+ >+ *buffer = (DATA_BLOB) { >+ .data = dyn_buffer.data + offset, >+ .length = buffer_length, >+ }; >+ return NT_STATUS_OK; >+} >diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h >index 6914e11156b0..136e0e0111aa 100644 >--- a/libcli/smb/smbXcli_base.h >+++ b/libcli/smb/smbXcli_base.h >@@ -395,6 +395,15 @@ void smb2cli_conn_set_cc_max_chunks(struct smbXcli_conn *conn, > void smb2cli_conn_set_mid(struct smbXcli_conn *conn, uint64_t mid); > uint64_t smb2cli_conn_get_mid(struct smbXcli_conn *conn); > >+NTSTATUS smb2cli_parse_dyn_buffer(uint32_t dyn_offset, >+ const DATA_BLOB dyn_buffer, >+ uint32_t min_offset, >+ uint32_t buffer_offset, >+ uint32_t buffer_length, >+ uint32_t max_length, >+ uint32_t *next_offset, >+ DATA_BLOB *buffer); >+ > struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx, > struct tevent_context *ev, > struct smbXcli_conn *conn, >-- >2.25.1 > > >From d2635c612ff2e12b92c04bf6a5bf4cb609ecf3a7 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 29 Jun 2021 15:42:56 +0200 >Subject: [PATCH 5/5] libcli/smb: allow unexpected padding in SMB2 READ > responses > >Make use of smb2cli_parse_dyn_buffer() in smb2cli_read_done() >as it was exactly introduced for a similar problem see: > > commit 4c6c71e1378401d66bf2ed230544a75f7b04376f > Author: Stefan Metzmacher <metze@samba.org> > AuthorDate: Thu Jan 14 17:32:15 2021 +0100 > Commit: Volker Lendecke <vl@samba.org> > CommitDate: Fri Jan 15 08:36:34 2021 +0000 > > libcli/smb: allow unexpected padding in SMB2 IOCTL responses > > A NetApp Ontap 7.3.7 SMB server add 8 padding bytes to an > offset that's already 8 byte aligned. > > RN: Work around special SMB2 IOCTL response behavior of NetApp Ontap 7.3.7 > BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607 > > Pair-Programmed-With: Volker Lendecke <vl@samba.org> > > Signed-off-by: Stefan Metzmacher <metze@samba.org> > Signed-off-by: Volker Lendecke <vl@samba.org> > > Autobuild-User(master): Volker Lendecke <vl@samba.org> > Autobuild-Date(master): Fri Jan 15 08:36:34 UTC 2021 on sn-devel-184 > >RN: Work around special SMB2 READ response behavior of NetApp Ontap 7.3.7 >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Thu Jul 15 23:53:55 UTC 2021 on sn-devel-184 > >(cherry picked from commit 155348cda65b441a6c4db1ed84dbf1682d02973c) >--- > libcli/smb/smb2cli_read.c | 22 ++++++++++++++++++---- > selftest/knownfail.d/smb2-read-bug14607 | 1 - > 2 files changed, 18 insertions(+), 5 deletions(-) > delete mode 100644 selftest/knownfail.d/smb2-read-bug14607 > >diff --git a/libcli/smb/smb2cli_read.c b/libcli/smb/smb2cli_read.c >index 8110b65d4322..c7f48741b875 100644 >--- a/libcli/smb/smb2cli_read.c >+++ b/libcli/smb/smb2cli_read.c >@@ -90,8 +90,13 @@ static void smb2cli_read_done(struct tevent_req *subreq) > tevent_req_data(req, > struct smb2cli_read_state); > NTSTATUS status; >+ NTSTATUS error; > struct iovec *iov; >+ const uint8_t dyn_ofs = SMB2_HDR_BODY + 0x10; >+ DATA_BLOB dyn_buffer = data_blob_null; > uint8_t data_offset; >+ DATA_BLOB data_buffer = data_blob_null; >+ uint32_t next_offset = 0; /* this variable is completely ignored */ > static const struct smb2cli_req_expected_response expected[] = { > { > .status = STATUS_BUFFER_OVERFLOW, >@@ -117,14 +122,23 @@ static void smb2cli_read_done(struct tevent_req *subreq) > data_offset = CVAL(iov[1].iov_base, 2); > state->data_length = IVAL(iov[1].iov_base, 4); > >- if ((data_offset != SMB2_HDR_BODY + 16) || >- (state->data_length > iov[2].iov_len)) { >- tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); >+ dyn_buffer = data_blob_const((uint8_t *)iov[2].iov_base, >+ iov[2].iov_len); >+ >+ error = smb2cli_parse_dyn_buffer(dyn_ofs, >+ dyn_buffer, >+ dyn_ofs, /* min_offset */ >+ data_offset, >+ state->data_length, >+ dyn_buffer.length, /* max_length */ >+ &next_offset, >+ &data_buffer); >+ if (tevent_req_nterror(req, error)) { > return; > } > > state->recv_iov = iov; >- state->data = (uint8_t *)iov[2].iov_base; >+ state->data = data_buffer.data; > > state->out_valid = true; > >diff --git a/selftest/knownfail.d/smb2-read-bug14607 b/selftest/knownfail.d/smb2-read-bug14607 >deleted file mode 100644 >index 05b8adfa8cd9..000000000000 >--- a/selftest/knownfail.d/smb2-read-bug14607 >+++ /dev/null >@@ -1 +0,0 @@ >-samba3.smb2.read.bug14607 >-- >2.25.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
jra
:
review+
Actions:
View
Attachments on
bug 14607
:
16374
|
16376
|
16377
|
16398
|
16399
|
16683
|
16684
| 16685 |
16686