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)
committerKarolin Seeger <kseeger@samba.org>
Sun, 22 Jun 2014 14:26:14 +0000 (16:26 +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

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

index 8252e4fcfc925d542ebc98ba4555655fe2111291..4f3859749697ce7193d6ffc5ccabfb92b87eb8dd 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;
 }