CVE-2020-10704: lib util asn1: Add ASN.1 max tree depth
authorGary Lockyer <gary@catalyst.net.nz>
Thu, 2 Apr 2020 23:18:03 +0000 (12:18 +1300)
committerGary Lockyer <gary@samba.org>
Mon, 4 May 2020 02:59:31 +0000 (02:59 +0000)
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>
16 files changed:
auth/gensec/gensec_util.c
lib/fuzzing/fuzz_ldap_decode.c
lib/util/asn1.c
lib/util/asn1.h
lib/util/tests/asn1_tests.c
libcli/auth/spnego_parse.c
libcli/cldap/cldap.c
libcli/ldap/ldap_message.c
source3/lib/tldap.c
source3/lib/tldap_util.c
source3/libsmb/clispnego.c
source3/torture/torture.c
source4/auth/gensec/gensec_krb5.c
source4/ldap_server/ldap_server.c
source4/libcli/ldap/ldap_client.c
source4/libcli/ldap/ldap_controls.c

index 20c9c2a1fbb745a02b11506202f637d9f53ef686..e185acc0c2055917876df0151b4b417749f26903 100644 (file)
@@ -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;
 
index 659169aca9667b167c887a2f0d1da547b2c26f79..d89ba6370612745e6634adbcdcb33ce23e186da8 100644 (file)
@@ -34,7 +34,11 @@ int LLVMFuzzerTestOneInput(uint8_t *buf, size_t len)
        struct ldap_message *ldap_msg;
        NTSTATUS status;
 
-       asn1 = asn1_init(mem_ctx);
+       /*
+        * Need to limit the max parse tree depth to 250 to prevent
+        * ASAN detecting stack overflows.
+        */
+       asn1 = asn1_init(mem_ctx, 250);
        if (!asn1) {
                goto out;
        }
index 6ae54d4cf20aba6b08a6a7c8454baef1d9700472..868bd218c9eef8d4b065b0e29995b49b36278991 100644 (file)
@@ -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;
 }
 
@@ -1119,9 +1129,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)
index ddd6986357435c620300d35660ed4ab38822feae..fc365724e936e89678b6d753ae5c18aa66fc7452 100644 (file)
@@ -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);
index e4b386ad785aee637ee81aa00bc37850b1cae2d7..ab5262c4ffb510e0c992d681d71f71ac050b3345 100644 (file)
@@ -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;
                }
index f538b44552cbc81f4be59cfd1c43fa60d5ad4731..f7f19b107788f7a926b1bd691e597625da5c43fa 100644 (file)
@@ -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;
index f609bf278e4b09610ef79be208d6b8c9bca8cbbd..3f68772851722a5de3645812de8748178f0d6d91 100644 (file)
@@ -233,7 +233,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;
        }
index f21598374a19542ec5ac09038545e9ad8186f416..ba82bddeab10ac0302f36a332752ffb1563cb41e 100644 (file)
@@ -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;
index d6c6e8859a60d51e23b86a41f560ecd98165ecbd..bf5fc05d785eab711e1bc424d6d793e2d6011d3b 100644 (file)
@@ -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;
        }
index 1b86962a32efd7e18bfee870bb3b95752b52bef2..168932a8a96d32870b3b9b73f5e92eb47a1ffbee 100644 (file)
@@ -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;
        }
index 4a0fbcd73af29934eb4e9fa3607266d2272686d3..1608f6a99603cc5402bbd090b876758920599f63 100644 (file)
@@ -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;
        }
index b7c0dd3f73dde3b21752d8c9580691a2c089d9c7..c3d8fb4e30ca09b9b043d86eb02c2d725aec42bb 100644 (file)
@@ -11975,7 +11975,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;
index 866ecc821337d99f221510ff3a1940250ba34ac8..45abbb97b6bba0cd02f2374b8628ce65de0b7730 100644 (file)
@@ -438,7 +438,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;
        }
@@ -472,7 +472,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) {
index 709b7bcacfac9d6d86c073fa2a9a276b63fc4977..6d32932990988ebc938284d5446a3ef778b88f1c 100644 (file)
@@ -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;
index a5defbcb4e3f6853f15a95e9ced92e0c7ecc2715..319ef3a60a7c1ef7743d8bed5a3dc74fc6ab9cb8 100644 (file)
@@ -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);
index 716ca148308799526d2aefc548a7f624a2a2d1be..df012a158e08014c973a33bd45f37eb0a4e71f31 100644 (file)
@@ -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;