Attempt to fix bug #7399 - SMB2: QUERY_DIRECTORY is returning invalid values.
authorJeremy Allison <jra@samba.org>
Thu, 29 Apr 2010 20:40:25 +0000 (13:40 -0700)
committerJeremy Allison <jra@samba.org>
Thu, 29 Apr 2010 20:40:25 +0000 (13:40 -0700)
Based on an initial patch from Ira Cooper <samba@ira.wakeful.net>.

Jeremy.

source3/smbd/smb2_find.c
source3/smbd/trans2.c

index 546aed8db3eaee806df09c91cde531b38fef2cc1..66be7562e8734f83749ee7f43d36d163017298f8 100644 (file)
@@ -89,6 +89,17 @@ NTSTATUS smbd_smb2_request_process_find(struct smbd_smb2_request *req)
                return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
        }
 
+       /* The output header is 8 bytes. */
+       if (in_output_buffer_length <= 8) {
+               return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+       }
+
+       DEBUG(10,("smbd_smb2_request_find_done: in_output_buffer_length = %u\n",
+               (unsigned int)in_output_buffer_length ));
+
+       /* Take into account the output header. */
+       in_output_buffer_length -= 8;
+
        in_file_name_buffer.data = (uint8_t *)req->in.vector[i+2].iov_base;
        in_file_name_buffer.length = in_file_name_length;
 
@@ -172,6 +183,9 @@ static void smbd_smb2_request_find_done(struct tevent_req *subreq)
        SIVAL(outbody.data, 0x04,
              out_output_buffer.length);        /* output buffer length */
 
+       DEBUG(10,("smbd_smb2_request_find_done: out_output_buffer.length = %u\n",
+               (unsigned int)out_output_buffer.length ));
+
        outdyn = out_output_buffer;
 
        error = smbd_smb2_request_done(req, outbody, &outdyn);
@@ -210,7 +224,7 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
        char *base_data;
        char *end_data;
        int last_entry_off = 0;
-       uint64_t off = 0;
+       int off = 0;
        uint32_t num = 0;
        uint32_t dirtype = aHIDDEN | aSYSTEM | aDIR;
        const char *directory;
@@ -364,8 +378,10 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
        off = 0;
        num = 0;
 
-       DEBUG(8,("smbd_smb2_find_send: dirpath=<%s> dontdescend=<%s>\n",
-               directory, lp_dontdescend(SNUM(conn))));
+       DEBUG(8,("smbd_smb2_find_send: dirpath=<%s> dontdescend=<%s>, "
+               "in_output_buffer_length = %u\n",
+               directory, lp_dontdescend(SNUM(conn)),
+               (unsigned int)in_output_buffer_length ));
        if (in_list(directory,lp_dontdescend(SNUM(conn)),conn->case_sensitive)) {
                dont_descend = true;
        }
@@ -380,6 +396,8 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
                bool out_of_space = false;
                int space_remaining = in_output_buffer_length - off;
 
+               SMB_ASSERT(space_remaining >= 0);
+
                ok = smbd_dirptr_lanman2_entry(state,
                                               conn,
                                               fsp->dptr,
@@ -401,7 +419,7 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
                                               &last_entry_off,
                                               NULL);
 
-               off = PTR_DIFF(pdata, base_data);
+               off = (int)PTR_DIFF(pdata, base_data);
 
                if (!ok) {
                        if (num > 0) {
index 4dff67347b22a709538ad586064a8414f09309da..102b41f91aa34868cfcbb084b7aa5e0c639e0d99 100644 (file)
@@ -1464,7 +1464,7 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
                                    uint32_t mode,
                                    const char *fname,
                                    const struct smb_filename *smb_fname,
-                                   uint64_t space_remaining,
+                                   int space_remaining,
                                    uint8_t align,
                                    bool do_pad,
                                    char *base_data,
@@ -1484,8 +1484,8 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
        char *nameptr;
        char *last_entry_ptr;
        bool was_8_3;
-       off_t off;
-       off_t pad = 0;
+       int off;
+       int pad = 0;
 
        *out_of_space = false;
 
@@ -1517,7 +1517,9 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
        c_date = convert_timespec_to_time_t(cdate_ts);
 
        /* align the record */
-       off = PTR_DIFF(pdata, base_data);
+       SMB_ASSERT(align >= 1);
+
+       off = (int)PTR_DIFF(pdata, base_data);
        pad = (off + (align-1)) & ~(align-1);
        pad -= off;
        off += pad;
@@ -1527,6 +1529,9 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
        }
        space_remaining -= pad;
 
+       DEBUG(10,("smbd_marshall_dir_entry: space_remaining = %d\n",
+               space_remaining ));
+
        pdata += pad;
        p = pdata;
        last_entry_ptr = p;
@@ -1641,7 +1646,10 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
                /* Max string size is 255 bytes. */
                if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
                        *out_of_space = true;
-                       DEBUG(9,("smbd_marshall_dir_entry: out of space\n"));
+                       DEBUG(9,("smbd_marshall_dir_entry: out of space "
+                               "(wanted %u, had %d)\n",
+                               (unsigned int)PTR_DIFF(p + 255 + ea_len,pdata),
+                               space_remaining ));
                        return False; /* Not finished - just out of space */
                }
 
@@ -2021,7 +2029,10 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
 
        if (PTR_DIFF(p,pdata) > space_remaining) {
                *out_of_space = true;
-               DEBUG(9,("smbd_marshall_dir_entry: out of space\n"));
+               DEBUG(9,("smbd_marshall_dir_entry: out of space "
+                       "(wanted %u, had %d)\n",
+                       (unsigned int)PTR_DIFF(p,pdata),
+                       space_remaining ));
                return false; /* Not finished - just out of space */
        }