From: Volker Lendecke Date: Thu, 4 Oct 2018 13:21:01 +0000 (+0200) Subject: tdb: Make tdb_find circular-safe X-Git-Tag: tdb-1.3.17~1390 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e63f7bd3a98023e2400ebb99a0f83098eb708eb5;p=thirdparty%2Fsamba.git tdb: Make tdb_find circular-safe Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison --- diff --git a/lib/tdb/common/tdb.c b/lib/tdb/common/tdb.c index 62df8eb1d32..c16e5779b87 100644 --- a/lib/tdb/common/tdb.c +++ b/lib/tdb/common/tdb.c @@ -114,13 +114,18 @@ static tdb_off_t tdb_find(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, struct tdb_record *r) { tdb_off_t rec_ptr; + struct tdb_chainwalk_ctx chainwalk; /* read in the hash top */ if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) return 0; + tdb_chainwalk_init(&chainwalk, rec_ptr); + /* keep looking until we find the right record */ while (rec_ptr) { + bool ok; + if (tdb_rec_read(tdb, rec_ptr, r) == -1) return 0; @@ -131,13 +136,12 @@ static tdb_off_t tdb_find(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, NULL) == 0) { return rec_ptr; } - /* detect tight infinite loop */ - if (rec_ptr == r->next) { - tdb->ecode = TDB_ERR_CORRUPT; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_find: loop detected.\n")); + rec_ptr = r->next; + + ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); + if (!ok) { return 0; } - rec_ptr = r->next; } tdb->ecode = TDB_ERR_NOEXIST; return 0;