Bug 15436 - smbclient -L can dereference uninitialized pointer if server returns bogus info_ctr level
Summary: smbclient -L can dereference uninitialized pointer if server returns bogus in...
Status: NEW
Alias: None
Product: Samba 4.1 and newer
Classification: Unclassified
Component: libsmbclient (show other bugs)
Version: unspecified
Hardware: All All
: P5 normal (vote)
Target Milestone: ---
Assignee: Samba QA Contact
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-07-28 12:11 UTC by Robert Morris
Modified: 2023-08-01 12:44 UTC (History)
0 users

See Also:


Attachments
fake smb server that returns a bogus level to smbclient -L (18.82 KB, text/x-csrc)
2023-07-28 12:11 UTC, Robert Morris
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Robert Morris 2023-07-28 12:11:22 UTC
Created attachment 18006 [details]
fake smb server that returns a bogus level to smbclient -L

In smbclient -L, browse_host_rpc() uses info_ctr.ctr.ctr1 if
dcerpc_srvsvc_NetShareEnumAll() returns OK:

        for (i=0; i < info_ctr.ctr.ctr1->count; i++) {

ndr_pull_srvsvc_NetShareEnumAll() allocates a heap block which
dcerpc_srvsvc_NetShareEnumAll() later copies over info_ctr:

                if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
                        NDR_PULL_ALLOC(ndr, r->out.info_ctr);
                }

Ordinarily the content of the info_ctr heap block is initialized in
one of the arms of the switch statement in
ndr_pull_srvsvc_NetShareCtr(). But if the "level" supplied by the
server doesn't match any of the switch cases, then the heap block
isn't initialized, but ndr_pull_srvsvc_NetShareCtr() still returns OK.

As a result, if the server returns a bogus "level", browse_host_rpc()
can trip over a garbage info_ctr.ctr.ctr1.

I've attached a demo smb server which causes smbclient -L to crash
if compiled with a debugging malloc.
Comment 1 Robert Morris 2023-08-01 12:44:29 UTC
The loop in browse_host_rpc() assumes that info_ctr.level is 1 and
that the array is non-NULL if count > 0, but
dcerpc_srvsvc_NetShareEnumAll() doesn't necessarily conform.