[SCM] Samba Shared Repository - branch master updated

[email protected] (Douglas Bagnall)
Newsgroups gmane.network.samba.cvs
Message-ID <[email protected]>
The branch, master has been updated
       via  91d5ea2 librpc/ndr/uuid.c: improve speed and accuracy of GUID string parsing
       via  6c9a185 s4-torture: better, failing, tests for GUID_from_string
      from  c0549ae cli-quotas: fix potential memory leak

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 91d5ea2ae90140cad0fa8021f07dad3f3d7b7734
Author: Douglas Bagnall <[email protected]>
Date:   Wed Dec 7 11:54:41 2016 +1300

    librpc/ndr/uuid.c: improve speed and accuracy of GUID string parsing
    
    GUID_from_data_blob() was relying on sscanf to parse strings, which was
    slow and quite accepting of invalid GUIDs. Instead we directly read a
    fixed number of hex bytes for each field.
    
    This now passes the samba4.local.ndr.*.guid_from_string_invalid tests.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Andrew Bartlett <[email protected]>
    
    Autobuild-User(master): Douglas Bagnall <[email protected]>
    Autobuild-Date(master): Wed Dec 14 08:55:42 CET 2016 on sn-devel-144

commit 6c9a185be260a914bc0bd2dcf76c9dcb9664a687
Author: Douglas Bagnall <[email protected]>
Date:   Wed Dec 7 14:35:58 2016 +1300

    s4-torture: better, failing, tests for GUID_from_string
    
    These tests reveal that the current implementation accepts all kinds
    of invalid GUIDs. In particular, we fail on these ones:
    
     "00000001-0002-0003-0405--060708090a0"
     "-0000001-0002-0003-0405-060708090a0b"
     "-0000001-0002-0003-04-5-060708090a0b"
     "d0000001-0002-0003-0405-060708090a-b"
     "00000001-  -2-0003-0405-060708090a0b"
     "00000001-0002-0003-0405- 060708090a0"
     "0x000001-0002-0003-0405-060708090a0b"
     "00000001-0x02-0x03-0405-060708090a0b"
    
    This test is added to selftest/knownfail.
    
    The test for valid string GUIDs is extended to test upper and mixed case
    GUIDs.
    
    Signed-off-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Andrew Bartlett <[email protected]>

-----------------------------------------------------------------------

Summary of changes:
 librpc/ndr/uuid.c         | 132 ++++++++++++++++++++++++++++++++++++++--------
 source4/torture/ndr/ndr.c |  64 ++++++++++++++++++----
 2 files changed, 166 insertions(+), 30 deletions(-)


Changeset truncated at 500 lines:

diff --git a/librpc/ndr/uuid.c b/librpc/ndr/uuid.c
index a3f68d1..037dd90 100644
--- a/librpc/ndr/uuid.c
+++ b/librpc/ndr/uuid.c
@@ -52,6 +52,102 @@ _PUBLIC_ NTSTATUS GUID_from_ndr_blob(const DATA_BLOB *b, struct GUID *guid)
 	return ndr_map_error2ntstatus(ndr_err);
 }
 
