From b01952c6fb15b92fff3ad1bf8f1cf579875e5483 Mon Sep 17 00:00:00 2001
From: Gary Lockyer <gary@catalyst.net.nz>
Date: Fri, 3 Apr 2020 12:18:03 +1300
Subject: [PATCH 1/8] CVE-2020-10704: lib util asn1: Add ASN.1 max tree depth

Add maximum parse tree depth to the call to asn1_init, which will be
used to limit the depth of the ASN.1 parse tree.

Credit to OSS-Fuzz

REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20454
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14334

Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
---
 auth/gensec/gensec_util.c           |  2 +-
 lib/util/asn1.c                     | 17 +++++++++-
 lib/util/asn1.h                     |  9 +++++-
 lib/util/tests/asn1_tests.c         |  2 +-
 libcli/auth/spnego_parse.c          |  6 ++--
 libcli/cldap/cldap.c                |  2 +-
 libcli/ldap/ldap_message.c          |  2 +-
 source3/lib/tldap.c                 |  4 +--
 source3/lib/tldap_util.c            |  4 +--
 source3/libsmb/clispnego.c          |  4 +--
 source3/torture/torture.c           |  2 +-
 source4/auth/gensec/gensec_krb5.c   |  4 +--
 source4/ldap_server/ldap_server.c   |  2 +-
 source4/libcli/ldap/ldap_client.c   |  2 +-
 source4/libcli/ldap/ldap_controls.c | 48 ++++++++++++++---------------
 15 files changed, 66 insertions(+), 44 deletions(-)

diff --git a/auth/gensec/gensec_util.c b/auth/gensec/gensec_util.c
index 20c9c2a1fbb..e185acc0c20 100644
--- a/auth/gensec/gensec_util.c
+++ b/auth/gensec/gensec_util.c
@@ -76,7 +76,7 @@ NTSTATUS gensec_generate_session_info_pac(TALLOC_CTX *mem_ctx,
 static bool gensec_gssapi_check_oid(const DATA_BLOB *blob, const char *oid)
 {
 	bool ret = false;
-	struct asn1_data *data = asn1_init(NULL);
+	struct asn1_data *data = asn1_init(NULL, ASN1_MAX_TREE_DEPTH);
 
 	if (!data) return false;
 
diff --git a/lib/util/asn1.c b/lib/util/asn1.c
index 51da5424956..ec6e674ce20 100644
--- a/lib/util/asn1.c
+++ b/lib/util/asn1.c
@@ -36,15 +36,19 @@ struct asn1_data {
 	off_t ofs;
 	struct nesting *nesting;
 	bool has_error;
+	unsigned depth;
+	unsigned max_depth;
 };
 
 /* allocate an asn1 structure */
-struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx)
+struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx, unsigned max_depth)
 {
 	struct asn1_data *ret = talloc_zero(mem_ctx, struct asn1_data);
 	if (ret == NULL) {
 		DEBUG(0,("asn1_init failed! out of memory\n"));
+		return ret;
 	}
+	ret->max_depth = max_depth;
 	return ret;
 }
 
@@ -480,6 +484,11 @@ bool asn1_check_BOOLEAN(struct asn1_data *data, bool v)
 /* load a struct asn1_data structure with a lump of data, ready to be parsed */
 bool asn1_load(struct asn1_data *data, DATA_BLOB blob)
 {
+	/*
+	 * Save the maximum depth
+	 */
+	unsigned max_depth = data->max_depth;
+
 	ZERO_STRUCTP(data);
 	data->data = (uint8_t *)talloc_memdup(data, blob.data, blob.length);
 	if (!data->data) {
@@ -487,6 +496,7 @@ bool asn1_load(struct asn1_data *data, DATA_BLOB blob)
 		return false;
 	}
 	data->length = blob.length;
+	data->max_depth = max_depth;
 	return true;
 }
 
