diff options
author | David Sterba <dsterba@suse.com> | 2016-09-30 18:51:46 +0200 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2016-10-03 15:07:24 +0200 |
commit | d89205c4a5304572d8b6e67cee25594d4baaedee (patch) | |
tree | 6eb2c2f2062685d983d9ca7f9bbdf01da276983c /qgroup-verify.c | |
parent | 801f15bdf1598a75f20d1c07d3e0640d37499165 (diff) |
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 <lukas.lueg@gmail.com>
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=156811
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'qgroup-verify.c')
-rw-r--r-- | qgroup-verify.c | 21 |
1 files 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; + } } } |