diff options
author | Zach Brown <zab@redhat.com> | 2013-01-17 13:24:35 -0800 |
---|---|---|
committer | Zach Brown <zab@redhat.com> | 2013-02-05 16:09:38 -0800 |
commit | 968efc6f988623aff2b4c21af8317ec80836a4b9 (patch) | |
tree | fb153f57b5134c2255e61911954469b619b1f9f7 | |
parent | ea0ac9416fd13b7e20899d8c7c130e5375171ea6 (diff) |
btrfs-progs: more carefully check eb backrefs
check_owner_ref() could deref a null path node if btrfs_search_slot()
fails or simply doesn't find a tree tall enough to get to the parent of
the desired block.
This was flagged by static analysis warning that btrfs_search_slot()'s
return value wasn't being checked.
Signed-off-by: Zach Brown <zab@redhat.com>
Again: caught by static analysis.
-rw-r--r-- | btrfsck.c | 11 |
1 files changed, 8 insertions, 3 deletions
@@ -1970,8 +1970,10 @@ static int check_owner_ref(struct btrfs_root *root, struct btrfs_root *ref_root; struct btrfs_key key; struct btrfs_path path; + struct extent_buffer *parent; int level; int found = 0; + int ret; list_for_each_entry(node, &rec->backrefs, list) { if (node->is_data) @@ -2002,10 +2004,13 @@ static int check_owner_ref(struct btrfs_root *root, btrfs_init_path(&path); path.lowest_level = level + 1; - btrfs_search_slot(NULL, ref_root, &key, &path, 0, 0); + ret = btrfs_search_slot(NULL, ref_root, &key, &path, 0, 0); + if (ret < 0) + return 0; - if (buf->start == btrfs_node_blockptr(path.nodes[level + 1], - path.slots[level + 1])) + parent = path.nodes[level + 1]; + if (parent && buf->start == btrfs_node_blockptr(parent, + path.slots[level + 1])) found = 1; btrfs_release_path(ref_root, &path); |