summaryrefslogtreecommitdiff
path: root/cmds-send.c
diff options
context:
space:
mode:
authorQu Wenruo <quwenruo@cn.fujitsu.com>2016-12-15 16:37:02 +0800
committerDavid Sterba <dsterba@suse.com>2016-12-21 16:29:06 +0100
commite0485281ed319d99bdae13acdd5c9aed014083d9 (patch)
tree91bcd7a0b99c1f3bd0b1e3d9ac40f480272a450d /cmds-send.c
parente27189a39163e6d6d6781fdec55ae6ee11671839 (diff)
btrfs-progs: Fix NULL pointer when receive clone operation
Regression introduced by a2f7af94abe4a3491ca1280a2ae1d63edc0d62ab "btrfs-progs: subvol_uuid_search: return error encoded pointer" IS_ERR() will only check if it's an error code, won't check if it's NULL. And for all the caller the commit modifies, it can return NULL and makes cause segfault. Fix it by introducing new IS_ERR_OR_NULL() macro, and for NULL pointer and needs to return int case, convert NULL pointer to -ENOENT. Reported-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com> Tested-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com> Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'cmds-send.c')
-rw-r--r--cmds-send.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/cmds-send.c b/cmds-send.c
index 5da64d82..cec11e6b 100644
--- a/cmds-send.c
+++ b/cmds-send.c
@@ -70,8 +70,12 @@ static int get_root_id(struct btrfs_send *sctx, const char *path, u64 *root_id)
si = subvol_uuid_search(&sctx->sus, 0, NULL, 0, path,
subvol_search_by_path);
- if (IS_ERR(si))
- return PTR_ERR(si);
+ if (IS_ERR_OR_NULL(si)) {
+ if (!si)
+ return -ENOENT;
+ else
+ return PTR_ERR(si);
+ }
*root_id = si->root_id;
free(si->path);
free(si);
@@ -85,7 +89,7 @@ static struct subvol_info *get_parent(struct btrfs_send *sctx, u64 root_id)
si_tmp = subvol_uuid_search(&sctx->sus, root_id, NULL, 0, NULL,
subvol_search_by_root_id);
- if (IS_ERR(si_tmp))
+ if (IS_ERR_OR_NULL(si_tmp))
return si_tmp;
si = subvol_uuid_search(&sctx->sus, 0, si_tmp->parent_uuid, 0, NULL,
@@ -105,8 +109,11 @@ static int find_good_parent(struct btrfs_send *sctx, u64 root_id, u64 *found)
int i;
parent = get_parent(sctx, root_id);
- if (IS_ERR(parent)) {
- ret = PTR_ERR(parent);
+ if (IS_ERR_OR_NULL(parent)) {
+ if (!parent)
+ ret = -ENOENT;
+ else
+ ret = PTR_ERR(parent);
goto out;
}
@@ -122,7 +129,7 @@ static int find_good_parent(struct btrfs_send *sctx, u64 root_id, u64 *found)
s64 tmp;
parent2 = get_parent(sctx, sctx->clone_sources[i]);
- if (IS_ERR(parent2))
+ if (IS_ERR_OR_NULL(parent2))
continue;
if (parent2->root_id != parent->root_id) {
free(parent2->path);
@@ -136,8 +143,11 @@ static int find_good_parent(struct btrfs_send *sctx, u64 root_id, u64 *found)
parent2 = subvol_uuid_search(&sctx->sus,
sctx->clone_sources[i], NULL, 0, NULL,
subvol_search_by_root_id);
- if (IS_ERR(parent2)) {
- ret = PTR_ERR(parent2);
+ if (IS_ERR_OR_NULL(parent2)) {
+ if (!parent2)
+ ret = -ENOENT;
+ else
+ ret = PTR_ERR(parent2);
goto out;
}
tmp = parent2->ctransid - parent->ctransid;