From 9bef27dec1a81b7ba46bc3126edd5ac1b225f6dc Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Wed, 28 May 2014 10:40:27 -0700
Subject: [PATCH] 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>
---
 source3/lib/system.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/source3/lib/system.c b/source3/lib/system.c
index af72b2a..698de12 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -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;
 }
 
-- 
1.9.1.423.g4596e3a

From 70199b99aa90d2da82c5200b3b0452ac0e28bf0c Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Wed, 11 Jun 2014 13:22:14 -0700
Subject: [PATCH] s3: smbd - fix processing of packets with invalid DOS charset
 conversions.

Bug 10654 - Segmentation fault in smbd_marshall_dir_entry()'s SMB_FIND_FILE_UNIX handler

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

Signed-off-by: Jeremy Allison <jra@samba.org>
---
 source3/lib/charcnv.c   | 16 ++++++++++------
 source3/libsmb/clirap.c |  4 ++--
 source3/smbd/lanman.c   |  4 ++--
 3 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c
index d3f65ca..d8cd2a5 100644
--- a/source3/lib/charcnv.c
+++ b/source3/lib/charcnv.c
@@ -822,7 +822,7 @@ size_t ucs2_align(const void *base_ptr, const void *p, int flags)
  **/
 size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags)
 {
-	size_t src_len = strlen(src);
+	size_t src_len = 0;
 	char *tmpbuf = NULL;
 	size_t ret;
 
@@ -840,17 +840,21 @@ size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags)
 		src = tmpbuf;
 	}
 
+	src_len = strlen(src);
 	if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) {
 		src_len++;
 	}
 
 	ret = convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len, True);
-	if (ret == (size_t)-1 &&
-			(flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
-			&& dest_len > 0) {
-		((char *)dest)[0] = '\0';
-	}
+
 	SAFE_FREE(tmpbuf);
+	if (ret == (size_t)-1) {
+		if ((flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
+				&& dest_len > 0) {
+			((char *)dest)[0] = '\0';
+		}
+		return 0;
+	}
 	return ret;
 }
 
diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c
index d39d38e..31c4cfe 100644
--- a/source3/libsmb/clirap.c
+++ b/source3/libsmb/clirap.c
@@ -319,7 +319,7 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
 				sizeof(param) - PTR_DIFF(p,param) - 1,
 				STR_TERMINATE|STR_UPPER);
 
-		if (len == (size_t)-1) {
+		if (len == 0) {
 			SAFE_FREE(last_entry);
 			return false;
 		}
@@ -331,7 +331,7 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
 					sizeof(param) - PTR_DIFF(p,param) - 1,
 					STR_TERMINATE);
 
-			if (len == (size_t)-1) {
+			if (len == 0) {
 				SAFE_FREE(last_entry);
 				return false;
 			}
diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
index aef12df..724b869 100644
--- a/source3/smbd/lanman.c
+++ b/source3/smbd/lanman.c
@@ -128,7 +128,7 @@ static int CopyExpanded(connection_struct *conn,
 		return 0;
 	}
 	l = push_ascii(*dst,buf,*p_space_remaining, STR_TERMINATE);
-	if (l == -1) {
+	if (l == 0) {
 		return 0;
 	}
 	(*dst) += l;
@@ -143,7 +143,7 @@ static int CopyAndAdvance(char **dst, char *src, int *n)
 		return 0;
 	}
 	l = push_ascii(*dst,src,*n, STR_TERMINATE);
-	if (l == -1) {
+	if (l == 0) {
 		return 0;
 	}
 	(*dst) += l;
-- 
2.0.0.526.g5318336