From 0cae9d308c475ef15017eebf227e98f566e643af Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 11 Feb 2025 15:33:35 +0100 Subject: [PATCH] s3:tldap: avoid using talloc_tos() Async code should never use it without creating its own stackframe! Signed-off-by: Stefan Metzmacher Reviewed-by: Volker Lendecke --- source3/lib/tldap.c | 32 ++++++++++++++++++++----------- source3/lib/tldap_util.c | 41 ++++++++++++++++++++++++---------------- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/source3/lib/tldap.c b/source3/lib/tldap.c index db06e9f1282..ef6937a85ef 100644 --- a/source3/lib/tldap.c +++ b/source3/lib/tldap.c @@ -703,6 +703,7 @@ static int tldap_msg_msgid(struct tevent_req *req) static void tldap_msg_received(struct tevent_req *subreq) { + TALLOC_CTX *frame = talloc_stackframe(); struct tldap_context *ld = tevent_req_callback_data( subreq, struct tldap_context); struct tevent_req *req; @@ -718,7 +719,7 @@ static void tldap_msg_received(struct tevent_req *subreq) uint8_t type; bool ok; - received = read_ldap_recv(subreq, talloc_tos(), &inbuf, &err); + received = read_ldap_recv(subreq, frame, &inbuf, &err); TALLOC_FREE(subreq); ld->read_req = NULL; if (received == -1) { @@ -726,7 +727,7 @@ static void tldap_msg_received(struct tevent_req *subreq) goto fail; } - data = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH); + data = asn1_init(frame, ASN1_MAX_TREE_DEPTH); if (data == NULL) { /* * We have to disconnect all, we can't tell which of @@ -757,8 +758,8 @@ static void tldap_msg_received(struct tevent_req *subreq) "tldap_msg_received: got msgid 0 of " "type %"PRIu8", disconnecting\n", type); - tldap_context_disconnect(ld, TLDAP_SERVER_DOWN); - return; + status = TLDAP_SERVER_DOWN; + goto fail; } num_pending = talloc_array_length(ld->pending); @@ -791,6 +792,7 @@ static void tldap_msg_received(struct tevent_req *subreq) done: if (num_pending == 0) { + TALLOC_FREE(frame); return; } @@ -801,10 +803,12 @@ static void tldap_msg_received(struct tevent_req *subreq) goto fail; } tevent_req_set_callback(ld->read_req, tldap_msg_received, ld); + TALLOC_FREE(frame); return; fail: tldap_context_disconnect(ld, status); + TALLOC_FREE(frame); } static TLDAPRC tldap_msg_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, @@ -1415,13 +1419,16 @@ static bool tldap_unescape_inplace(char *value, size_t *val_len) static bool tldap_push_filter_basic(struct tldap_context *ld, struct asn1_data *data, + TALLOC_CTX *tmpctx, const char **_s); static bool tldap_push_filter_substring(struct tldap_context *ld, struct asn1_data *data, + TALLOC_CTX *tmpctx, const char *val, const char **_s); static bool tldap_push_filter_int(struct tldap_context *ld, struct asn1_data *data, + TALLOC_CTX *tmpctx, const char **_s) { const char *s = *_s; @@ -1453,7 +1460,7 @@ static bool tldap_push_filter_int(struct tldap_context *ld, tldap_debug(ld, TLDAP_DEBUG_TRACE, "Filter op: NOT\n"); if (!asn1_push_tag(data, TLDAP_FILTER_NOT)) return false; s++; - ret = tldap_push_filter_int(ld, data, &s); + ret = tldap_push_filter_int(ld, data, tmpctx, &s); if (!ret) { return false; } @@ -1472,7 +1479,7 @@ static bool tldap_push_filter_int(struct tldap_context *ld, return false; default: - ret = tldap_push_filter_basic(ld, data, &s); + ret = tldap_push_filter_basic(ld, data, tmpctx, &s); if (!ret) { return false; } @@ -1489,7 +1496,7 @@ static bool tldap_push_filter_int(struct tldap_context *ld, } while (*s) { - ret = tldap_push_filter_int(ld, data, &s); + ret = tldap_push_filter_int(ld, data, tmpctx, &s); if (!ret) { return false; } @@ -1520,9 +1527,9 @@ done: static bool tldap_push_filter_basic(struct tldap_context *ld, struct asn1_data *data, + TALLOC_CTX *tmpctx, const char **_s) { - TALLOC_CTX *tmpctx = talloc_tos(); const char *s = *_s; const char *e; const char *eq; @@ -1693,7 +1700,7 @@ static bool tldap_push_filter_basic(struct tldap_context *ld, /* substring */ if (!asn1_push_tag(data, TLDAP_FILTER_SUB)) return false; if (!asn1_write_OctetString(data, s, e - s)) return false; - ret = tldap_push_filter_substring(ld, data, val, &s); + ret = tldap_push_filter_substring(ld, data, tmpctx, val, &s); if (!ret) { return false; } @@ -1731,10 +1738,10 @@ static bool tldap_push_filter_basic(struct tldap_context *ld, static bool tldap_push_filter_substring(struct tldap_context *ld, struct asn1_data *data, + TALLOC_CTX *tmpctx, const char *val, const char **_s) { - TALLOC_CTX *tmpctx = talloc_tos(); bool initial = true; const char *star; char *chunk; @@ -1830,15 +1837,18 @@ static bool tldap_push_filter(struct tldap_context *ld, struct asn1_data *data, const char *filter) { + TALLOC_CTX *frame = talloc_stackframe(); const char *s = filter; bool ret; - ret = tldap_push_filter_int(ld, data, &s); + ret = tldap_push_filter_int(ld, data, frame, &s); if (ret && *s) { tldap_debug(ld, TLDAP_DEBUG_ERROR, "Incomplete or malformed filter\n"); + TALLOC_FREE(frame); return false; } + TALLOC_FREE(frame); return ret; } diff --git a/source3/lib/tldap_util.c b/source3/lib/tldap_util.c index 89aea4c6a69..bc0b2e75689 100644 --- a/source3/lib/tldap_util.c +++ b/source3/lib/tldap_util.c @@ -179,7 +179,7 @@ bool tldap_add_mod_blobs(TALLOC_CTX *mem_ctx, } if ((i == num_mods) && (talloc_array_length(mods) < num_mods + 1)) { - mods = talloc_realloc(talloc_tos(), mods, struct tldap_mod, + mods = talloc_realloc(mem_ctx, mods, struct tldap_mod, num_mods+1); if (mods == NULL) { return false; @@ -196,17 +196,19 @@ bool tldap_add_mod_str(TALLOC_CTX *mem_ctx, struct tldap_mod **pmods, int *pnum_mods, int mod_op, const char *attrib, const char *str) { + TALLOC_CTX *frame = talloc_stackframe(); DATA_BLOB utf8; bool ret; - if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_UTF8, str, + if (!convert_string_talloc(frame, CH_UNIX, CH_UTF8, str, strlen(str), &utf8.data, &utf8.length)) { + TALLOC_FREE(frame); return false; } ret = tldap_add_mod_blobs(mem_ctx, pmods, pnum_mods, mod_op, attrib, &utf8, 1); - TALLOC_FREE(utf8.data); + TALLOC_FREE(frame); return ret; } @@ -287,24 +289,25 @@ bool tldap_make_mod_blob(struct tldap_message *existing, TALLOC_CTX *mem_ctx, static int compare_utf8_blobs(const DATA_BLOB *d1, const DATA_BLOB *d2) { + TALLOC_CTX *frame = talloc_stackframe(); char *s1, *s2; size_t s1len, s2len; int ret; - if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX, d1->data, + if (!convert_string_talloc(frame, CH_UTF8, CH_UNIX, d1->data, d1->length, &s1, &s1len)) { /* can't do much here */ + TALLOC_FREE(frame); return 0; } - if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX, d2->data, + if (!convert_string_talloc(frame, CH_UTF8, CH_UNIX, d2->data, d2->length, &s2, &s2len)) { /* can't do much here */ - TALLOC_FREE(s1); + TALLOC_FREE(frame); return 0; } ret = strcasecmp_m(s1, s2); - TALLOC_FREE(s2); - TALLOC_FREE(s1); + TALLOC_FREE(frame); return ret; } @@ -312,16 +315,18 @@ bool tldap_make_mod_fmt(struct tldap_message *existing, TALLOC_CTX *mem_ctx, struct tldap_mod **pmods, int *pnum_mods, const char *attrib, const char *fmt, ...) { + TALLOC_CTX *frame = talloc_stackframe(); va_list ap; char *newval; bool ret; DATA_BLOB blob = data_blob_null; va_start(ap, fmt); - newval = talloc_vasprintf(talloc_tos(), fmt, ap); + newval = talloc_vasprintf(frame, fmt, ap); va_end(ap); if (newval == NULL) { + TALLOC_FREE(frame); return false; } @@ -331,7 +336,7 @@ bool tldap_make_mod_fmt(struct tldap_message *existing, TALLOC_CTX *mem_ctx, } ret = tldap_make_mod_blob_int(existing, mem_ctx, pmods, pnum_mods, attrib, blob, compare_utf8_blobs); - TALLOC_FREE(newval); + TALLOC_FREE(frame); return ret; } @@ -355,11 +360,13 @@ TLDAPRC tldap_search_va(struct tldap_context *ld, const char *base, int scope, TALLOC_CTX *mem_ctx, struct tldap_message ***res, const char *fmt, va_list ap) { + TALLOC_CTX *frame = talloc_stackframe(); char *filter; TLDAPRC rc; - filter = talloc_vasprintf(talloc_tos(), fmt, ap); + filter = talloc_vasprintf(frame, fmt, ap); if (filter == NULL) { + TALLOC_FREE(frame); return TLDAP_NO_MEMORY; } @@ -368,7 +375,7 @@ TLDAPRC tldap_search_va(struct tldap_context *ld, const char *base, int scope, NULL /*sctrls*/, 0, NULL /*cctrls*/, 0, 0 /*timelimit*/, 0 /*sizelimit*/, 0 /*deref*/, mem_ctx, res); - TALLOC_FREE(filter); + TALLOC_FREE(frame); return rc; } @@ -390,13 +397,15 @@ TLDAPRC tldap_search_fmt(struct tldap_context *ld, const char *base, int scope, bool tldap_pull_uint64(struct tldap_message *msg, const char *attr, uint64_t *presult) { + TALLOC_CTX *frame = talloc_stackframe(); char *str; uint64_t result; int error = 0; - str = tldap_talloc_single_attribute(msg, attr, talloc_tos()); + str = tldap_talloc_single_attribute(msg, attr, frame); if (str == NULL) { DEBUG(10, ("Could not find attribute %s\n", attr)); + TALLOC_FREE(frame); return false; } @@ -404,11 +413,11 @@ bool tldap_pull_uint64(struct tldap_message *msg, const char *attr, if (error != 0) { DBG_DEBUG("Attribute conversion failed (%s)\n", strerror(error)); - TALLOC_FREE(str); + TALLOC_FREE(frame); return false; } - TALLOC_FREE(str); + TALLOC_FREE(frame); *presult = result; return true; } @@ -784,7 +793,7 @@ static void tldap_search_paged_done(struct tevent_req *subreq) TALLOC_FREE(state->cookie.data); - asn1 = asn1_init(talloc_tos(), ASN1_MAX_TREE_DEPTH); + asn1 = asn1_init(state, ASN1_MAX_TREE_DEPTH); if (tevent_req_nomem(asn1, req)) { return; } -- 2.47.2