From f566347fe0524a109818764590831425ba647f95 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 12 Nov 2018 11:37:31 -0800 Subject: [PATCH] s3: lib: nmbname: Ensure we limit the NetBIOS name correctly. CID: 1433607 Firstly, make the exit condition from the loop explicit (we must never write into byte n, where n >= sizeof(name->name). Secondly ensure exiting from the loop that n==MAX_NETBIOSNAME_LEN, as this is the sign of a correct NetBIOS name encoding (RFC1002) in order to properly read the NetBIOS name type (which is always encoded in byte 16 == name->name[15]). BUG: https://bugzilla.samba.org/show_bug.cgi?id=11495 Signed-off-by: Jeremy Allison Reviewed-by: David Disseldorp Autobuild-User(master): David Disseldorp Autobuild-Date(master): Tue Nov 13 20:54:56 CET 2018 on sn-devel-144 (cherry picked from commit 3634e20c7603103b0f2e00e5b61cc63f905d780d) --- source3/libsmb/nmblib.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index ef6177e5209..727939575a7 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -207,25 +207,33 @@ static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name) unsigned char c1,c2; c1 = ubuf[offset++]-'A'; c2 = ubuf[offset++]-'A'; - if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) + if ((c1 & 0xF0) || (c2 & 0xF0)) { return(0); + } + if (n >= sizeof(name->name)) { + return 0; + } name->name[n++] = (c1<<4) | c2; m -= 2; } - name->name[n] = 0; - - if (n==MAX_NETBIOSNAME_LEN) { - /* parse out the name type, its always - * in the 16th byte of the name */ - name->name_type = ((unsigned char)name->name[15]) & 0xff; - - /* remove trailing spaces */ - name->name[15] = 0; - n = 14; - while (n && name->name[n]==' ') - name->name[n--] = 0; + /* + * RFC1002: For a valid NetBIOS name, exiting from the above, + * n *must* be MAX_NETBIOSNAME_LEN (16). + */ + if (n != MAX_NETBIOSNAME_LEN) { + return 0; } + /* parse out the name type, its always + * in the 16th byte of the name */ + name->name_type = ((unsigned char)name->name[15]) & 0xff; + + /* remove trailing spaces */ + name->name[15] = 0; + n = 14; + while (n && name->name[n]==' ') + name->name[n--] = 0; + /* now the domain parts (if any) */ n = 0; while (ubuf[offset]) { -- 2.20.1.321.g9e740568ce-goog