Bug 1097815 (CVE-2014-0244) - CVE-2014-0244 samba: nmbd denial of service
Summary: CVE-2014-0244 samba: nmbd denial of service
Keywords:
Status: CLOSED ERRATA
Alias: CVE-2014-0244
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL:
Whiteboard:
Depends On: 1105499 1105500 1105501 1105502 1105504 1105505 1112150 1112151 1112251
Blocks: 1098221
TreeView+ depends on / blocked
 
Reported: 2014-05-14 15:09 UTC by Daniel B
Modified: 2021-06-01 15:32 UTC (History)
15 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
A denial of service flaw was found in the way the sys_recvfile() function of nmbd, the NetBIOS message block daemon, processed non-blocking sockets. An attacker could send a specially crafted packet that, when processed, would cause nmbd to enter an infinite loop and consume an excessive amount of CPU time.
Clone Of:
Environment:
EL 5.10 i386 samba3x as a domain controler
Last Closed: 2014-08-12 16:49:13 UTC
Embargoed:


Attachments (Terms of Use)
Strace of nmbd when the problem is triggered (50.67 KB, text/plain)
2014-05-14 15:09 UTC, Daniel B
no flags Details


Links
System ID Private Priority Status Summary Last Updated
CentOS 7121 0 None None None Never
Red Hat Product Errata RHSA-2014:0866 0 normal SHIPPED_LIVE Moderate: samba and samba3x security update 2014-07-09 20:27:55 UTC
Red Hat Product Errata RHSA-2014:0867 0 normal SHIPPED_LIVE Moderate: samba security update 2014-07-09 20:17:12 UTC

Description Daniel B 2014-05-14 15:09:34 UTC
Created attachment 895515 [details]
Strace of nmbd when the problem is triggered

Description of problem:

I'm running samba3x (samba3x-3.6.6-0.139.el5_10) as an simple NT domain controler on a CentOS 5.10, and found sometime the nmbd process stuck (eating 100% CPU, and not responding anymore to any request, making any domain login impossible). The only solution was to kill -9 this process and restart it. It was occuring randomly, so was quite hard to troubleshoot, but after a few hours, I've finaly identified what's causing it (well at least, I know a simple request from a client is enough to trigger it)

I'll attach:

- a strace of the process at the time the problem occure. In this file the last lines (recvfrom(12, 0xbfcff9c8, 576, 0, 0xbfcffc08, 0xbfcff988) = -1 EAGAIN (Resource temporarily unavailable)) is repeated indefinitly as long as the process isn't killed, producing several GB per hour in the strace file. I've truncated it to the interesting part

- a pcap of the packet crashing nmbd (which you can replay with tcpreplay to reproduce the issue)

Version-Release number of selected component (if applicable):


How reproducible:
100% with the attached pcap


