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>
master
David Sterba 2016-09-30 18:51:46 +02:00
parent 801f15bdf1
commit d89205c4a5
1 changed files with 18 additions and 3 deletions

View File

@ -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;
}
}
}