[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Wed Nov 20 06:07:02 UTC 2019


The branch, master has been updated
       via  f7f92803f60 librpc: Check for NULL pointer in value() in ntlmssp_AUTHENTICATE
       via  33e9021cbee selftest: Test repushing an ntlmssp AUTHENTICATE_MESSAGE
       via  ac1be895d25 selftest: Confirm that NDR bugs are fixed in DCOM code
       via  1aec7425752 pidl: check the size of pulled arrays of arrays
       via  536a84935ce ndr_orpc: properly allocate empty DUALSTRINGARRAY
       via  b1eda993b65 selftest: Confirm that --base64-input and --input work and a PIDL bug is fixed.
       via  24fa3374e04 python: Return the stdout when also checking error codes
       via  2da54d11f1e ndrdump: Still print --dump bytes after parse failure
       via  0491f172751 ndrdump: Invert sense of --stop-on-parse-failure into --print-after-parse-failure
       via  c83ad13e589 ndrdump: Return a different error code for ndr_pull() failures
       via  6f0d30fd5cc ndrdump: Allow for base64-encoded input in a file and on the command line
       via  d4eabfb763b ndrdump: Check for input decode failures
       via  3194baaf88d ndrdump: Add const
       via  c90bc75df84 ndrdump: TALLOC_FREE() on each exit path to allow running with leak detection
       via  8a6f1de67b1 ndrdump: print structure name when failing to setup
       via  db6c12f1584 ndrdump: Fix one more NTSTATUS rather than friendly ndr message
      from  1af1ebe54ae librpc: Unify packet dumping on ndr_pull() failure

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


- Log -----------------------------------------------------------------
commit f7f92803f600f8d302cdbb668c42ca8b186a797f
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Nov 19 17:38:50 2019 +1300

    librpc: Check for NULL pointer in value() in ntlmssp_AUTHENTICATE
    
    This allows ndrdump --validate to avoid following a NULL pointer when re-pushing
    a valid but unusual input.
    
    It also avoids an issue if the Samba server code were to provide a response
    without an EncryptedRandomSessionKey.
    
    At this stage ntlmssp.idl is not used for this, instead the packets are
    generated with msrpc_gen().
    
    Found by Douglas Bagnall using Hongfuzz and the new fuzz_ndr_X
    fuzzer.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Wed Nov 20 06:06:29 UTC 2019 on sn-devel-184

commit 33e9021cbee4c17ee2f11d02b99902a742d77293
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Nov 20 12:14:52 2019 +1300

    selftest: Test repushing an ntlmssp AUTHENTICATE_MESSAGE
    
    This demonstrates a bug found by Douglas Bagnall using Hongfuzz and the new fuzz_ndr_X
    fuzzer where the value() evaluatuion could segfault if it was made to follow a NULL
    pointer.
    
    This also demonstrates that the --base64 mode works on file inputs.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit ac1be895d2501dc79dcff2c1e03549fe5b5a930c
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Nov 20 11:40:51 2019 +1300

    selftest: Confirm that NDR bugs are fixed in DCOM code
    
    Test input provided by Michael Hanselmann and found using Hongfuzz.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13875
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 1aec742575252d1efcc47a8e9023889bfb0e5709
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Thu Oct 31 09:35:19 2019 +1300

    pidl: check the size of pulled arrays of arrays
    
    We were accidentally checking the memory just past the array instead of
    checking each member.
    
    This could have led to the size of some arrays not being checked.
    
    Found by Michael Hanselmann using Honggfuzz and an fuzzer for Samba's
    NDR layer.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13877
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Pair-programmed-with: Andrew Bartlett <abartlet at samba.org>
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 536a84935ce7647f43528d6d376f6762c5e8eb78
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Wed Oct 30 15:02:49 2019 +1300

    ndr_orpc: properly allocate empty DUALSTRINGARRAY
    
    When there is no data we still need to allocate for the terminating NULL.
    
    Found by Michael Hanselmann using Honggfuzz and an fuzzer for Samba's
    NDR layer.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13875
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit b1eda993b658590ebb0a8225e448ce399946ed83
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Nov 20 10:56:14 2019 +1300

    selftest: Confirm that --base64-input and --input work and a PIDL bug is fixed.
    
    The PIDL bug is in the handling of arrays of arrays.
    
    Test input provided by Michael Hanselmann and found using Hongfuzz.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13875
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 24fa3374e041f9ad26b6f124aed0c5a61a7d551e
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Nov 20 10:55:18 2019 +1300

    python: Return the stdout when also checking error codes
    
    This will aid in checking that ndrdump behaves as expected when
    failing to parse
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 2da54d11f1e9744885558a64e72bf93b6009ae0e
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Nov 20 10:45:02 2019 +1300

    ndrdump: Still print --dump bytes after parse failure
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 0491f1727513137a5cf86073d11608b7dd8a2056
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Nov 20 13:26:11 2019 +1300

    ndrdump: Invert sense of --stop-on-parse-failure into --print-after-parse-failure
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit c83ad13e5893889852cbd7d2208bf45c2b72b07c
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Nov 20 10:39:54 2019 +1300

    ndrdump: Return a different error code for ndr_pull() failures
    
    This may assist in distinguishing between "runner" and "pull" failures.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 6f0d30fd5cc921dedbc0f0741e3959b4ebc4027d
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Nov 20 10:00:52 2019 +1300

    ndrdump: Allow for base64-encoded input in a file and on the command line
    
    It has become customary to provide reproduction steps for fuzzing failures
    in terms of an ndrdump command line.  This allows the input to be provided
    as a argument or in a file rather than via base64 -d.  This makes reproducing
    the issue easier as everything can be put in a plaintext bug report.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit d4eabfb763b7c0ea6b112ea3a129977a68466977
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Nov 20 09:59:07 2019 +1300

    ndrdump: Check for input decode failures
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 3194baaf88d78f86cbf821600cd69712e1cc02a2
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Nov 20 09:58:15 2019 +1300

    ndrdump: Add const
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit c90bc75df8446c79a9e251c7b07a59674d828505
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Nov 18 13:46:53 2019 +1300

    ndrdump: TALLOC_FREE() on each exit path to allow running with leak detection
    
    This allows us to learn if there are other memory leaks not on the mem_ctx
    during the processing of the packet.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 8a6f1de67b1c2e925cce8fb20b6657a425cbaedb
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Nov 18 13:44:02 2019 +1300

    ndrdump: print structure name when failing to setup
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit db6c12f1584215c21cd5e56bef13c6d1c8b608ce
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Nov 20 12:17:37 2019 +1300

    ndrdump: Fix one more NTSTATUS rather than friendly ndr message
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

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

Summary of changes:
 librpc/idl/ntlmssp.idl                             |   2 +-
 librpc/ndr/ndr_orpc.c                              |   4 +-
 librpc/tools/ndrdump.c                             | 120 +++++++++++++-----
 pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm           |   4 +
 python/samba/tests/__init__.py                     |   1 +
 python/samba/tests/blackbox/ndrdump.py             | 100 +++++++++++++++
 .../fuzzed_ntlmssp-AUTHENTICATE_MESSAGE.b64.txt    |   1 +
 .../tests/fuzzed_ntlmssp-AUTHENTICATE_MESSAGE.txt  | 134 +++++++++++++++++++++
 8 files changed, 332 insertions(+), 34 deletions(-)
 create mode 100644 source4/librpc/tests/fuzzed_ntlmssp-AUTHENTICATE_MESSAGE.b64.txt
 create mode 100644 source4/librpc/tests/fuzzed_ntlmssp-AUTHENTICATE_MESSAGE.txt


Changeset truncated at 500 lines:

diff --git a/librpc/idl/ntlmssp.idl b/librpc/idl/ntlmssp.idl
index f984b7b0b4c..dd4c0b91640 100644
--- a/librpc/idl/ntlmssp.idl
+++ b/librpc/idl/ntlmssp.idl
@@ -271,7 +271,7 @@ interface ntlmssp
 		[value(ndr_ntlmssp_string_length(NegotiateFlags, Workstation))] uint16 WorkstationLen;
 		[value(WorkstationLen)] uint16 WorkstationMaxLen;
 		[relative] [subcontext(0),subcontext_size(WorkstationLen)] [flag(ndr_ntlmssp_negotiated_string_flags(r->NegotiateFlags))] string *Workstation;
-		[value(EncryptedRandomSessionKey->length)] uint16 EncryptedRandomSessionKeyLen;
+		[value(EncryptedRandomSessionKey == NULL ? 0 : EncryptedRandomSessionKey->length)] uint16 EncryptedRandomSessionKeyLen;
 		[value(EncryptedRandomSessionKeyLen)] uint16 EncryptedRandomSessionKeyMaxLen;
 		[relative] [subcontext(0),subcontext_size(EncryptedRandomSessionKeyLen)] DATA_BLOB *EncryptedRandomSessionKey;
 		NEGOTIATE NegotiateFlags;
diff --git a/librpc/ndr/ndr_orpc.c b/librpc/ndr/ndr_orpc.c
index f24ddc5f826..01ba885d942 100644
--- a/librpc/ndr/ndr_orpc.c
+++ b/librpc/ndr/ndr_orpc.c
@@ -37,7 +37,7 @@ enum ndr_err_code ndr_pull_DUALSTRINGARRAY(struct ndr_pull *ndr, int ndr_flags,
 	NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &num_entries));
 	NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &security_offset));
 
