All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] btrfs: btrfs: don't trust sub_stripes from disk
@ 2022-10-21  0:44 ` Qu Wenruo
  0 siblings, 0 replies; 8+ messages in thread
From: Qu Wenruo @ 2022-10-21  0:43 UTC (permalink / raw)
  To: linux-btrfs; +Cc: kernel test robot, Viktor Kuzmin

[BUG]
There are two reports (the earliest one from LKP, a more recent one from
kernel bugzilla) that we can have some chunks with 0 as sub_stripes.

This will cause divide-by-zero errors at btrfs_rmap_block, which is
introduced by a recent kernel patch ac0677348f3c ("btrfs: merge
calculations for simple striped profiles in btrfs_rmap_block"):

		if (map->type & (BTRFS_BLOCK_GROUP_RAID0 |
				 BTRFS_BLOCK_GROUP_RAID10)) {
			stripe_nr = stripe_nr * map->num_stripes + i;
			stripe_nr = div_u64(stripe_nr, map->sub_stripes); <<<
		}

[CAUSE]
From the more recent report, it has been proven that we have some chunks
with 0 as sub_stripes, mostly caused by older mkfs.

It turns out that the mkfs.btrfs fix is only introduced in 6718ab4d33aa
("btrfs-progs: Initialize sub_stripes to 1 in btrfs_alloc_data_chunk")
which is included in v5.4 btrfs-progs release.

So there would be quite some old fses with such 0 sub_stripes.

[FIX]
Just don't trust the sub_stripes values from disk.

We have a trusted btrfs_raid_array[] to fetch the correct sub_stripes
numbers for each profile.

By this, we can keep the compatibility with older fses while still avoid
divide-by-zero bugs.

Fixes: ac0677348f3c ("btrfs: merge calculations for simple striped profiles in btrfs_rmap_block")
Reported-by: kernel test robot <oliver.sang@intel.com>
Reported-by: Viktor Kuzmin <kvaster@gmail.com>
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216559
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/volumes.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 94ba46d57920..39588cb9a7b6 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -7142,6 +7142,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
 	u64 devid;
 	u64 type;
 	u8 uuid[BTRFS_UUID_SIZE];
+	int index;
 	int num_stripes;
 	int ret;
 	int i;
@@ -7149,6 +7150,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
 	logical = key->offset;
 	length = btrfs_chunk_length(leaf, chunk);
 	type = btrfs_chunk_type(leaf, chunk);
+	index = btrfs_bg_flags_to_raid_index(type);
 	num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
 
 #if BITS_PER_LONG == 32
@@ -7202,7 +7204,14 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
 	map->io_align = btrfs_chunk_io_align(leaf, chunk);
 	map->stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
 	map->type = type;
-	map->sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk);
+	/*
+	 * Don't trust the sub_stripes value, as for profiles other
+	 * than RAID10, they may have 0 as sub_stripes for older mkfs.
+	 * In that case, it can cause divide-by-zero errors later.
+	 * Since currently sub_stripes is fixed for each profile, let's
+	 * use the trusted value instead.
+	 */
+	map->sub_stripes = btrfs_raid_array[index].sub_stripes;
 	map->verified_stripes = 0;
 	em->orig_block_len = btrfs_calc_stripe_length(em);
 	for (i = 0; i < num_stripes; i++) {
-- 
2.38.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH] btrfs: btrfs: don't trust sub_stripes from disk
@ 2022-10-21  0:44 ` Qu Wenruo
  0 siblings, 0 replies; 8+ messages in thread
From: Qu Wenruo @ 2022-10-21  0:44 UTC (permalink / raw)
  To: linux-btrfs; +Cc: kernel test robot, Viktor Kuzmin

[BUG]
There are two reports (the earliest one from LKP, a more recent one from
kernel bugzilla) that we can have some chunks with 0 as sub_stripes.

