From 94b8dd4bcaadaf182526349b226f3101a292301c 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 a83bc34f58b..337e7d2ee22 100644 --- a/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/lib/ldb/ldb_tdb/ldb_tdb.c @@ -1904,6 +1904,7 @@ struct kv_ctx { int (*parser)(struct ldb_val key, struct ldb_val data, void *private_data); + int parser_ret; }; static int ldb_tdb_traverse_fn_wrapper(struct tdb_context *tdb, TDB_DATA tdb_key, TDB_DATA tdb_data, void *ctx) @@ -1999,7 +2000,8 @@ static int ltdb_tdb_parse_record_wrapper(TDB_DATA tdb_key, TDB_DATA tdb_data, .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_tdb_parse_record(struct ltdb_private *ltdb, @@ -2027,7 +2029,9 @@ static int ltdb_tdb_parse_record(struct ltdb_private *ltdb, ret = tdb_parse_record(ltdb->tdb, key, ltdb_tdb_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(ltdb->tdb)); -- 2.11.0