The branch, master has been updated
       via  0c5d0e1... Second part of fix for 7501 - SMB2: CREATE request 
replies getting mangled.
      from  fd9e02d... Fix for bug 7501 -  SMB2: CREATE request replies getting 
mangled.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 0c5d0e1c37daf5b802e990bde8469934ae33f6cc
Author: Jeremy Allison <[email protected]>
Date:   Tue Jun 8 17:44:05 2010 -0700

    Second part of fix for 7501 - SMB2: CREATE request replies getting mangled.
    
    Based on code from Ira Cooper <[email protected]>, and also
    advice on refactoring the patch into a function call. outbuf vectors
    can be reallocated by smb2 processing code, so when returning interim
    responses we must not make assumptions about vector size.
    
    Jeremy

-----------------------------------------------------------------------

Summary of changes:
 source3/smbd/smb2_server.c |  134 ++++++++++++++++++++++----------------------
 1 files changed, 67 insertions(+), 67 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 009cc77..d7be0de 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -476,23 +476,71 @@ void smbd_server_connection_terminate_ex(struct 
smbd_server_connection *sconn,
        exit_server_cleanly(reason);
 }
 
-static bool dup_smb2_vec(struct iovec *dstvec,
-                       const struct iovec *srcvec,
-                       int offset)
+static bool dup_smb2_vec3(TALLOC_CTX *ctx,
+                       struct iovec *outvec,
+                       const struct iovec *srcvec)
 {
+       /* vec[0] is always boilerplate and must
+        * be allocated with size OUTVEC_ALLOC_SIZE. */
 
-       if (srcvec[offset].iov_len &&
-                       srcvec[offset].iov_base) {
-               dstvec[offset].iov_base = talloc_memdup(dstvec,
-                                       srcvec[offset].iov_base,
-                                       srcvec[offset].iov_len);
-               if (!dstvec[offset].iov_base) {
+       outvec[0].iov_base = talloc_memdup(ctx,
+                               srcvec[0].iov_base,
+                               OUTVEC_ALLOC_SIZE);
+       if (!outvec[0].iov_base) {
+               return false;
+       }
+       outvec[0].iov_len = SMB2_HDR_BODY;
+
+       /*
+        * If this is a "standard" vec[1] of length 8,
+        * pointing to srcvec[0].iov_base + SMB2_HDR_BODY,
+        * then duplicate this. Else use talloc_memdup().
+        */
+
+       if (srcvec[1].iov_len == 8 &&
+                       srcvec[1].iov_base ==
+                               ((uint8_t *)srcvec[0].iov_base) +
+                                       SMB2_HDR_BODY) {
+               outvec[1].iov_base = ((uint8_t *)outvec[1].iov_base) +
+                                       SMB2_HDR_BODY;
+               outvec[1].iov_len = 8;
+       } else {
+               outvec[1].iov_base = talloc_memdup(ctx,
+                               srcvec[1].iov_base,
+                               srcvec[1].iov_len);
+               if (!outvec[1].iov_base) {
                        return false;
                }
-               dstvec[offset].iov_len = srcvec[offset].iov_len;
+               outvec[1].iov_len = srcvec[1].iov_len;
+       }
+
+       /*
+        * If this is a "standard" vec[2] of length 1,
+        * pointing to srcvec[0].iov_base + (OUTVEC_ALLOC_SIZE - 1)
+        * then duplicate this. Else use talloc_memdup().
+        */
+
+       if (srcvec[2].iov_base &&
+                       srcvec[2].iov_len) {
+               if (srcvec[2].iov_base ==
+                               ((uint8_t *)srcvec[0].iov_base) +
+                                       (OUTVEC_ALLOC_SIZE - 1) &&
+                               srcvec[2].iov_len == 1) {
+                       /* Common SMB2 error packet case. */
+                       outvec[2].iov_base = ((uint8_t *)outvec[0].iov_base) +
+                               (OUTVEC_ALLOC_SIZE - 1);
+               } else {
+                       outvec[2].iov_base = talloc_memdup(ctx,
+                                       srcvec[2].iov_base,
+                                       srcvec[2].iov_len);
+                       if (!outvec[2].iov_base) {
+                               return false;
+                       }
+               }
+               outvec[2].iov_len = srcvec[2].iov_len;
        } else {
-               dstvec[offset].iov_base = NULL;
-               dstvec[offset].iov_len = 0;
+               outvec[2].iov_base = NULL;
+               outvec[2].iov_len = 0;
        }
        return true;
 }
@@ -528,30 +576,9 @@ static struct smbd_smb2_request *dup_smb2_req(const struct 
smbd_smb2_request *re
        outvec[0].iov_len = 4;
        memcpy(newreq->out.nbt_hdr, req->out.nbt_hdr, 4);
 
+       /* Setup the vectors identically to the ones in req. */
        for (i = 1; i < count; i += 3) {
-               /* i + 0 and i + 1 are always
-                * boilerplate. */
-               outvec[i].iov_base = talloc_memdup(outvec,
-                                               req->out.vector[i].iov_base,
-                                               OUTVEC_ALLOC_SIZE);
-               if (!outvec[i].iov_base) {
-                       break;
-               }
-               outvec[i].iov_len = SMB2_HDR_BODY;
-
-               outvec[i+1].iov_base = ((uint8_t *)outvec[i].iov_base) +
-                                               SMB2_HDR_BODY;
-               outvec[i+1].iov_len = 8;
-
-               if (req->out.vector[i+2].iov_base ==
-                               ((uint8_t *)req->out.vector[i].iov_base) +
-                                       (OUTVEC_ALLOC_SIZE - 1) &&
-                               req->out.vector[i+2].iov_len == 1) {
-                       /* Common SMB2 error packet case. */
-                       outvec[i+2].iov_base = ((uint8_t *)outvec[i].iov_base) +
-                               (OUTVEC_ALLOC_SIZE - 1);
-                       outvec[i+2].iov_len = 1;
-               } else if (!dup_smb2_vec(outvec, req->out.vector, i+2)) {
+               if (!dup_smb2_vec3(outvec, &outvec[i], &req->out.vector[i])) {
                        break;
                }
        }
@@ -821,44 +848,17 @@ NTSTATUS smbd_smb2_request_pending_queue(struct 
smbd_smb2_request *req,
        if (!outvec) {
                return NT_STATUS_NO_MEMORY;
        }
+
+       /* 0 is always boilerplate and must
+        * be of size 4 for the length field. */
+
        outvec[0].iov_base = req->out.nbt_hdr;
        outvec[0].iov_len = 4;
        SIVAL(req->out.nbt_hdr, 0, 0);
 
-       outvec[1].iov_base = talloc_memdup(outvec,
-                               req->out.vector[i].iov_base,
-                               OUTVEC_ALLOC_SIZE);
-       if (!outvec[1].iov_base) {
+       if (!dup_smb2_vec3(outvec, &outvec[1], &req->out.vector[i])) {
                return NT_STATUS_NO_MEMORY;
        }
-       outvec[1].iov_len = SMB2_HDR_BODY;
-
-       outvec[2].iov_base = ((uint8_t *)outvec[1].iov_base) +
-                               SMB2_HDR_BODY;
-       outvec[2].iov_len = 8;
-
-       if (req->out.vector[i+2].iov_base &&
-                       req->out.vector[i+2].iov_len) {
-               if (req->out.vector[i+2].iov_base ==
-                               ((uint8_t *)req->out.vector[i].iov_base) +
-                                       (OUTVEC_ALLOC_SIZE - 1) &&
-                               req->out.vector[i].iov_len == 1) {
-                       /* Common SMB2 error packet case. */
-                       outvec[3].iov_base = ((uint8_t *)outvec[1].iov_base) +
-                               (OUTVEC_ALLOC_SIZE - 1);
-               } else {
-                       outvec[3].iov_base = talloc_memdup(outvec,
-                                       req->out.vector[i+2].iov_base,
-                                       req->out.vector[i+2].iov_len);
-                       if (!outvec[3].iov_base) {
-                               return NT_STATUS_NO_MEMORY;
-                       }
-               }
-               outvec[3].iov_len = req->out.vector[i+2].iov_len;
-       } else {
-               outvec[3].iov_base = NULL;
-               outvec[3].iov_len = 0;
-       }
 
        TALLOC_FREE(req->out.vector);
 


-- 
Samba Shared Repository

Reply via email to