This will cause divide-by-zero errors at btrfs_rmap_block, which is
introduced by a recent kernel patch ac0677348f3c ("btrfs: merge
calculations for simple striped profiles in btrfs_rmap_block"):

		if (map->type & (BTRFS_BLOCK_GROUP_RAID0 |
				 BTRFS_BLOCK_GROUP_RAID10)) {
			stripe_nr = stripe_nr * map->num_stripes + i;
			stripe_nr = div_u64(stripe_nr, map->sub_stripes); <<<
		}

[CAUSE]
From the more recent report, it has been proven that we have some chunks
with 0 as sub_stripes, mostly caused by older mkfs.

It turns out that the mkfs.btrfs fix is only introduced in 6718ab4d33aa
("btrfs-progs: Initialize sub_stripes to 1 in btrfs_alloc_data_chunk")
which is included in v5.4 btrfs-progs release.

So there would be quite some old fses with such 0 sub_stripes.

[FIX]
Just don't trust the sub_stripes values from disk.

We have a trusted btrfs_raid_array[] to fetch the correct sub_stripes
numbers for each profile.

By this, we can keep the compatibility with older fses while still avoid
divide-by-zero bugs.

Fixes: ac0677348f3c ("btrfs: merge calculations for simple striped profiles in btrfs_rmap_block")
Reported-by: kernel test robot <oliver.sang@intel.com>
Reported-by: Viktor Kuzmin <kvaster@gmail.com>
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216559
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/volumes.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 94ba46d57920..39588cb9a7b6 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -7142,6 +7142,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
 	u64 devid;
 	u64 type;
 	u8 uuid[BTRFS_UUID_SIZE];
+	int index;
 	int num_stripes;
 	int ret;
 	int i;
@@ -7149,6 +7150,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
 	logical = key->offset;
 	length = btrfs_chunk_length(leaf, chunk);
 	type = btrfs_chunk_type(leaf, chunk);
+	index = btrfs_bg_flags_to_raid_index(type);
 	num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
 
 #if BITS_PER_LONG == 32
@@ -7202,7 +7204,14 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
 	map->io_align = btrfs_chunk_io_align(leaf, chunk);
 	map->stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
 	map->type = type;
-	map->sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk);
+	/*
+	 * Don't trust the sub_stripes value, as for profiles other
+	 * than RAID10, they may have 0 as sub_stripes for older mkfs.
+	 * In that case, it can cause divide-by-zero errors later.
+	 * Since currently sub_stripes is fixed for each profile, let's
+	 * use the trusted value instead.
+	 */
+	map->sub_stripes = btrfs_raid_array[index].sub_stripes;
 	map->verified_stripes = 0;
 	em->orig_block_len = btrfs_calc_stripe_length(em);
 	for (i = 0; i < num_stripes; i++) {
-- 
2.38.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] btrfs: btrfs: don't trust sub_stripes from disk
  2022-10-21  0:44 ` Qu Wenruo
  (?)
@ 2022-10-21  0:47 ` Su Yue
  -1 siblings, 0 replies; 8+ messages in thread
From: Su Yue @ 2022-10-21  0:47 UTC (permalink / raw)
  To: Qu Wenruo, linux-btrfs; +Cc: kernel test robot, Viktor Kuzmin



