From d89205c4a5304572d8b6e67cee25594d4baaedee Mon Sep 17 00:00:00 2001 From: David Sterba Date: Fri, 30 Sep 2016 18:51:46 +0200 Subject: [PATCH] btrfs-progs: check: better error handling in find_parent_roots Fix use-before-sanity-check leading to undefined behaviour and handle errors more gracefully. Reported-by: Lukas Lueg Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=156811 Signed-off-by: David Sterba --- qgroup-verify.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/qgroup-verify.c b/qgroup-verify.c index f6df12d5..df0e5474 100644 --- a/qgroup-verify.c +++ b/qgroup-verify.c @@ -330,9 +330,18 @@ static int find_parent_roots(struct ulist *roots, u64 parent) * For each unresolved root, we recurse */ ref = find_ref_bytenr(parent); + if (!ref) { + error("bytenr ref not found for parent %llu", + (unsigned long long)parent); + return -EIO; + } node = &ref->bytenr_node; - BUG_ON(ref == NULL); - BUG_ON(ref->bytenr != parent); + if (ref->bytenr != parent) { + error("found bytenr ref does not match parent: %llu != %llu", + (unsigned long long)ref->bytenr, + (unsigned long long)parent); + return -EIO; + } { /* @@ -341,9 +350,15 @@ static int find_parent_roots(struct ulist *roots, u64 parent) */ struct rb_node *prev_node = rb_prev(&ref->bytenr_node); struct ref *prev; + if (prev_node) { prev = rb_entry(prev_node, struct ref, bytenr_node); - BUG_ON(prev->bytenr == parent); + if (prev->bytenr == parent) { + error( + "unexpected: prev bytenr same as parent: %llu", + (unsigned long long)parent); + return -EIO; + } } }