@@ -1103,9 +1113,14 @@ bool asn1_extract_blob(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
 */
 void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len)
 {
+	/*
+	 * Save max_depth
+	 */
+	unsigned max_depth = data->max_depth;
 	ZERO_STRUCTP(data);
 	data->data = buf;
 	data->length = len;
+	data->max_depth = max_depth;
 }
 
 int asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size)
diff --git a/lib/util/asn1.h b/lib/util/asn1.h
index ddd69863574..fc365724e93 100644
--- a/lib/util/asn1.h
+++ b/lib/util/asn1.h
@@ -45,7 +45,14 @@ typedef struct asn1_data ASN1_DATA;
 
 #define ASN1_MAX_OIDS 20
 
-struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx);
+/*
+ * The maximum permitted depth for an ASN.1 parse tree, the limit is chosen
+ * to align with the value for windows. Note that this value will trigger
+ * ASAN stack overflow errors.
+ */
+#define ASN1_MAX_TREE_DEPTH 512
+
+struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx, unsigned max_depth);
 void asn1_free(struct asn1_data *data);
 bool asn1_has_error(const struct asn1_data *data);
 void asn1_set_error(struct asn1_data *data);
diff --git a/lib/util/tests/asn1_tests.c b/lib/util/tests/asn1_tests.c
index e4b386ad785..ab5262c4ffb 100644
--- a/lib/util/tests/asn1_tests.c
+++ b/lib/util/tests/asn1_tests.c
@@ -330,7 +330,7 @@ static bool test_asn1_Integer(struct torture_context *tctx)
 		DATA_BLOB blob;
 		int val;
 
-		data = asn1_init(mem_ctx);
+		data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 		if (!data) {
 			goto err;
 		}
diff --git a/libcli/auth/spnego_parse.c b/libcli/auth/spnego_parse.c
index f538b44552c..f7f19b10778 100644
--- a/libcli/auth/spnego_parse.c
+++ b/libcli/auth/spnego_parse.c
@@ -296,7 +296,7 @@ ssize_t spnego_read_data(TALLOC_CTX *mem_ctx, DATA_BLOB data, struct spnego_data
 		return ret;
 	}
 
-	asn1 = asn1_init(mem_ctx);
+	asn1 = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 	if (asn1 == NULL) {
 		return -1;
 	}