On 2022/10/21 08:44, Qu Wenruo wrote:
> [BUG]
> There are two reports (the earliest one from LKP, a more recent one from
> kernel bugzilla) that we can have some chunks with 0 as sub_stripes.
> 
> This will cause divide-by-zero errors at btrfs_rmap_block, which is
> introduced by a recent kernel patch ac0677348f3c ("btrfs: merge
> calculations for simple striped profiles in btrfs_rmap_block"):
> 
> 		if (map->type & (BTRFS_BLOCK_GROUP_RAID0 |
> 				 BTRFS_BLOCK_GROUP_RAID10)) {
> 			stripe_nr = stripe_nr * map->num_stripes + i;
> 			stripe_nr = div_u64(stripe_nr, map->sub_stripes); <<<
> 		}
> 
> [CAUSE]
>  From the more recent report, it has been proven that we have some chunks
> with 0 as sub_stripes, mostly caused by older mkfs.
> 
> It turns out that the mkfs.btrfs fix is only introduced in 6718ab4d33aa
> ("btrfs-progs: Initialize sub_stripes to 1 in btrfs_alloc_data_chunk")
> which is included in v5.4 btrfs-progs release.
> 
> So there would be quite some old fses with such 0 sub_stripes.
> 
> [FIX]
> Just don't trust the sub_stripes values from disk.
> 
> We have a trusted btrfs_raid_array[] to fetch the correct sub_stripes
> numbers for each profile.
> 
> By this, we can keep the compatibility with older fses while still avoid
> divide-by-zero bugs.
> 
> Fixes: ac0677348f3c ("btrfs: merge calculations for simple striped profiles in btrfs_rmap_block")
> Reported-by: kernel test robot <oliver.sang@intel.com>
> Reported-by: Viktor Kuzmin <kvaster@gmail.com>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=216559
> Signed-off-by: Qu Wenruo <wqu@suse.com>
> ---

LGTM,
Reviewed-by: Su Yue <glass@fydeos.io>
>   fs/btrfs/volumes.c | 11 ++++++++++-
>   1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> index 94ba46d57920..39588cb9a7b6 100644
> --- a/fs/btrfs/volumes.c
> +++ b/fs/btrfs/volumes.c
> @@ -7142,6 +7142,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
>   	u64 devid;
>   	u64 type;
>   	u8 uuid[BTRFS_UUID_SIZE];
> +	int index;
>   	int num_stripes;
>   	int ret;
>   	int i;
> @@ -7149,6 +7150,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
>   	logical = key->offset;
>   	length = btrfs_chunk_length(leaf, chunk);
>   	type = btrfs_chunk_type(leaf, chunk);
> +	index = btrfs_bg_flags_to_raid_index(type);
>   	num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
>   
>   #if BITS_PER_LONG == 32
> @@ -7202,7 +7204,14 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
>   	map->io_align = btrfs_chunk_io_align(leaf, chunk);
>   	map->stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
>   	map->type = type;
> -	map->sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk);
> +	/*
> +	 * Don't trust the sub_stripes value, as for profiles other
> +	 * than RAID10, they may have 0 as sub_stripes for older mkfs.
> +	 * In that case, it can cause divide-by-zero errors later.
> +	 * Since currently sub_stripes is fixed for each profile, let's
> +	 * use the trusted value instead.
> +	 */
> +	map->sub_stripes = btrfs_raid_array[index].sub_stripes;
>   	map->verified_stripes = 0;
>   	em->orig_block_len = btrfs_calc_stripe_length(em);
>   	for (i = 0; i < num_stripes; i++) {

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] btrfs: btrfs: don't trust sub_stripes from disk
  2022-10-21  0:44 ` Qu Wenruo
  (?)
  (?)
@ 2022-10-21  8:05 ` Johannes Thumshirn
  -1 siblings, 0 replies; 8+ messages in thread
From: Johannes Thumshirn @ 2022-10-21  8:05 UTC (permalink / raw)
  To: Qu Wenruo, linux-btrfs; +Cc: kernel test robot, Viktor Kuzmin

Looks good,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] btrfs: btrfs: don't trust sub_stripes from disk
@ 2022-10-21  8:12 ` Anand Jain
  2022-10-21  8:26   ` Qu Wenruo
  0 siblings, 1 reply; 8+ messages in thread
From: Anand Jain @ 2022-10-21  8:12 UTC (permalink / raw)
  To: Qu Wenruo, linux-btrfs; +Cc: kernel test robot, Viktor Kuzmin

