From: Andrew Bartlett Date: Wed, 22 May 2019 04:38:08 +0000 (+1200) Subject: ldb: Fix segfault parsing new pack formats X-Git-Tag: ldb-1.4.8~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3cb3b34def330b57b008a02c027d8ea658ae487c;p=thirdparty%2Fsamba.git 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 Reviewed-by: Garming Sam (cherry picked from commit a3101b9704f554a350493553336cbbbd7d4ae02e) --- 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));