]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
ldb: Fix segfault parsing new pack formats
authorAndrew Bartlett <abartlet@samba.org>
Wed, 22 May 2019 04:38:08 +0000 (16:38 +1200)
committerKarolin Seeger <kseeger@samba.org>
Wed, 28 Aug 2019 07:36:29 +0000 (07:36 +0000)
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 <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
(cherry picked from commit a3101b9704f554a350493553336cbbbd7d4ae02e)

lib/ldb/ldb_tdb/ldb_tdb.c

index a83bc34f58b2bbafe19bd5ee1da2bec40c53a6b6..337e7d2ee2224dddc25aa0dcad16e9e08d42db89 100644 (file)
@@ -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));