btrfs-progs: more carefully check eb backrefs
authorZach Brown <zab@redhat.com>
Thu, 17 Jan 2013 21:24:35 +0000 (13:24 -0800)
committerZach Brown <zab@redhat.com>
Wed, 6 Feb 2013 00:09:38 +0000 (16:09 -0800)
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.

btrfsck.c

index dd0f18b..d292540 100644 (file)
--- a/btrfsck.c
+++ b/btrfsck.c
@@ -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);