tdb: Make the freelist walk circular-safe
authorVolker Lendecke <vl@samba.org>
Thu, 4 Oct 2018 15:12:42 +0000 (17:12 +0200)
committerJeremy Allison <jra@samba.org>
Mon, 8 Oct 2018 20:17:11 +0000 (22:17 +0200)
We can't really do the full check while the freelist is modified on the
fly. As long as we don't merge any freelist entries, we should be good
to apply this check.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
lib/tdb/common/freelist.c

index a19289a399c8c72f975d27c938c58c9ea1554bcf..8870a418328bc1682059c805f9aa2d673994b525 100644 (file)
@@ -444,6 +444,8 @@ static tdb_off_t tdb_allocate_from_freelist(
        struct tdb_context *tdb, tdb_len_t length, struct tdb_record *rec)
 {
        tdb_off_t rec_ptr, last_ptr, newrec_ptr;
+       struct tdb_chainwalk_ctx chainwalk;
+       bool modified;
        struct {
                tdb_off_t rec_ptr, last_ptr;
                tdb_len_t rec_len;
@@ -466,6 +468,9 @@ static tdb_off_t tdb_allocate_from_freelist(
        if (tdb_ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1)
                return 0;
 
+       modified = false;
+       tdb_chainwalk_init(&chainwalk, rec_ptr);
+
        bestfit.rec_ptr = 0;
        bestfit.last_ptr = 0;
        bestfit.rec_len = 0;
@@ -526,6 +531,8 @@ static tdb_off_t tdb_allocate_from_freelist(
                                merge_created_candidate = true;
                        }
 
+                       modified = true;
+
                        continue;
                }
 
@@ -542,6 +549,14 @@ static tdb_off_t tdb_allocate_from_freelist(
                last_ptr = rec_ptr;
                rec_ptr = rec->next;
 
+               if (!modified) {
+                       bool ok;
+                       ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr);
+                       if (!ok) {
+                               return 0;
+                       }
+               }
+
                /* if we've found a record that is big enough, then
                   stop searching if its also not too big. The
                   definition of 'too big' changes as we scan