On 21/10/2022 08:44, Qu Wenruo wrote:
> [BUG]
> There are two reports (the earliest one from LKP, a more recent one from
> kernel bugzilla) that we can have some chunks with 0 as sub_stripes.
> 
> This will cause divide-by-zero errors at btrfs_rmap_block, which is
> introduced by a recent kernel patch ac0677348f3c ("btrfs: merge
> calculations for simple striped profiles in btrfs_rmap_block"):
> 
> 		if (map->type & (BTRFS_BLOCK_GROUP_RAID0 |
> 				 BTRFS_BLOCK_GROUP_RAID10)) {
> 			stripe_nr = stripe_nr * map->num_stripes + i;
> 			stripe_nr = div_u64(stripe_nr, map->sub_stripes); <<<
> 		}
> 
> [CAUSE]
>  From the more recent report, it has been proven that we have some chunks
> with 0 as sub_stripes, mostly caused by older mkfs.
> 
> It turns out that the mkfs.btrfs fix is only introduced in 6718ab4d33aa
> ("btrfs-progs: Initialize sub_stripes to 1 in btrfs_alloc_data_chunk")
> which is included in v5.4 btrfs-progs release.
> 
> So there would be quite some old fses with such 0 sub_stripes.
> 
> [FIX]
> Just don't trust the sub_stripes values from disk.
> 
> We have a trusted btrfs_raid_array[] to fetch the correct sub_stripes
> numbers for each profile.
> 
> By this, we can keep the compatibility with older fses while still avoid
> divide-by-zero bugs.
> 
> Fixes: ac0677348f3c ("btrfs: merge calculations for simple striped profiles in btrfs_rmap_block")
> Reported-by: kernel test robot <oliver.sang@intel.com>
> Reported-by: Viktor Kuzmin <kvaster@gmail.com>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=216559
> Signed-off-by: Qu Wenruo <wqu@suse.com>
> ---
>   fs/btrfs/volumes.c | 11 ++++++++++-
>   1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> index 94ba46d57920..39588cb9a7b6 100644
> --- a/fs/btrfs/volumes.c
> +++ b/fs/btrfs/volumes.c
> @@ -7142,6 +7142,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
>   	u64 devid;
>   	u64 type;
>   	u8 uuid[BTRFS_UUID_SIZE];
> +	int index;
>   	int num_stripes;
>   	int ret;
>   	int i;
> @@ -7149,6 +7150,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
>   	logical = key->offset;
>   	length = btrfs_chunk_length(leaf, chunk);
>   	type = btrfs_chunk_type(leaf, chunk);
> +	index = btrfs_bg_flags_to_raid_index(type);
>   	num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
>   
>   #if BITS_PER_LONG == 32
> @@ -7202,7 +7204,14 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
>   	map->io_align = btrfs_chunk_io_align(leaf, chunk);
>   	map->stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
>   	map->type = type;


> -	map->sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk);
> +	/*
> +	 * Don't trust the sub_stripes value, as for profiles other
> +	 * than RAID10, they may have 0 as sub_stripes for older mkfs.
> +	 * In that case, it can cause divide-by-zero errors later.
> +	 * Since currently sub_stripes is fixed for each profile, let's
> +	 * use the trusted value instead.
> +	 */
> +	map->sub_stripes = btrfs_raid_array[index].sub_stripes;

It is a potential security threat, we have to fix this in the kernel. 
However, the code is doing correct to read from the disk instead of 
setting it to the expected value. So if the read sub_stripes is 
incorrect, why not return EUCLEAN so that the user will upgrade the 
btrfs-progs to fix the mkfs instead.

IMO.



