s3: nmbd: Fix bug 10633 - nmbd denial of service
authorJeremy Allison <jra@samba.org>
Wed, 28 May 2014 17:40:27 +0000 (10:40 -0700)
committerJeremy Allison <jra@samba.org>
Tue, 24 Jun 2014 23:33:13 +0000 (01:33 +0200)
The Linux kernel has a bug in that it can give spurious
wakeups on a non-blocking UDP socket for a non-deliverable packet.

When nmbd was changed to use non-blocking sockets it
became vulnerable to a spurious wakeup from poll/epoll.

Fix sys_recvfile() to return on EWOULDBLOCK/EAGAIN.

CVE-2014-0244

https://bugzilla.samba.org/show_bug.cgi?id=10633

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source3/lib/system.c

index af72b2a8d3883a13acd81af05622ddcd0c02e33c..698de1221ceb113146491f179344fe1dba15bab9 100644 (file)
@@ -169,6 +169,7 @@ ssize_t sys_send(int s, const void *msg, size_t len, int flags)
 
 /*******************************************************************
 A recvfrom wrapper that will deal with EINTR.
+NB. As used with non-blocking sockets, return on EAGAIN/EWOULDBLOCK
 ********************************************************************/
 
 ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
@@ -177,11 +178,7 @@ ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *f
 
        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
+       } while (ret == -1 && (errno == EINTR));
        return ret;
 }