@@ -339,7 +339,7 @@ ssize_t spnego_read_data(TALLOC_CTX *mem_ctx, DATA_BLOB data, struct spnego_data
 
 ssize_t spnego_write_data(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct spnego_data *spnego)
 {
-	struct asn1_data *asn1 = asn1_init(mem_ctx);
+	struct asn1_data *asn1 = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 	ssize_t ret = -1;
 
 	if (asn1 == NULL) {
@@ -411,7 +411,7 @@ bool spnego_write_mech_types(TALLOC_CTX *mem_ctx,
 			     DATA_BLOB *blob)
 {
 	bool ret = false;
-	struct asn1_data *asn1 = asn1_init(mem_ctx);
+	struct asn1_data *asn1 = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 
 	if (asn1 == NULL) {
 		return false;
diff --git a/libcli/cldap/cldap.c b/libcli/cldap/cldap.c
index daba37a21d7..8fa9ce0b273 100644
--- a/libcli/cldap/cldap.c
+++ b/libcli/cldap/cldap.c
@@ -229,7 +229,7 @@ static bool cldap_socket_recv_dgram(struct cldap_socket *c,
 		goto error;
 	}
 
-	asn1 = asn1_init(in);
+	asn1 = asn1_init(in, ASN1_MAX_TREE_DEPTH);
 	if (!asn1) {
 		goto nomem;
 	}
diff --git a/libcli/ldap/ldap_message.c b/libcli/ldap/ldap_message.c
index f21598374a1..ba82bddeab1 100644
--- a/libcli/ldap/ldap_message.c
+++ b/libcli/ldap/ldap_message.c
@@ -390,7 +390,7 @@ _PUBLIC_ bool ldap_encode(struct ldap_message *msg,
 			  const struct ldap_control_handler *control_handlers,
 			  DATA_BLOB *result, TALLOC_CTX *mem_ctx)
 {
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 	int i, j;
 
 	if (!data) return false;
diff --git a/source3/lib/tldap.c b/source3/lib/tldap.c
index d6c6e8859a6..bf5fc05d785 100644
--- a/source3/lib/tldap.c
+++ b/source3/lib/tldap.c
@@ -632,7 +632,7 @@ static void tldap_msg_received(struct tevent_req *subreq)
 		goto fail;
 	}
 
-	data = asn1_init(talloc_tos());
+	data = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH);
 	if (data == NULL) {
 		status = TLDAP_NO_MEMORY;
 		goto fail;
@@ -763,7 +763,7 @@ static struct tevent_req *tldap_req_create(TALLOC_CTX *mem_ctx,
 	if (req == NULL) {
 		return NULL;
 	}
-	state->out = asn1_init(state);
+	state->out = asn1_init(state, ASN1_MAX_TREE_DEPTH);
 	if (state->out == NULL) {
 		goto err;
 	}
diff --git a/source3/lib/tldap_util.c b/source3/lib/tldap_util.c
index 1b86962a32e..168932a8a96 100644
--- a/source3/lib/tldap_util.c
+++ b/source3/lib/tldap_util.c
@@ -644,7 +644,7 @@ static struct tevent_req *tldap_ship_paged_search(
 	struct tldap_control *pgctrl;
 	struct asn1_data *asn1 = NULL;
 
-	asn1 = asn1_init(state);
+	asn1 = asn1_init(state, ASN1_MAX_TREE_DEPTH);
 	if (asn1 == NULL) {
 		return NULL;
 	}
@@ -783,7 +783,7 @@ static void tldap_search_paged_done(struct tevent_req *subreq)
 
 	TALLOC_FREE(state->cookie.data);
 
-	asn1 = asn1_init(talloc_tos());
+	asn1 = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH);
 	if (tevent_req_nomem(asn1, req)) {
 		return;
 	}
diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c
index 4a0fbcd73af..1608f6a9960 100644
--- a/source3/libsmb/clispnego.c
+++ b/source3/libsmb/clispnego.c
@@ -50,7 +50,7 @@ bool spnego_parse_negTokenInit(TALLOC_CTX *ctx,
 		*secblob = data_blob_null;
 	}
 
-	data = asn1_init(talloc_tos());
+	data = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH);
 	if (data == NULL) {
 		return false;
 	}
@@ -171,7 +171,7 @@ DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const ui
 	ASN1_DATA *data;
 	DATA_BLOB ret = data_blob_null;
 
-	data = asn1_init(talloc_tos());
+	data = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH);
 	if (data == NULL) {
 		return data_blob_null;
 	}
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index a795e61125f..c4b0a7bc4f9 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -11370,7 +11370,7 @@ tldap_build_extended_control(enum tldap_extended_val val)
 	ZERO_STRUCT(empty_control);
 
 	if (val != EXTENDED_NONE) {
-		data = asn1_init(talloc_tos());
+		data = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH);
 
 		if (!data) {
 			return NULL;
diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c
index 0323da87d29..b735063656a 100644
--- a/source4/auth/gensec/gensec_krb5.c
+++ b/source4/auth/gensec/gensec_krb5.c
@@ -444,7 +444,7 @@ static DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLO
 	struct asn1_data *data;
 	DATA_BLOB ret = data_blob_null;
 
-	data = asn1_init(mem_ctx);
+	data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 	if (!data || !ticket->data) {
 		return ret;
 	}
@@ -478,7 +478,7 @@ static DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLO
 static bool gensec_gssapi_parse_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, DATA_BLOB *ticket, uint8_t tok_id[2])
 {
 	bool ret = false;
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 	int data_remaining;
 
 	if (!data) {
diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c
index 709b7bcacfa..6d329329909 100644
--- a/source4/ldap_server/ldap_server.c
+++ b/source4/ldap_server/ldap_server.c
@@ -560,7 +560,7 @@ static void ldapsrv_call_read_done(struct tevent_req *subreq)
 		return;
 	}
 
-	asn1 = asn1_init(call);
+	asn1 = asn1_init(call, ASN1_MAX_TREE_DEPTH);
 	if (asn1 == NULL) {
 		ldapsrv_terminate_connection(conn, "no memory");
 		return;
diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c
index da84adc7769..2d75af6af6e 100644
--- a/source4/libcli/ldap/ldap_client.c
+++ b/source4/libcli/ldap/ldap_client.c
@@ -284,7 +284,7 @@ static void ldap_connection_recv_done(struct tevent_req *subreq)
 		return;
 	}
 
-	asn1 = asn1_init(conn);
+	asn1 = asn1_init(conn, ASN1_MAX_TREE_DEPTH);
 	if (asn1 == NULL) {
 		TALLOC_FREE(msg);
 		ldap_error_handler(conn, NT_STATUS_NO_MEMORY);
diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c
index 716ca148308..df012a158e0 100644
--- a/source4/libcli/ldap/ldap_controls.c
+++ b/source4/libcli/ldap/ldap_controls.c
@@ -32,7 +32,7 @@ static bool decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void *_out)
 {
 	void **out = (void **)_out;
 	DATA_BLOB attr;
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 	struct ldb_sort_resp_control *lsrc;
 
 	if (!data) return false;
@@ -79,7 +79,7 @@ static bool decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void *_out)
 	void **out = (void **)_out;
 	DATA_BLOB attr;
 	DATA_BLOB rule;
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 	struct ldb_server_sort_control **lssc;
 	int num;
 
@@ -166,7 +166,7 @@ static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void *_out)
 		return true;
 	}
 
-	data = asn1_init(mem_ctx);
+	data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 	if (!data) return false;
 
 	if (!asn1_load(data, in)) {
@@ -198,7 +198,7 @@ static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void *_out)
 static bool decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void *_out)
 {
 	void **out = (void **)_out;
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 	struct ldb_sd_flags_control *lsdfc;
 
 	if (!data) return false;
@@ -232,7 +232,7 @@ static bool decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void *_out)
 static bool decode_search_options_request(void *mem_ctx, DATA_BLOB in, void *_out)
 {
 	void **out = (void **)_out;
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 	struct ldb_search_options_control *lsoc;
 
 	if (!data) return false;
@@ -267,7 +267,7 @@ static bool decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void *_out
 {
 	void **out = (void **)_out;
 	DATA_BLOB cookie;
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 	struct ldb_paged_control *lprc;
 
 	if (!data) return false;
@@ -316,7 +316,7 @@ static bool decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void *_out)
 {
 	void **out = (void **)_out;
 	DATA_BLOB cookie;
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 	struct ldb_dirsync_control *ldc;
 
 	if (!data) return false;
@@ -372,7 +372,7 @@ static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void *_out)
 {
 	void **out = (void **)_out;
 	DATA_BLOB source_attribute;
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 	struct ldb_asq_control *lac;
 
 	if (!data) return false;
@@ -433,7 +433,7 @@ static bool decode_verify_name_request(void *mem_ctx, DATA_BLOB in, void *_out)
 {
 	void **out = (void **)_out;
 	DATA_BLOB name;
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 	struct ldb_verify_name_control *lvnc;
 	int len;
 
@@ -485,7 +485,7 @@ static bool decode_verify_name_request(void *mem_ctx, DATA_BLOB in, void *_out)
 static bool encode_verify_name_request(void *mem_ctx, void *in, DATA_BLOB *out)
 {
 	struct ldb_verify_name_control *lvnc = talloc_get_type(in, struct ldb_verify_name_control);
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 	DATA_BLOB gc_utf16;
 
 	if (!data) return false;
@@ -528,7 +528,7 @@ static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void *_out)
 {
 	void **out = (void **)_out;
 	DATA_BLOB assertion_value, context_id;
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 	struct ldb_vlv_req_control *lvrc;
 
 	if (!data) return false;
@@ -626,7 +626,7 @@ static bool decode_vlv_response(void *mem_ctx, DATA_BLOB in, void *_out)
 {
 	void **out = (void **)_out;
 	DATA_BLOB context_id;
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 	struct ldb_vlv_resp_control *lvrc;
 
 	if (!data) return false;
@@ -682,7 +682,7 @@ static bool decode_vlv_response(void *mem_ctx, DATA_BLOB in, void *_out)
 static bool encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out)
 {
 	struct ldb_sort_resp_control *lsrc = talloc_get_type(in, struct ldb_sort_resp_control);
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 
 	if (!data) return false;
 
@@ -716,7 +716,7 @@ static bool encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out)
 static bool encode_server_sort_request(void *mem_ctx, void *in, DATA_BLOB *out)
 {
 	struct ldb_server_sort_control **lssc = talloc_get_type(in, struct ldb_server_sort_control *);
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 	int num;
 
 	if (!data) return false;
@@ -782,7 +782,7 @@ static bool encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out)
 		return true;
 	}
 
-	data = asn1_init(mem_ctx);
+	data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 
 	if (!data) return false;
 
@@ -810,7 +810,7 @@ static bool encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out)
 static bool encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out)
 {
 	struct ldb_sd_flags_control *lsdfc = talloc_get_type(in, struct ldb_sd_flags_control);
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 
 	if (!data) return false;
 
@@ -838,7 +838,7 @@ static bool encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out)
 static bool encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *out)
 {
 	struct ldb_search_options_control *lsoc = talloc_get_type(in, struct ldb_search_options_control);
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 
 	if (!data) return false;
 
@@ -866,7 +866,7 @@ static bool encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *ou
 static bool encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out)
 {
 	struct ldb_paged_control *lprc = talloc_get_type(in, struct ldb_paged_control);
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 
 	if (!data) return false;
 
@@ -901,7 +901,7 @@ static bool encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out
 static bool encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out)
 {
 	struct ldb_asq_control *lac = talloc_get_type(in, struct ldb_asq_control);
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 
 	if (!data) return false;
 
@@ -936,7 +936,7 @@ static bool encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out)
 static bool encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out)
 {
 	struct ldb_dirsync_control *ldc = talloc_get_type(in, struct ldb_dirsync_control);
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 
 	if (!data) return false;
 
@@ -972,7 +972,7 @@ static bool encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out)
 static bool encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out)
 {
 	struct ldb_vlv_req_control *lvrc = talloc_get_type(in, struct ldb_vlv_req_control);
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 
 	if (!data) return false;
 
@@ -1040,7 +1040,7 @@ static bool encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out)
 static bool encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out)
 {
 	struct ldb_vlv_resp_control *lvrc = talloc_get_type(in, struct ldb_vlv_resp_control);
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 
 	if (!data) return false;
 
@@ -1083,7 +1083,7 @@ static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out)
 {
 	struct dsdb_openldap_dereference_control *control = talloc_get_type(in, struct dsdb_openldap_dereference_control);
 	int i,j;
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 
 	if (!data) return false;
 	
@@ -1132,7 +1132,7 @@ static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out)
 static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void *_out)
 {
 	void **out = (void **)_out;
-	struct asn1_data *data = asn1_init(mem_ctx);
+	struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
 	struct dsdb_openldap_dereference_result_control *control;
 	struct dsdb_openldap_dereference_result **r = NULL;
 	int i = 0;
-- 
2.17.1