Steps to Reproduce:
1. You need a client with IP 192.168.7.50 and MAC 6c:62:6d:b0:25:42
2. The server running nmbd with IP 192.168.7.1 and MAC 52:54:00:7C:31:C4
(if you have different values you'll have to tweak the pcap with tcprewrite)
3. The netbios name of the samba server should be SAS (it's contained in the pcap and needs to match the netbios name of the server in order to trigger the issue)
4. Run nmbd (I'm running it with daemontools with /usr/sbin/nmbd -F -S but that probably doesn't matter)
5. Replay the attached pcap with tcpreplay -i eth0 nmbd_dos.pcap

Actual results:
nmbd will go in a loop, taking 100% of a core, and won't respond to any further requests, making impossible to login on the domain

Expected results:
nmbd should continue working as normal

Additional info:

Marking this a security issue as it makes it very easy to DOS a domain controler

Comment 2 Stefan Cornelius 2014-05-23 11:49:42 UTC
Thanks for the detailed report and the reproducer, that helped a lot.

I managed to reproduce the issue. When nmbd hangs, it has the following backtrace:

#0  0x00002ba5fb059d53 in __recvfrom_nocancel () from /lib64/libc.so.6
#1  0x00002ba5f85e506d in recvfrom (s=12, buf=0x7fff3cbe5940, len=576, flags=0, from=0x7fff3cbe5b80, fromlen=0x7fff3cbe5914)
    at /usr/include/bits/socket2.h:55
#2  sys_recvfrom (s=12, buf=0x7fff3cbe5940, len=576, flags=0, from=0x7fff3cbe5b80, fromlen=0x7fff3cbe5914) at lib/system.c:288
#3  0x00002ba5f85f6a73 in read_udp_v4_socket (fd=12, buf=0x7fff3cbe5940 "PW\276<\377\177", len=576, psa=0x7fff3cbe5b80) at lib/util_sock.c:259
#4  0x00002ba5f853ddb8 in read_packet (fd=12, packet_type=DGRAM_PACKET) at libsmb/nmblib.c:802
#5  0x00002ba5f84c7601 in listen_for_packets (run_election=<value optimized out>) at nmbd/nmbd_packets.c:1971
#6  0x00002ba5f84bae0b in process (argc=<value optimized out>, argv=<value optimized out>) at nmbd/nmbd.c:493
#7  main (argc=<value optimized out>, argv=<value optimized out>) at nmbd/nmbd.c:1020


read_udp_v4_socket has the following code:
ret = (ssize_t)sys_recvfrom(fd,buf,len,0,
		(struct sockaddr *)psa,&socklen);
if (ret <= 0) {
	/* Don't print a low debug error for a non-blocking socket. */
	if (errno == EAGAIN) {
		DEBUG(10,("read_udp_v4_socket: returned EAGAIN\n"));
	} else {
		DEBUG(2,("read_udp_v4_socket: failed. errno=%s\n",
			strerror(errno)));
	}
	return 0;
}

So, we can see it calls sys_recvfrom() and wants to bail out if it encounters EAGAIN return values.

Now, the interesting part is how sys_recvfrom() is implemented:
ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
{
	ssize_t ret;

	do {
		ret = recvfrom(s, buf, len, flags, from, fromlen);
#if defined(EWOULDBLOCK)
	} while (ret == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
#else
	} while (ret == -1 && (errno == EINTR || errno == EAGAIN));
#endif
	return ret;
}

We see that it simply loops the recvfrom() and continues doing so if it encounters -1 or EAGAIN, so there's a chance that we end up looping endlessly. Also, it will never propagate -1/EAGAIN errors up to read_udp_v4_socket, so the check in read_udp_v4_socket is essentially useless at this point.

Comment 19 Stefan Cornelius 2014-06-23 12:23:06 UTC
Public now.

External Reference:

http://www.samba.org/samba/security/CVE-2014-0244

Comment 20 Stefan Cornelius 2014-06-23 12:26:05 UTC
Created samba tracking bugs for this issue:

Affects: fedora-all [bug 1112251]

Comment 21 Vincent Danen 2014-07-04 00:36:00 UTC
The upstream patch is here:

http://git.samba.org/?p=samba.git;a=commitdiff;h=d77a74237e660dd2ce9f1e14b02635f8a2569653

Comment 22 Martin Prpič 2014-07-08 12:52:28 UTC
IssueDescription:

A denial of service flaw was found in the way the sys_recvfile() function of nmbd, the NetBIOS message block daemon, processed non-blocking sockets. An attacker could send a specially crafted packet that, when processed, would cause nmbd to enter an infinite loop and consume an excessive amount of CPU time.

Comment 23 errata-xmlrpc 2014-07-09 16:18:36 UTC
This issue has been addressed in following products:

  Red Hat Enterprise Linux 7

Via RHSA-2014:0867 https://rhn.redhat.com/errata/RHSA-2014-0867.html

Comment 24 errata-xmlrpc 2014-07-09 16:29:28 UTC
This issue has been addressed in following products:

  Red Hat Enterprise Linux 6
  Red Hat Enterprise Linux 5

Via RHSA-2014:0866 https://rhn.redhat.com/errata/RHSA-2014-0866.html

Comment 26 Stefan Cornelius 2014-08-12 16:49:13 UTC
This issue has been addressed in following products:

  Red Hat Enterprise Linux 6

Via RHSA-2014:1009 https://rhn.redhat.com/errata/RHSA-2014-1009.html


Note You need to log in before you can comment on or make changes to this bug.