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>
Mon, 23 Jun 2014 05:58:57 +0000 (07:58 +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 d0e34bc20e598002e81d3c0799e20db65d99f355..8f919e529f7a71da1fb9eb593ef337532d555967 100644 (file)
@@ -278,6 +278,7 @@ ssize_t sys_recv(int fd, void *buf, size_t count, 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)
@@ -286,11 +287,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;
 }