+static NTSTATUS read_hex_bytes(const char *s, uint hexchars, uint64_t *dest)
+{
+	uint64_t x = 0;
+	uint i;
+	char c;
+
+	if ((hexchars & 1) || hexchars > 16) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	for (i = 0; i < hexchars; i++) {
+		x <<= 4;
+		c = s[i];
+		if (c >= '0' && c <= '9') {
+			x += c - '0';
+		}
+		else if (c >= 'a' && c <= 'f') {
+			x += c - 'a' + 10;
+		}
+		else if (c >= 'A' && c <= 'F') {
+			x += c - 'A' + 10;
+		}
+		else {
+			/* BAD character (including '\0') */
+			return NT_STATUS_INVALID_PARAMETER;
+		}
+	}
+	*dest = x;
+	return NT_STATUS_OK;
+}
+
+
+static NTSTATUS parse_guid_string(const char *s,
+				  uint32_t *time_low,
+				  uint32_t *time_mid,
+				  uint32_t *time_hi_and_version,
+				  uint32_t *clock_seq,
+				  uint32_t *node)
+{
+	uint64_t tmp;
+	NTSTATUS status;
+	int i;
+	/* "e12b56b6-0a95-11d1-adbb-00c04fd8d5cd"
+                |     |    |    |    |
+                |     |    |    |    \ node[6]
+                |     |    |    \_____ clock_seq[2]
+                |     |    \__________ time_hi_and_version
+		|     \_______________ time_mid
+		\_____________________ time_low
+	*/
+	status = read_hex_bytes(s, 8, &tmp);
+	if (!NT_STATUS_IS_OK(status) || s[8] != '-') {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+	*time_low = tmp;
+	s += 9;
+
+	status = read_hex_bytes(s, 4, &tmp);
+	if (!NT_STATUS_IS_OK(status) || s[4] != '-') {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+	*time_mid = tmp;
+	s += 5;
+
+	status = read_hex_bytes(s, 4, &tmp);
+	if (!NT_STATUS_IS_OK(status) || s[4] != '-') {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+	*time_hi_and_version = tmp;
+	s += 5;
+
+	for (i = 0; i < 2; i++) {
+		status = read_hex_bytes(s, 2, &tmp);
+		if (!NT_STATUS_IS_OK(status)) {
+			return NT_STATUS_INVALID_PARAMETER;
+		}
+		clock_seq[i] = tmp;
+		s += 2;
+	}
+	if (s[0] != '-') {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	s++;
+
+	for (i = 0; i < 6; i++) {
+		status = read_hex_bytes(s, 2, &tmp);
+		if (!NT_STATUS_IS_OK(status)) {
+			return NT_STATUS_INVALID_PARAMETER;
+		}
+		node[i] = tmp;
+		s += 2;
+	}
+
+	return NT_STATUS_OK;
+}
 
 /**
   build a GUID from a string
@@ -75,32 +171,26 @@ _PUBLIC_ NTSTATUS GUID_from_data_blob(const DATA_BLOB *s, struct GUID *guid)
 	switch(s->length) {
 	case 36:
 	{
-		char string[37];
-		memcpy(string, s->data, 36);
-		string[36] = 0;
-
-		if (11 == sscanf(string,
-				 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-				 &time_low, &time_mid, &time_hi_and_version, 
-				 &clock_seq[0], &clock_seq[1],
-				 &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
-			status = NT_STATUS_OK;
-		}
+		status = parse_guid_string((char *)s->data,
+					   &time_low,
+					   &time_mid,
+					   &time_hi_and_version,
+					   clock_seq,
+					   node);
 		break;
 	}
 	case 38:
 	{
-		char string[39];
-		memcpy(string, s->data, 38);
-		string[38] = 0;
-
-		if (11 == sscanf(string, 
-				 "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
-				 &time_low, &time_mid, &time_hi_and_version, 
-				 &clock_seq[0], &clock_seq[1],
-				 &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
-			status = NT_STATUS_OK;
+		if (s->data[0] != '{' || s->data[37] != '}') {
+			break;
 		}
+
+		status = parse_guid_string((char *)s->data + 1,
+					   &time_low,
+					   &time_mid,
+					   &time_hi_and_version,
+					   clock_seq,
+					   node);
 		break;
 	}
 	case 32:
diff --git a/source4/torture/ndr/ndr.c b/source4/torture/ndr/ndr.c
index 7d28eb0..d67585c 100644
--- a/source4/torture/ndr/ndr.c
+++ b/source4/torture/ndr/ndr.c
@@ -296,17 +296,61 @@ static bool test_guid_from_string_null(struct torture_context *tctx)
 static bool test_guid_from_string_invalid(struct torture_context *tctx)
 {
 	struct GUID g1;
-	torture_assert_ntstatus_equal(tctx, NT_STATUS_INVALID_PARAMETER,
-				      GUID_from_string("bla", &g1),
-				      "parameter not invalid");
+	bool failed = false;
+	int i;
+	const char *bad_guids[] = {
+		"bla",
+		"",
+		/*
+		"00000001-0002-0003-0405-060708090a0b",  correct
+		*/
+		"00000001-0002-0003-0405-060708090a0b1", /* too long */
+		"00000001-0002-0003-0405-060708090a0",  /* too short */
+		"00000001-0002-0003-0405--060708090a0",  /* negative */
+		"00000001-0002-0003--0405-060708090a0",  /* negative */
+		"-0000001-0002-0003-0405-060708090a0b",  /* negative */
+		"-0000001-0002-0003-04-5-060708090a0b",  /* negative */
+		"d0000001-0002-0003-0405-060708090a-b",  /* negative */
+		"00000001-  -2-0003-0405-060708090a0b",  /* negative, space */
+		"00000001-0002-0003-0405- 060708090a0",  /* whitespace */
+		" 0000001-0002-0003--0405-060708090a0",  /* whitespace */
+		"00000001-0002-0003--0405-060708090a ",  /* whitespace */
+		"0000001-00002-0003-04050-60708090a0b",  /* misshapen */
+		"00000010-0002-0003-04050-60708090a0b",  /* misshapen */
+		"00000001-0002-0003-0405-0z0708090a0b",  /* bad char */
+		"00000001-00x2-0x03-0405-060708090a0b",  /* bad char (00x) */
+		"0x000001-0002-0003-0405-060708090a0b",  /* 0x char */
+		"00000001-0x02-0x03-0405-060708090a0b",  /* 0x char */
+	};
+
+	for (i = 0; i < ARRAY_SIZE(bad_guids); i++) {
+		NTSTATUS status = GUID_from_string(bad_guids[i], &g1);
+		if (! NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
+			torture_comment(tctx, "bad guid %s parsed as OK\n",
+					bad_guids[i]);
+			failed = true;
+		}
+	}
+	if (failed) {
+		torture_fail(tctx, "wrongly allowing invalid guids");
+	}
 	return true;
 }
 
 static bool test_guid_from_string(struct torture_context *tctx)
 {
 	struct GUID g1, exp;
+	/* we are asserting all these guids are valid and equal */
+	const char *guids[4] = {
+		"00000001-0002-0003-0405-060708090a0b",
+		"{00000001-0002-0003-0405-060708090a0b}",
+		"{00000001-0002-0003-0405-060708090a0B}", /* mixed */
+		"00000001-0002-0003-0405-060708090A0B",   /* upper */
+	};
+	int i;
+
 	torture_assert_ntstatus_ok(tctx,
-				   GUID_from_string("00000001-0002-0003-0405-060708090a0b", &g1),
+				   GUID_from_string(guids[0], &g1),
 				   "invalid return code");
 	exp.time_low = 1;
 	exp.time_mid = 2;
@@ -319,12 +363,14 @@ static bool test_guid_from_string(struct torture_context *tctx)
 	exp.node[3] = 9;
 	exp.node[4] = 10;
 	exp.node[5] = 11;
-	torture_assert(tctx, GUID_equal(&g1, &exp), "UUID parsed incorrectly");
-	torture_assert_ntstatus_ok(tctx,
-				   GUID_from_string("{00000001-0002-0003-0405-060708090a0b}", &g1),
-				   "invalid return code");
-	torture_assert(tctx, GUID_equal(&g1, &exp), "UUID parsed incorrectly");
 
+	for (i = 1; i < ARRAY_SIZE(guids); i++) {
+		torture_assert_ntstatus_ok(tctx,
+					   GUID_from_string(guids[i], &g1),
+					   "invalid return code");
+		torture_assert(tctx, GUID_equal(&g1, &exp),
+			       "UUID parsed incorrectly");
+	}
 	return true;
 }
 


-- 
Samba Shared Repository
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.