-	ar->stringbindings = talloc_array(ndr, struct STRINGBINDING *, num_entries);
+	ar->stringbindings = talloc_array(ndr, struct STRINGBINDING *, 1);
 	ar->stringbindings[0] = NULL;
 
 	do {
@@ -56,7 +56,7 @@ enum ndr_err_code ndr_pull_DUALSTRINGARRAY(struct ndr_pull *ndr, int ndr_flags,
 	ar->stringbindings[towernum] = NULL;
 	towernum = 0;
 
-	ar->securitybindings = talloc_array(ndr, struct SECURITYBINDING *, num_entries);
+	ar->securitybindings = talloc_array(ndr, struct SECURITYBINDING *, 1);
 	ar->securitybindings[0] = NULL;
 
 	do {
diff --git a/librpc/tools/ndrdump.c b/librpc/tools/ndrdump.c
index e911cf4c1e4..f02b1edab02 100644
--- a/librpc/tools/ndrdump.c
+++ b/librpc/tools/ndrdump.c
@@ -26,6 +26,7 @@
 #include "librpc/gen_ndr/ndr_dcerpc.h"
 #include "lib/cmdline/popt_common.h"
 #include "param/param.h"
+#include "lib/util/base64.h"
 
 static const struct ndr_interface_call *find_function(
 	const struct ndr_interface_table *p,
@@ -265,7 +266,8 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
 	 * name of a public structure
 	 */
 	const char *format = NULL;
-	uint8_t *data;
+	const char *cmdline_input = NULL;
+	const uint8_t *data;
 	size_t size;
 	DATA_BLOB blob;
 	struct ndr_pull *ndr_pull;
@@ -284,7 +286,8 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
 	bool assume_ndr64 = false;
 	bool quiet = false;
 	bool hex_input = false;
-	bool stop_on_parse_failure = false;
+	bool base64_input = false;
+	bool print_after_parse_failure = false;
 	int opt;
 	enum {
 		OPT_CONTEXT_FILE=1000,
@@ -293,8 +296,10 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
 		OPT_LOAD_DSO,
 		OPT_NDR64,
 		OPT_QUIET,
+		OPT_BASE64_INPUT,
 		OPT_HEX_INPUT,
-		OPT_STOP_ON_PARSE_FAILURE,
+		OPT_CMDLINE_INPUT,
+		OPT_PRINT_AFTER_PARSE_FAILURE,
 	};
 	struct poptOption long_options[] = {
 		POPT_AUTOHELP
@@ -304,9 +309,11 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
 		{"load-dso", 'l', POPT_ARG_STRING, NULL, OPT_LOAD_DSO, "load from shared object file", NULL },
 		{"ndr64", 0, POPT_ARG_NONE, NULL, OPT_NDR64, "Assume NDR64 data", NULL },
 		{"quiet", 0, POPT_ARG_NONE, NULL, OPT_QUIET, "Don't actually dump anything", NULL },
+		{"base64-input", 0, POPT_ARG_NONE, NULL, OPT_BASE64_INPUT, "Read the input file in as a base64 string", NULL },
 		{"hex-input", 0, POPT_ARG_NONE, NULL, OPT_HEX_INPUT, "Read the input file in as a hex dump", NULL },
-		{"stop-on-parse-failure", 0, POPT_ARG_NONE, NULL, OPT_STOP_ON_PARSE_FAILURE,
-		 "Do not try to print structures that fail to parse.", NULL },
+		{"input", 0, POPT_ARG_STRING, NULL, OPT_CMDLINE_INPUT, "Provide the input on the command line (use with --base64-input)", "INPUT" },
+		{"print-after-parse-failure", 0, POPT_ARG_NONE, NULL, OPT_PRINT_AFTER_PARSE_FAILURE,
+		 "Try to print structures that fail to parse (used to develop parsers, segfaults are likely).", NULL },
 		POPT_COMMON_SAMBA
 		POPT_COMMON_VERSION
 		{ NULL }
@@ -348,11 +355,17 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
 		case OPT_QUIET:
 			quiet = true;
 			break;
+		case OPT_BASE64_INPUT:
+			base64_input = true;
+			break;
 		case OPT_HEX_INPUT:
 			hex_input = true;
 			break;
-		case OPT_STOP_ON_PARSE_FAILURE:
-			stop_on_parse_failure = true;
+		case OPT_CMDLINE_INPUT:
+			cmdline_input = poptGetOptArg(pc);
+			break;
+		case OPT_PRINT_AFTER_PARSE_FAILURE:
+			print_after_parse_failure = true;
 			break;
 		}
 	}
@@ -419,34 +432,43 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
 
 	st = talloc_zero_size(mem_ctx, f->struct_size);
 	if (!st) {
-		printf("Unable to allocate %d bytes\n", (int)f->struct_size);
+		printf("Unable to allocate %d bytes for %s structure\n",
+		       (int)f->struct_size,
+		       f->name);
+		TALLOC_FREE(mem_ctx);
 		exit(1);
 	}
 
 	v_st = talloc_zero_size(mem_ctx, f->struct_size);
 	if (!v_st) {
-		printf("Unable to allocate %d bytes\n", (int)f->struct_size);
+		printf("Unable to allocate %d bytes for %s validation "
+		       "structure\n",
+		       (int)f->struct_size,
+		       f->name);
+		TALLOC_FREE(mem_ctx);
 		exit(1);
 	}
 
 	if (ctx_filename) {
 		if (flags & NDR_IN) {
 			printf("Context file can only be used for \"out\" packages\n");
+			TALLOC_FREE(mem_ctx);
 			exit(1);
 		}
 			
 		data = (uint8_t *)file_load(ctx_filename, &size, 0, mem_ctx);
 		if (!data) {
 			perror(ctx_filename);
+			TALLOC_FREE(mem_ctx);
 			exit(1);
 		}
 
-		blob.data = data;
-		blob.length = size;
+		blob = data_blob_const(data, size);
 
 		ndr_pull = ndr_pull_init_blob(&blob, mem_ctx);
 		if (ndr_pull == NULL) {
 			perror("ndr_pull_init_blob");
+			TALLOC_FREE(mem_ctx);
 			exit(1);
 		}
 		ndr_pull->flags |= LIBNDR_FLAG_REF_ALLOC;
@@ -469,15 +491,24 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
 		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 			printf("pull for context file returned %s\n",
 			       ndr_map_error2string(ndr_err));
-			exit(1);
+			TALLOC_FREE(mem_ctx);
+			exit(2);
 		}
 		memcpy(v_st, st, f->struct_size);
 	}
 
-	if (filename)
+	if (filename && cmdline_input) {
+		printf("cannot combine --input with a filename\n");
+		TALLOC_FREE(mem_ctx);
+		exit(1);
+	} else if (cmdline_input) {
+		data = (const uint8_t *)cmdline_input;
+		size = strlen(cmdline_input);
+	} else if (filename) {
 		data = (uint8_t *)file_load(filename, &size, 0, mem_ctx);
-	else
+	} else {
 		data = (uint8_t *)stdin_load(mem_ctx, &size);
+	}
 
 	if (!data) {
 		if (filename)
@@ -487,16 +518,33 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
 		exit(1);
 	}
 	
-	if (hex_input) {
-		blob = hexdump_to_data_blob(mem_ctx, (char *)data, size);
+	if (hex_input && base64_input) {
+		printf("cannot combine --hex-input with --base64-input\n");
+		TALLOC_FREE(mem_ctx);
+		exit(1);
+
+	} else if (hex_input) {
+		blob = hexdump_to_data_blob(mem_ctx, (const char *)data, size);
+	} else if (base64_input) {
+		/* Use talloc_strndup() to ensure null termination */
+		blob = base64_decode_data_blob(talloc_strndup(mem_ctx,
+							      (const char *)data, size));
+		/* base64_decode_data_blob() allocates on NULL */
+		talloc_steal(mem_ctx, blob.data);
 	} else {
-		blob.data = data;
-		blob.length = size;
+		blob = data_blob_const(data, size);
+	}
+
+	if (data != NULL && blob.data == NULL) {
+		printf("failed to decode input data\n");
+		TALLOC_FREE(mem_ctx);
+		exit(1);
 	}
 
 	ndr_pull = ndr_pull_init_blob(&blob, mem_ctx);
 	if (ndr_pull == NULL) {
 		perror("ndr_pull_init_blob");
+		TALLOC_FREE(mem_ctx);
 		exit(1);
 	}
 	ndr_pull->flags |= LIBNDR_FLAG_REF_ALLOC;
@@ -536,8 +584,9 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
 						      ndr_print,
 						      &f->out_pipes);
 		if (!NT_STATUS_IS_OK(status)) {
-			printf("dump FAILED\n");
-			exit(1);
+			printf("pull and dump of pipes FAILED\n");
+			TALLOC_FREE(mem_ctx);
+			exit(2);
 		}
 	}
 
@@ -545,17 +594,22 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
 	printf("pull returned %s\n",
 	       ndr_map_error2string(ndr_err));
 
-	if (stop_on_parse_failure && !NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-		printf("not printing because --stop-on-parse-failure\n");
-		exit(1);
-	}
-
 	if (ndr_pull->offset > ndr_pull->relative_highest_offset) {
 		highest_ofs = ndr_pull->offset;
 	} else {
 		highest_ofs = ndr_pull->relative_highest_offset;
 	}
 
+	if (dumpdata) {
+		printf("%d bytes consumed\n", highest_ofs);
+		ndrdump_data(blob.data, blob.length, dumpdata);
+	}
+
+	if (!print_after_parse_failure && !NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		TALLOC_FREE(mem_ctx);
+		exit(2);
+	}
+
 	if (highest_ofs != ndr_pull->data_size) {
 		printf("WARNING! %d unread bytes\n", ndr_pull->data_size - highest_ofs);
 		ndrdump_data(ndr_pull->data+highest_ofs,
@@ -563,9 +617,10 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
 			     dumpdata);
 	}
 
-	if (dumpdata) {
-		printf("%d bytes consumed\n", highest_ofs);
-		ndrdump_data(blob.data, blob.length, dumpdata);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		printf("WARNING: pull of %s was incomplete, "
+		       "therefore the parse below may SEGFAULT\n",
+			f->name);
 	}
 
 	f->ndr_print(ndr_print, format, flags, st);
@@ -602,10 +657,11 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
 		}
 
 		ndr_err = f->ndr_push(ndr_v_push, flags, st);
