summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2014-05-28 10:40:27 -0700
committerKarolin Seeger <kseeger@samba.org>2014-06-23 07:58:57 +0200
commit331ae420e9fc10b56b3abdcda1c5d98f18f017d4 (patch)
treeca150488b30433bc531ad250d937ddce2ab746cf
parent3b5dcee460a14fd1af5dc931ad010e39b4e7326f (diff)
downloadsamba-331ae420e9fc10b56b3abdcda1c5d98f18f017d4.tar.gz
s3: nmbd: Fix bug 10633 - nmbd denial of service
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>
-rw-r--r--source3/lib/system.c7
1 files changed, 2 insertions, 5 deletions
diff --git a/source3/lib/system.c b/source3/lib/system.c
index d0e34bc20e5..8f919e529f7 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -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;
}