s3: smbd - fix processing of packets with invalid DOS charset conversions.
authorJeremy Allison <jra@samba.org>
Sun, 8 Jun 2014 04:51:44 +0000 (21:51 -0700)
committerKarolin Seeger <kseeger@samba.org>
Sun, 22 Jun 2014 14:26:14 +0000 (16:26 +0200)
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>
CVE-2014-3493

source3/lib/charcnv.c
source3/libsmb/clirap.c
source3/smbd/lanman.c

index 71d2c3aba56f6eb678d365c232dccae0202f85a1..2189812e2ab8bf46d8243bc369ba99702a951caf 100644 (file)
@@ -46,9 +46,9 @@ void gfree_charcnv(void)
  **/
 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 size;
+       size_t size = 0;
        bool ret;
 
        /* No longer allow a length of -1. */
@@ -62,24 +62,32 @@ size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags)
                        smb_panic("malloc fail");
                }
                if (!strupper_m(tmpbuf)) {
+                       if ((flags & (STR_TERMINATE|STR_TERMINATE_ASCII)) &&
+                                       dest &&
+                                       dest_len > 0) {
+                               *(char *)dest = 0;
+                       }
                        SAFE_FREE(tmpbuf);
-                       return (size_t)-1;
+                       return 0;
                }
                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, &size);
-       if (ret == false &&
-                       (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
-                       && dest_len > 0) {
-               ((char *)dest)[0] = '\0';
-       }
        SAFE_FREE(tmpbuf);
-       return ret ? size : (size_t)-1;
+       if (ret == false) {
+               if ((flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) &&
+                               dest_len > 0) {
+                       ((char *)dest)[0] = '\0';
+               }
+               return 0;
+       }
+       return size;
 }
 
 /********************************************************************
index 036919f903cea2ce12cd50cafccbb55c0abd336f..64e3767c1297dc4e53af3c25fc33d7b5611975f4 100644 (file)
@@ -327,7 +327,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;
                }
@@ -339,7 +339,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;
                        }
index 1b734a7299e3bf95723fe7f0d83606b91c8e3aac..0a0ab6b9754b820f3c55aba4b3d4e813515f16d7 100644 (file)
@@ -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;