>   	map->verified_stripes = 0;
>   	em->orig_block_len = btrfs_calc_stripe_length(em);
>   	for (i = 0; i < num_stripes; i++) {


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] btrfs: btrfs: don't trust sub_stripes from disk
  2022-10-21  8:12 ` Anand Jain
@ 2022-10-21  8:26   ` Qu Wenruo
  2022-10-24 14:01     ` David Sterba
  0 siblings, 1 reply; 8+ messages in thread
From: Qu Wenruo @ 2022-10-21  8:26 UTC (permalink / raw)
  To: Anand Jain, Qu Wenruo, linux-btrfs; +Cc: kernel test robot, Viktor Kuzmin



On 2022/10/21 16:12, Anand Jain wrote:
> On 21/10/2022 08:44, Qu Wenruo wrote:
>> [BUG]
>> There are two reports (the earliest one from LKP, a more recent one from
>> kernel bugzilla) that we can have some chunks with 0 as sub_stripes.
>>
>> This will cause divide-by-zero errors at btrfs_rmap_block, which is
>> introduced by a recent kernel patch ac0677348f3c ("btrfs: merge
>> calculations for simple striped profiles in btrfs_rmap_block"):
>>
>>         if (map->type & (BTRFS_BLOCK_GROUP_RAID0 |
>>                  BTRFS_BLOCK_GROUP_RAID10)) {
>>             stripe_nr = stripe_nr * map->num_stripes + i;
>>             stripe_nr = div_u64(stripe_nr, map->sub_stripes); <<<
>>         }
>>
>> [CAUSE]
>>  From the more recent report, it has been proven that we have some chunks
>> with 0 as sub_stripes, mostly caused by older mkfs.
>>
>> It turns out that the mkfs.btrfs fix is only introduced in 6718ab4d33aa
>> ("btrfs-progs: Initialize sub_stripes to 1 in btrfs_alloc_data_chunk")
>> which is included in v5.4 btrfs-progs release.
>>
>> So there would be quite some old fses with such 0 sub_stripes.
>>
>> [FIX]
>> Just don't trust the sub_stripes values from disk.
>>
>> We have a trusted btrfs_raid_array[] to fetch the correct sub_stripes
>> numbers for each profile.
>>
>> By this, we can keep the compatibility with older fses while still avoid
>> divide-by-zero bugs.
>>
>> Fixes: ac0677348f3c ("btrfs: merge calculations for simple striped
>> profiles in btrfs_rmap_block")
>> Reported-by: kernel test robot <oliver.sang@intel.com>
>> Reported-by: Viktor Kuzmin <kvaster@gmail.com>
>> Link: https://bugzilla.kernel.org/show_bug.cgi?id=216559
>> Signed-off-by: Qu Wenruo <wqu@suse.com>
>> ---
>>   fs/btrfs/volumes.c | 11 ++++++++++-
>>   1 file changed, 10 insertions(+), 1 deletion(-)
>>
>> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
>> index 94ba46d57920..39588cb9a7b6 100644
>> --- a/fs/btrfs/volumes.c
>> +++ b/fs/btrfs/volumes.c
>> @@ -7142,6 +7142,7 @@ static int read_one_chunk(struct btrfs_key *key,
>> struct extent_buffer *leaf,
>>       u64 devid;
>>       u64 type;
>>       u8 uuid[BTRFS_UUID_SIZE];
>> +    int index;
>>       int num_stripes;
>>       int ret;
>>       int i;
>> @@ -7149,6 +7150,7 @@ static int read_one_chunk(struct btrfs_key *key,
>> struct extent_buffer *leaf,
>>       logical = key->offset;
>>       length = btrfs_chunk_length(leaf, chunk);
>>       type = btrfs_chunk_type(leaf, chunk);
>> +    index = btrfs_bg_flags_to_raid_index(type);
>>       num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
>>   #if BITS_PER_LONG == 32
>> @@ -7202,7 +7204,14 @@ static int read_one_chunk(struct btrfs_key
>> *key, struct extent_buffer *leaf,
>>       map->io_align = btrfs_chunk_io_align(leaf, chunk);
>>       map->stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
>>       map->type = type;
>
>
>> -    map->sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk);
>> +    /*
>> +     * Don't trust the sub_stripes value, as for profiles other
>> +     * than RAID10, they may have 0 as sub_stripes for older mkfs.
>> +     * In that case, it can cause divide-by-zero errors later.
>> +     * Since currently sub_stripes is fixed for each profile, let's
>> +     * use the trusted value instead.
>> +     */
>> +    map->sub_stripes = btrfs_raid_array[index].sub_stripes;
>
> It is a potential security threat, we have to fix this in the kernel.
> However, the code is doing correct to read from the disk instead of
> setting it to the expected value. So if the read sub_stripes is
> incorrect, why not return EUCLEAN so that the user will upgrade the
> btrfs-progs to fix the mkfs instead.

Or we will reject all older fses and cause compatibility problems.

And you're asking users to mkfs to "fix" some fses which can be safely
mounted just by older kernels?

That's not a fix, but a completely data wipe.
>
> IMO.
>
>
>
>>       map->verified_stripes = 0;
>>       em->orig_block_len = btrfs_calc_stripe_length(em);
>>       for (i = 0; i < num_stripes; i++) {
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] btrfs: btrfs: don't trust sub_stripes from disk
  2022-10-21  8:26   ` Qu Wenruo
