From c8a28a5bf14178641c8d1d24e756374ed66b2dd8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 22 May 2019 16:38:08 +1200 Subject: [PATCH] ldb: Fix segfault parsing new pack formats We need to check for the errors given by ldb_unpack() et al by preserving the error code from kv_ctx->parser() called by tdb_parse_record() in ltdb_parse_record(). Otherwise we will silently accept corrupt records and segfault later. Likewise new pack formats will confuse the parser but not be detected except by the incomplete struct ldb_message. With this patch, the user will see a message like: Invalid data for index DN=@BASEINFO Failed to connect to 'st/ad_dc/private/sam.ldb' with backend 'tdb': Unable to load ltdb cache records for backend 'ldb_tdb backend' Failed to connect to st/ad_dc/private/sam.ldb - Unable to load ltdb cache records for backend 'ldb_tdb backend' This can be refined in the future by a specific check for pack format versions in a higher caller, but this much is needed regardless to detect corrupt records. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13959 Signed-off-by: Andrew Bartlett --- lib/ldb/ldb_tdb/ldb_tdb.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/ldb/ldb_tdb/ldb_tdb.c b/lib/ldb/ldb_tdb/ldb_tdb.c index 2f0468fd40a..6e2cb633a4d 100644 --- a/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/lib/ldb/ldb_tdb/ldb_tdb.c @@ -242,6 +242,7 @@ struct kv_ctx { int (*parser)(struct ldb_val key, struct ldb_val data, void *private_data); + int parser_ret; }; static int ltdb_traverse_fn_wrapper(struct tdb_context *tdb, @@ -350,7 +351,8 @@ static int ltdb_parse_record_wrapper(TDB_DATA tdb_key, .data = tdb_data.dptr, }; - return kv_ctx->parser(key, data, kv_ctx->ctx); + kv_ctx->parser_ret = kv_ctx->parser(key, data, kv_ctx->ctx); + return kv_ctx->parser_ret; } static int ltdb_parse_record(struct ldb_kv_private *ldb_kv, @@ -374,7 +376,9 @@ static int ltdb_parse_record(struct ldb_kv_private *ldb_kv, ret = tdb_parse_record( ldb_kv->tdb, key, ltdb_parse_record_wrapper, &kv_ctx); - if (ret == 0) { + if (kv_ctx.parser_ret != LDB_SUCCESS) { + return kv_ctx.parser_ret; + } else if (ret == 0) { return LDB_SUCCESS; } return ltdb_err_map(tdb_error(ldb_kv->tdb)); -- 2.11.0