super-recover crashing because it found a bad superblock
diff mbox

Message ID dfe1eed9-2aac-a6b6-c681-93d74d4fd83d@thehawken.org
State New
Headers show

Commit Message

hawken Sept. 20, 2016, 12:38 a.m. UTC
Hi!

In super-recover.c, around line 96, check_super calls 
btrfs_super_csum_size, which then dies because the size was too big.
I have solved this by reimplementing that stub inside super-recover.c 
with error handling rather than crashing:



(Sorry for bad formatting)
This allowed me to recover my superblocks

I found this bug kind of ironic because a routine made to discover bad 
data, crashed because it encountered bad data :D

- hawken
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Qu Wenruo Sept. 20, 2016, 12:49 a.m. UTC | #1
At 09/20/2016 08:38 AM, hawken wrote:
> Hi!
>
> In super-recover.c, around line 96, check_super calls
> btrfs_super_csum_size, which then dies because the size was too big.
> I have solved this by reimplementing that stub inside super-recover.c
> with error handling rather than crashing:
>
> diff --git a/super-recover.c b/super-recover.c
> index adb2c44..2508e06 100644
> --- a/super-recover.c
> +++ b/super-recover.c
> @@ -93,7 +93,11 @@ void free_recover_superblock(struct
> btrfs_recover_superblock *recover)
>
>  static int check_super(u64 bytenr, struct btrfs_super_block *sb)
>  {
> -       int csum_size = btrfs_super_csum_size(sb);
> +       int t = btrfs_super_csum_type(sb);
> +       if(t >= ARRAY_SIZE(btrfs_csum_sizes))
> +               return 0;
> +       int csum_size = btrfs_csum_sizes[t];
> +
>         char result[csum_size];
>         u32 crc = ~(u32)0;

Oh, we have only fixed check_super() in disk_io.c, forgot this one.

We need to merge it with the one in disk_io.c, which checks super more 
comprehensively.

Nice one.

Thanks,
Qu
>
>
> (Sorry for bad formatting)
> This allowed me to recover my superblocks
>
> I found this bug kind of ironic because a routine made to discover bad
> data, crashed because it encountered bad data :D
>
> - hawken
> --
> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>


--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch
diff mbox

diff --git a/super-recover.c b/super-recover.c
index adb2c44..2508e06 100644
--- a/super-recover.c
+++ b/super-recover.c
@@ -93,7 +93,11 @@  void free_recover_superblock(struct 
btrfs_recover_superblock *recover)

  static int check_super(u64 bytenr, struct btrfs_super_block *sb)
  {
-       int csum_size = btrfs_super_csum_size(sb);
+       int t = btrfs_super_csum_type(sb);
+       if(t >= ARRAY_SIZE(btrfs_csum_sizes))
+               return 0;
+       int csum_size = btrfs_csum_sizes[t];
+
         char result[csum_size];
         u32 crc = ~(u32)0;