From 9bef27dec1a81b7ba46bc3126edd5ac1b225f6dc Mon Sep 17 00:00:00 2001 From: Jeremy Allison 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 --- 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 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 --- 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