-		status = ndr_map_error2ntstatus(ndr_err);
-		printf("push returned %s\n", nt_errstr(status));
+		printf("push returned %s\n",
+		       ndr_map_error2string(ndr_err));
 		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 			printf("validate push FAILED\n");
+			TALLOC_FREE(mem_ctx);
 			exit(1);
 		}
 
@@ -619,6 +675,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
 		ndr_v_pull = ndr_pull_init_blob(&v_blob, mem_ctx);
 		if (ndr_v_pull == NULL) {
 			perror("ndr_pull_init_blob");
+			TALLOC_FREE(mem_ctx);
 			exit(1);
 		}
 		ndr_v_pull->flags |= LIBNDR_FLAG_REF_ALLOC;
@@ -628,6 +685,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
 		       ndr_map_error2string(ndr_err));
 		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 			printf("validate pull FAILED\n");
+			TALLOC_FREE(mem_ctx);
 			exit(1);
 		}
 
@@ -689,7 +747,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
 	}
 
 	printf("dump OK\n");
-	talloc_free(mem_ctx);
+	TALLOC_FREE(mem_ctx);
 
 	poptFreeContext(pc);
 	
diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
index 8759e46aedb..c1a2cc99cb7 100644
--- a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
@@ -1247,10 +1247,14 @@ sub ParseElementPullLevel
 
 		if ($deferred and ContainsDeferred($e, $l)) {
 			$self->pidl("for ($counter = 0; $counter < ($length); $counter++) {");
+			$self->defer("for ($counter = 0; $counter < ($length); $counter++) {");
+			$self->defer_indent;
 			$self->indent;
 			$self->ParseElementPullLevel($e,GetNextLevel($e,$l), $ndr, $var_name, $env, 0, 1);
 			$self->deindent;
+			$self->defer_deindent;
 			$self->pidl("}");
+			$self->defer("}");
 		}
 
 		$self->ParseMemCtxPullEnd($e, $l, $ndr);
diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py
index fef21d261ca..3f22eaa1c94 100644
--- a/python/samba/tests/__init__.py
+++ b/python/samba/tests/__init__.py
@@ -438,6 +438,7 @@ class BlackboxTestCase(TestCaseInTempDir):
                                        stdoutdata,
                                        stderrdata,
                                        msg)
+        return stdoutdata
 
     def check_output(self, line):
         use_shell = not isinstance(line, list)
diff --git a/python/samba/tests/blackbox/ndrdump.py b/python/samba/tests/blackbox/ndrdump.py
index 4e638c920d8..ca637b3ac7b 100644
--- a/python/samba/tests/blackbox/ndrdump.py
+++ b/python/samba/tests/blackbox/ndrdump.py
@@ -110,3 +110,103 @@ dump OK
         # check_output will return bytes
         # convert expected to bytes for python 3
         self.assertEqual(actual, expected.encode('utf-8'))
+
+    def test_ndrdump_fuzzed_clusapi_QueryAllValues(self):
+        expected = b'''pull returned Success
+WARNING! 53 unread bytes
+[0000] 00 FF 00 00 FF 00 00 00   00 09 00 00 00 08 00 33   ........ .......3
+[0010] 33 32 37 36 32 36 39 33   32 37 36 38 34 01 00 00   32762693 27684...
+[0020] 80 32 0D FF 00 00 FF 00   00 00 00 08 00 00 00 1C   .2...... ........
+[0030] F1 29 08 00 00                                     .)... ''' \
+        b'''
+    clusapi_QueryAllValues: struct clusapi_QueryAllValues
+        out: struct clusapi_QueryAllValues
+            pcbData                  : *
+                pcbData                  : 0x01000000 (16777216)
+            ppData                   : *
+                ppData: ARRAY(1)
+                    ppData                   : NULL
+            rpc_status               : *
+                rpc_status               : WERR_OK
+            result                   : WERR_NOT_ENOUGH_MEMORY
+dump OK
+'''
+        try:
+            actual = self.check_output(
+                'ndrdump clusapi clusapi_QueryAllValues out ' +\
+                '--base64-input --input=' +\
+                'AAAAAQEAAAAAAAAAAAAAAAgAAAAA/wAA/wAAAAAJAAAACAAzMzI3NjI2OTMyNzY4NAEAAIAyDf8AAP8AAAAACAAAABzxKQgAAA==')
+        except BlackboxProcessError as e:
+            self.fail(e)
+        self.assertEqual(actual, expected)
+
+    def test_ndrdump_fuzzed_IOXIDResolver_ResolveOxid(self):
+        expected = '''pull returned Character Conversion Error
+'''
+        try:
+            actual = self.check_exit_code(
+                'ndrdump IOXIDResolver ResolveOxid out ' +\
+                '--base64-input --input=' +\
+                'c87PMf7CBAUAAAAADgQMBASjfPqKw0KPld6DY87PMfQ=',
+                2)
+        except BlackboxProcessError as e:
+            self.fail(e)
+        self.assertRegex(actual.decode('utf8'), expected + "$")
+
+    def test_ndrdump_fuzzed_IOXIDResolver_ResolveOxid2(self):
+        expected = '''pull returned Buffer Size Error
+'''
+        try:
+            actual = self.check_exit_code(
+                'ndrdump IOXIDResolver ResolveOxid2 out ' +\
+                '--base64-input --input=' +\
+                'AAAAAQ0K9Q0AAAAAAAAAA6ampqampqampqampqampqampqampqamNAAAAAAtNDQ=',
+                2)
+        except BlackboxProcessError as e:
+            self.fail(e)
+        self.assertRegex(actual.decode('utf8'), expected + "$")
+
+    def test_ndrdump_fuzzed_IOXIDResolver_ServerAlive2(self):
+        expected = b'''pull returned Success
+WARNING! 46 unread bytes
+[0000] 0D 36 0A 0A 0A 0A 0A 00   00 00 00 00 00 00 03 00   .6...... ........
+[0010] 00 00 01 00 00 33 39 36   31 36 31 37 37 36 38 34   .....396 16177684
+[0020] 32 34 FC 85 AC 49 0B 61   87 0A 0A 0A F5 00         24...I.a ......
+    ServerAlive: struct ServerAlive
+        out: struct ServerAlive
+            result                   : DOS code 0x01000000
+dump OK
+'''
+        try:
+            actual = self.check_output(
+                'ndrdump IOXIDResolver ServerAlive out ' +\
+                '--base64-input --input=' +\
+                'AAAAAQ02CgoKCgoAAAAAAAAAAwAAAAEAADM5NjE2MTc3Njg0MjT8haxJC2GHCgoK9QA=')
+        except BlackboxProcessError as e:
+            self.fail(e)
+        self.assertEqual(actual, expected)
+
+    def test_ndrdump_fuzzed_IRemoteActivation_RemoteActivation(self):
+        expected = '''pull returned Buffer Size Error
+'''
+        try:
+            actual = self.check_exit_code(
+                'ndrdump IRemoteActivation RemoteActivation out ' +\
+                '--base64-input --input=' +\
+                'AAAAAQAAAAAAAABKAAD/AAAAAP4AAAAAAAAASgAAAAAAAAABIiIjIiIiIiIiIiIiIiMiAAAAAAD/AAAAAAAA',
+                2)
+        except BlackboxProcessError as e:
+            self.fail(e)
+        self.assertRegex(actual.decode('utf8'), expected + "$")
+
+    def test_ndrdump_fuzzed_ntlmsssp_AUTHENTICATE_MESSAGE(self):
+        expected = open(self.data_path("fuzzed_ntlmssp-AUTHENTICATE_MESSAGE.txt")).read()
+        try:
+            actual = self.check_output(
+                "ndrdump ntlmssp AUTHENTICATE_MESSAGE struct --base64-input %s --validate" %
+                self.data_path("fuzzed_ntlmssp-AUTHENTICATE_MESSAGE.b64.txt"))
+        except BlackboxProcessError as e:
+            self.fail(e)
+        # check_output will return bytes
+        # convert expected to bytes for python 3
+        self.assertEqual(actual, expected.encode('utf-8'))
diff --git a/source4/librpc/tests/fuzzed_ntlmssp-AUTHENTICATE_MESSAGE.b64.txt b/source4/librpc/tests/fuzzed_ntlmssp-AUTHENTICATE_MESSAGE.b64.txt
new file mode 100644
index 00000000000..0a10ab03911
--- /dev/null
+++ b/source4/librpc/tests/fuzzed_ntlmssp-AUTHENTICATE_MESSAGE.b64.txt
@@ -0,0 +1 @@
+AA4AAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAzOQAAAAAAAAABAAAAAAAAAAD//gAAAAAAAAAABDMyMTUyMTE1MDI2MzE0Njg3/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+5+T2dekB8vfW3brf3WrDRDczOQAAAAA=
diff --git a/source4/librpc/tests/fuzzed_ntlmssp-AUTHENTICATE_MESSAGE.txt b/source4/librpc/tests/fuzzed_ntlmssp-AUTHENTICATE_MESSAGE.txt
new file mode 100644
index 00000000000..8dbe6e6dac2
--- /dev/null
+++ b/source4/librpc/tests/fuzzed_ntlmssp-AUTHENTICATE_MESSAGE.txt
@@ -0,0 +1,134 @@
+pull returned Success
+WARNING! 188 unread bytes
+[0000] 04 33 32 31 35 32 31 31   35 30 32 36 33 31 34 36   .3215211 50263146
+[0010] 38 37 FE FE FE FE FE FE   FE FE FE FE FE FE FE FE   87...... ........
+[0020] FE FE FE FE FE FE FE FE   FE FE FE FE FE FE FE FE   ........ ........
+[0030] FE FE FE FE FE FE FE FE   FE FE FE FE FE FE FE FE   ........ ........
+[0040] FE FE FE FE FE FE FE FE   FE FE FE FE FE FE FE FE   ........ ........
+[0050] FE FE FE FE FE FE FE FE   FE FE FE FE FE FE FE FE   ........ ........
+[0060] FE FE FE FE FE FE FE FE   FE FE FE FE FE FE FE FE   ........ ........
+[0070] FE FE FE FE FE FE FE FE   FE FE FE FE FE FE FE FE   ........ ........
+[0080] FE FE FE FE FE FE FE FE   FE FE FE FE FE FE FE FE   ........ ........
+[0090] FE FE FE FE FE FE FE FE   FE FE FE FE FE FE FE FE   ........ ........
+[00A0] FE FE FE FE FE E7 E4 F6   75 E9 01 F2 F7 D6 DD BA   ........ u.......
+[00B0] DF DD 6A C3 44 37 33 39   00 00 00 00               ..j.D739 ....
+    AUTHENTICATE_MESSAGE: struct AUTHENTICATE_MESSAGE
+        Signature                : ''
+        MessageType              : UNKNOWN_ENUM_VALUE (0)
+        LmChallengeResponseLen   : 0x0000 (0)
+        LmChallengeResponseMaxLen: 0x0000 (0)
+        LmChallengeResponse      : NULL
+        NtChallengeResponseLen   : 0x0000 (0)
+        NtChallengeResponseMaxLen: 0x0000 (0)
+        NtChallengeResponse      : NULL
+        DomainNameLen            : 0x0000 (0)
+        DomainNameMaxLen         : 0x0000 (0)
+        DomainName               : NULL
+        UserNameLen              : 0x0000 (0)
+        UserNameMaxLen           : 0x0001 (1)


-- 
Samba Shared Repository



More information about the samba-cvs mailing list