Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SMB server(Win10) returns at most 4280 byte as smb2_ioctl_reply.output_count. #213

Open
Arlen-LT opened this issue Sep 29, 2021 · 1 comment

Comments

@Arlen-LT
Copy link

The reason for trying to get the correct output_count from server is because it increases with the increment of the share amounts on my server in the range of 0-86, but once the share amounts exceeds 86, the output_count always returns 4280 and the status returns -22 so that I can't access the smb server. Some other smb clients such as linux, windows, mac can access the server correctly.

I am using function smb2_share_enum_async and the callback function returns status=-22.
I have checked the smb2_ioctl_request sent.

static int
smb2_encode_ioctl_request(struct smb2_context *smb2,
                          struct smb2_pdu *pdu,
                          struct smb2_ioctl_request *req)
{
        ...
        smb2_set_uint32(iov, 44, 65535); /* Max output response */
        ...
}

and smb2->max_transact_size = 8388608 ( > MaxOutputResponse).

The problem seems to be in the below function, offset gradually increases to approach iov->len with each loop when the dp->coder is dcerpc_utf16z_coder, and if (offset + actual * 2 > iov->len) { return -1; }, the value of the iov->len is got from smb2_get_uint32(iov, 36, &rep->output_count);, so, if the reply from server returns a fixed value (4280 in my example), the offset will return -1 in a loop while decoding. And then the offset will always be -1, at last, the status returns -22.

static int
dcerpc_process_deferred_pointers(struct dcerpc_context *ctx,
                                 struct dcerpc_pdu *pdu,
                                 struct smb2_iovec *iov,
                                 int offset)
{
        struct dcerpc_deferred_pointer *dp;
        int idx;

        while (pdu->cur_ptr != pdu->max_ptr) {
                idx = pdu->cur_ptr++;
                dp = &pdu->ptrs[idx];
                offset = dp->coder(ctx, pdu, iov, offset, dp->ptr);
        }

        return offset;
}

Custom Log:

 loop=170, offset=4176, cur_ptr=171, max_ptr=177
 dcerpc_utf16z_coder offset=4176,iov->len=4280
 loop=171, offset=4190, cur_ptr=172, max_ptr=177
 dcerpc_utf16z_coder offset=4190,iov->len=4280
 loop=172, offset=4208, cur_ptr=173, max_ptr=177
 dcerpc_utf16z_coder offset=4208,iov->len=4280
 loop=173, offset=4222, cur_ptr=174, max_ptr=177
 dcerpc_utf16z_coder offset=4222,iov->len=4280
 loop=174, offset=4250, cur_ptr=175, max_ptr=177
 dcerpc_utf16z_coder offset=4250,iov->len=4280
 loop=175, offset=4266, cur_ptr=176, max_ptr=177
 dcerpc_utf16z_coder offset=4266,iov->len=4280
 loop=176, offset=-1, cur_ptr=177, max_ptr=177
 dcerpc_utf16z_coder offset=-1,iov->len=4280
 dcerpc_process_deferred_pointers offset2=-1,cur_ptr=177,max_ptr=177
 dcerpc_ptr_coder offset=-1,iov->len=4280
 dcerpc_ptr_coder offset=-1,iov->len=4280
 dcerpc_uint32_coder offset=-1,iov->len=4280

Could anybody help me? Thanks a lot.

@sahlberg
Copy link
Owner

sahlberg commented Oct 6, 2021

Thanks for reporting this.
I will have a look, probably this weekend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants