Re: [PATCH] btrfs-progs: fix segfault in walk_down_tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, May 2, 2013 at 12:32 AM, Eric Sandeen <sandeen@xxxxxxxxxx> wrote:
> On 5/1/13 9:46 PM, Lin Ming wrote:
>> walk_down_tree will fault when read_tree_block fails with NULL returned.
>>
>> Signed-off-by: Lin Ming <mlin@xxxxxxxxxx>
>> ---
>>  cmds-check.c |    2 ++
>>  1 files changed, 2 insertions(+), 0 deletions(-)
>>
>> diff --git a/cmds-check.c b/cmds-check.c
>> index 12192fa..e4435d5 100644
>> --- a/cmds-check.c
>> +++ b/cmds-check.c
>> @@ -1256,6 +1256,8 @@ static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path,
>>                       reada_walk_down(root, cur, path->slots[*level]);
>>                       next = read_tree_block(root, bytenr, blocksize,
>>                                              ptr_gen);
>> +                     if (!next)
>> +                             goto out;
>>               }
>>
>>               *level = *level - 1;
>>
>
> I suppose that could fix a segfault . . . although, details
> would be nice.  next is only used as:
>
>         path->nodes[*level] = next;
>
> before it gets reassigned in the loop.  So I guess someone
> uses the path array and doesn't handle a NULL?

walk_down_tree():

        while (*level >= 0) {
                .....
                cur = path->nodes[*level];

                if (btrfs_header_level(cur) != *level)   <---- segfault here

                .....
                path->nodes[*level] = next;

>
> Ok, but if read_tree_block fails(), doesn't that mean some error
> occurred?  And if so, walk_down_tree would still return 0,
> which looks like success to the caller.  Then what?
>
> I guess that's what the other error returns in this function
> do as well.  :(
>
> But this seems like suboptimal behavior for a filesystem checker,
> doesn't it?  Just silently ignoring errors?
>
> And while this might fix the segfault I'm afraid it does so without
> really handling the problem, and it might never be noticed again.
>
> The caller looks like it might handle an error, if one were ever
> passed up (which it's not right now):
>
>                 wret = walk_down_tree(root, &path, wc, &level);
>                 if (wret < 0)
>                         ret = wret;
>                 if (wret != 0)
>                         break;
>
> Over on the kernel side, this commit at least catches the error
> and passes it up:
>
> commit 97d9a8a420444eb5b5c071d4b3b9c4100a7ae015
> Author: Tsutomu Itoh <t-itoh@xxxxxxxxxxxxxx>
> Date:   Thu Mar 24 06:33:21 2011 +0000
>
>     Btrfs: check return value of read_tree_block()
>
>     This patch is checking return value of read_tree_block(),
>     and if it is NULL, error processing.
>
>     Signed-off-by: Tsutomu Itoh <t-itoh@xxxxxxxxxxxxxx>
>     Signed-off-by: Chris Mason <chris.mason@xxxxxxxxxx>
>
> ...
>                 next = read_tree_block(root, bytenr, blocksize, generation);
> +               if (!next)
> +                       return -EIO;
> ...
>
> so that's probably a better way to go, though it might require some testing.

Agree, we should pass up the return value of walk_down_tree().

Lin Ming

>
> Another reason to get userspace caught up w/ kernelspace, argh.
>
> -Eric
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Filesystem Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux