Skip to content

btree_next hangs when encountering deleted entries #4132

@yoav-orca

Description

@yoav-orca

Describe the bug
running rpm query on a bdb backend with deleted entry results in an infinite loop.

rpm --define "_db_backend bdb_ro" --nosignature --dbpath /tmp/rpmdb -q abc

To Reproduce
Steps to reproduce the behavior:

  1. Download attached database file minimal-rpmdb-bdbro-hang-repro.tar.gz
  2. timeout 10s rpm --define "_db_backend bdb_ro" --nosignature --dbpath /tmp/rpmdb -q abc
  3. echo $? (will be 124)

Please link or attach the packages or spec files involved.

Expected behavior
The command should not hang

Output
If applicable, add copy of the output on the command line or a screenshots to help explain your problem.

Environment

  • OS / Distribution:
PRETTY_NAME="Debian GNU/Linux 13 (trixie)"
NAME="Debian GNU/Linux"
VERSION_ID="13"
VERSION="13 (trixie)"
VERSION_CODENAME=trixie
DEBIAN_VERSION_FULL=13.3
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
  • Version: RPM version 4.20.1

Additional context
I have tracked the issue to:

diff --git a/lib/backend/bdb_ro.c b/lib/backend/bdb_ro.c
@@ -461,8 +461,11 @@ static int btree_next(struct bdb_cur *cur)
 	voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx);
 	if (koff + 3 > pagesize || voff + 3 > pagesize)
 	    return -1;
-	if ((cur->page[koff + 2] & 0x80) != 0 || (cur->page[voff + 2] & 0x80) != 0)
-	    continue;	/* ignore deleted */
+	if ((cur->page[koff + 2] & 0x80) != 0 || (cur->page[voff + 2] & 0x80) != 0) {
+	    cur->idx += 2;	/* deleted key/value pair, advance to next entry */
+	    continue;
+	}
 	if (btree_getkv(cur, &cur->key, &cur->keyov, koff))
 	    return -1;

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions