smbd: implement FSCTL_SMBTORTURE_IOCTL_RESPONSE_BODY_PADDING8 as reproducer for bug...
authorStefan Metzmacher <metze@samba.org>
Thu, 14 Jan 2021 16:39:01 +0000 (17:39 +0100)
committerVolker Lendecke <vl@samba.org>
Fri, 15 Jan 2021 07:26:29 +0000 (07:26 +0000)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
selftest/knownfail.d/samba3.smb2.ioctl.bug14607 [new file with mode: 0644]
source3/smbd/smb2_ioctl.c
source3/smbd/smb2_ioctl_private.h

diff --git a/selftest/knownfail.d/samba3.smb2.ioctl.bug14607 b/selftest/knownfail.d/samba3.smb2.ioctl.bug14607
new file mode 100644 (file)
index 0000000..c535a8a
--- /dev/null
@@ -0,0 +1 @@
+^samba3.smb2.ioctl.*bug14607.nt4_dc
index 01ae6d64ac583f8bd9d53344c72337db58f31fe8..8b65a6916386b474b1ca553e8c087e9a5e11c443 100644 (file)
@@ -41,6 +41,7 @@ static struct tevent_req *smbd_smb2_ioctl_send(TALLOC_CTX *mem_ctx,
 static NTSTATUS smbd_smb2_ioctl_recv(struct tevent_req *req,
                                     TALLOC_CTX *mem_ctx,
                                     DATA_BLOB *out_output,
+                                    uint8_t *body_padding,
                                     bool *disconnect);
 
 static void smbd_smb2_request_ioctl_done(struct tevent_req *subreq);
@@ -195,6 +196,7 @@ NTSTATUS smbd_smb2_request_process_ioctl(struct smbd_smb2_request *req)
        case FSCTL_VALIDATE_NEGOTIATE_INFO:
        case FSCTL_QUERY_NETWORK_INTERFACE_INFO:
        case FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT:
+       case FSCTL_SMBTORTURE_IOCTL_RESPONSE_BODY_PADDING8:
                /*
                 * Some SMB2 specific CtlCodes like FSCTL_DFS_GET_REFERRALS or
                 * FSCTL_PIPE_WAIT does not take a file handle.
@@ -284,9 +286,12 @@ static void smbd_smb2_request_ioctl_done(struct tevent_req *subreq)
        NTSTATUS status;
        NTSTATUS error; /* transport error */
        bool disconnect = false;
+       uint16_t body_size;
+       uint8_t body_padding = 0;
 
        status = smbd_smb2_ioctl_recv(subreq, req,
                                      &out_output_buffer,
+                                     &body_padding,
                                      &disconnect);
 
        DEBUG(10,("smbd_smb2_request_ioctl_done: smbd_smb2_ioctl_recv returned "
@@ -319,10 +324,15 @@ static void smbd_smb2_request_ioctl_done(struct tevent_req *subreq)
                return;
        }
 
-       out_input_offset = SMB2_HDR_BODY + 0x30;
-       out_output_offset = SMB2_HDR_BODY + 0x30;
+       /*
+        * Only FSCTL_SMBTORTURE_IOCTL_RESPONSE_BODY_PADDING8
+        * sets body_padding to a value different from 0.
+        */
+       body_size = 0x30 + body_padding;
+       out_input_offset = SMB2_HDR_BODY + body_size;
+       out_output_offset = SMB2_HDR_BODY + body_size;
 
-       outbody = smbd_smb2_generate_outbody(req, 0x30);
+       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)) {
@@ -350,6 +360,9 @@ static void smbd_smb2_request_ioctl_done(struct tevent_req *subreq)
              out_output_buffer.length);        /* output count */
        SIVAL(outbody.data, 0x28, 0);           /* flags */
        SIVAL(outbody.data, 0x2C, 0);           /* reserved */
+       if (body_padding != 0) {
+               memset(outbody.data + 0x30, 0, body_padding);
+       }
 
        /*
         * Note: Windows Vista and 2008 send back also the
@@ -391,6 +404,26 @@ static struct tevent_req *smb2_ioctl_smbtorture(uint32_t ctl_code,
                tevent_req_done(req);
                return tevent_req_post(req, ev);
 
+       case FSCTL_SMBTORTURE_IOCTL_RESPONSE_BODY_PADDING8:
+               if (state->in_input.length != 0) {
+                       tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+                       return tevent_req_post(req, ev);
+               }
+
+               if (state->in_max_output > 0) {
+                       uint32_t size = state->in_max_output;
+
+                       state->out_output = data_blob_talloc(state, NULL, size);
+                       if (tevent_req_nomem(state->out_output.data, req)) {
+                               return tevent_req_post(req, ev);
+                       }
+                       memset(state->out_output.data, 8, size);
+               }
+
+               state->body_padding = 8;
+               tevent_req_done(req);
+               return tevent_req_post(req, ev);
+
        default:
                goto not_supported;
        }
@@ -476,6 +509,7 @@ static struct tevent_req *smbd_smb2_ioctl_send(TALLOC_CTX *mem_ctx,
 static NTSTATUS smbd_smb2_ioctl_recv(struct tevent_req *req,
                                     TALLOC_CTX *mem_ctx,
                                     DATA_BLOB *out_output,
+                                    uint8_t *body_padding,
                                     bool *disconnect)
 {
        NTSTATUS status = NT_STATUS_OK;
@@ -484,6 +518,7 @@ static NTSTATUS smbd_smb2_ioctl_recv(struct tevent_req *req,
        enum tevent_req_state req_state;
        uint64_t err;
 
+       *body_padding = state->body_padding;
        *disconnect = state->disconnect;
 
        if ((tevent_req_is_error(req, &req_state, &err) == false)
index ae07fed86066b009bcf10843a2192429dec9baea..7a35f8f5d0baa54952418312b83433bfe75694d7 100644 (file)
@@ -28,6 +28,7 @@ struct smbd_smb2_ioctl_state {
        DATA_BLOB in_input;
        uint32_t in_max_output;
        DATA_BLOB out_output;
+       uint8_t body_padding;
        bool disconnect;
 };