@ 2022-10-24 14:01     ` David Sterba
  0 siblings, 0 replies; 8+ messages in thread
From: David Sterba @ 2022-10-24 14:01 UTC (permalink / raw)
  To: Qu Wenruo
  Cc: Anand Jain, Qu Wenruo, linux-btrfs, kernel test robot, Viktor Kuzmin

On Fri, Oct 21, 2022 at 04:26:24PM +0800, Qu Wenruo wrote:
> >> -    map->sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk);
> >> +    /*
> >> +     * Don't trust the sub_stripes value, as for profiles other
> >> +     * than RAID10, they may have 0 as sub_stripes for older mkfs.
> >> +     * In that case, it can cause divide-by-zero errors later.
> >> +     * Since currently sub_stripes is fixed for each profile, let's
> >> +     * use the trusted value instead.
> >> +     */
> >> +    map->sub_stripes = btrfs_raid_array[index].sub_stripes;
> >
> > It is a potential security threat, we have to fix this in the kernel.
> > However, the code is doing correct to read from the disk instead of
> > setting it to the expected value. So if the read sub_stripes is
> > incorrect, why not return EUCLEAN so that the user will upgrade the
> > btrfs-progs to fix the mkfs instead.
> 
> Or we will reject all older fses and cause compatibility problems.
> 
> And you're asking users to mkfs to "fix" some fses which can be safely
> mounted just by older kernels?
> 
> That's not a fix, but a completely data wipe.

Yeah we can't suggest to use mkfs as a fix but can we at least rewrite
the items with the correct value at some occasion. Eventually we can add
a rescue subcommand.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] btrfs: btrfs: don't trust sub_stripes from disk
  2022-10-21  0:44 ` Qu Wenruo
                   ` (2 preceding siblings ...)
  (?)
@ 2022-10-24 14:18 ` David Sterba
  -1 siblings, 0 replies; 8+ messages in thread
From: David Sterba @ 2022-10-24 14:18 UTC (permalink / raw)
  To: Qu Wenruo; +Cc: linux-btrfs, kernel test robot, Viktor Kuzmin

On Fri, Oct 21, 2022 at 08:43:45AM +0800, Qu Wenruo wrote:
> [BUG]
> There are two reports (the earliest one from LKP, a more recent one from
> kernel bugzilla) that we can have some chunks with 0 as sub_stripes.
> 
> This will cause divide-by-zero errors at btrfs_rmap_block, which is
> introduced by a recent kernel patch ac0677348f3c ("btrfs: merge
> calculations for simple striped profiles in btrfs_rmap_block"):
> 
> 		if (map->type & (BTRFS_BLOCK_GROUP_RAID0 |
> 				 BTRFS_BLOCK_GROUP_RAID10)) {
> 			stripe_nr = stripe_nr * map->num_stripes + i;
> 			stripe_nr = div_u64(stripe_nr, map->sub_stripes); <<<
> 		}
> 
> [CAUSE]
> >From the more recent report, it has been proven that we have some chunks
> with 0 as sub_stripes, mostly caused by older mkfs.
> 
> It turns out that the mkfs.btrfs fix is only introduced in 6718ab4d33aa
> ("btrfs-progs: Initialize sub_stripes to 1 in btrfs_alloc_data_chunk")
> which is included in v5.4 btrfs-progs release.
> 
> So there would be quite some old fses with such 0 sub_stripes.
> 
> [FIX]
> Just don't trust the sub_stripes values from disk.
> 
> We have a trusted btrfs_raid_array[] to fetch the correct sub_stripes
> numbers for each profile.
> 
> By this, we can keep the compatibility with older fses while still avoid
> divide-by-zero bugs.
> 
> Fixes: ac0677348f3c ("btrfs: merge calculations for simple striped profiles in btrfs_rmap_block")
> Reported-by: kernel test robot <oliver.sang@intel.com>
> Reported-by: Viktor Kuzmin <kvaster@gmail.com>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=216559
> Signed-off-by: Qu Wenruo <wqu@suse.com>

Added to misc-next, thanks.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2022-10-24 16:58 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-21  0:44 [PATCH] btrfs: btrfs: don't trust sub_stripes from disk Qu Wenruo
2022-10-21  8:12 ` Anand Jain
2022-10-21  8:26   ` Qu Wenruo
2022-10-24 14:01     ` David Sterba
  -- strict thread matches above, loose matches on Subject: below --
2022-10-21  0:43 Qu Wenruo
2022-10-21  0:44 ` Qu Wenruo
2022-10-21  0:47 ` Su Yue
2022-10-21  8:05 ` Johannes Thumshirn
2022-10-24 14:18 ` David Sterba

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.