[SCM] Samba Shared Repository - branch master updated

Douglas Bagnall dbagnall at samba.org
Wed Dec 14 07:56:04 UTC 2016


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 <douglas.bagnall at catalyst.net.nz>
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 <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Douglas Bagnall <dbagnall at samba.org>
    Autobuild-Date(master): Wed Dec 14 08:55:42 CET 2016 on sn-devel-144

commit 6c9a185be260a914bc0bd2dcf76c9dcb9664a687
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
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 <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

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

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



More information about the samba-cvs mailing list