diff mbox series

[1/2] btrfs-progs: fix the wrong timestamp and UUID check for root items

Message ID fd138f8678808717635a145832c1b13320ce6cd2.1672120480.git.wqu@suse.com (mailing list archive)
State New, archived
Headers show
Series btrfs-progs: fix the uuid report in "btrfs subvolume list -u" | expand

Commit Message

Qu Wenruo Dec. 27, 2022, 5:55 a.m. UTC
[BUG]
Since commit d729048be6ef ("btrfs-progs: stop using
btrfs_root_item_v0"), "btrfs subvolume list" not longer correctly report
UUID nor timestamp, while older (btrfs-progs v6.0.2) still works
correct:

 v6.0.2:
 # btrfs subv list -u  /mnt/btrfs/
 ID 256 gen 12 top level 5 uuid ed4af580-d512-2644-b392-2a71aaeeb99e path subv1
 ID 257 gen 13 top level 5 uuid a22ccba7-0a0a-a94f-af4b-5116ab58bb61 path subv2

 v6.1:
 # ./btrfs subv list -u /mnt/btrfs/
 ID 256 gen 12 top level 5 uuid -                                    path subv1
 ID 257 gen 13 top level 5 uuid -                                    path subv2

[CAUSE]
Commit d729048be6ef ("btrfs-progs: stop using btrfs_root_item_v0")
removed old btrfs_root_item_v0, but incorrectly changed the check for
v0 root item.

Now we will treat v0 root items as latest root items, causing possible
out-of-bound access. while treat current root items as older v0 root
items, ignoring the UUID nor timestamp.

[FIX]
Fix the bug by using correct checks, and add extra comments on the
branches.

Issue: #562
Fixes: d729048be6ef ("btrfs-progs: stop using btrfs_root_item_v0")
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 cmds/subvolume-list.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

Comments

Anand Jain Dec. 27, 2022, 6:36 a.m. UTC | #1
On 12/27/22 13:55, Qu Wenruo wrote:
> [BUG]
> Since commit d729048be6ef ("btrfs-progs: stop using
> btrfs_root_item_v0"), "btrfs subvolume list" not longer correctly report
> UUID nor timestamp, while older (btrfs-progs v6.0.2) still works
> correct:
> 
>   v6.0.2:
>   # btrfs subv list -u  /mnt/btrfs/
>   ID 256 gen 12 top level 5 uuid ed4af580-d512-2644-b392-2a71aaeeb99e path subv1
>   ID 257 gen 13 top level 5 uuid a22ccba7-0a0a-a94f-af4b-5116ab58bb61 path subv2
> 
>   v6.1:
>   # ./btrfs subv list -u /mnt/btrfs/
>   ID 256 gen 12 top level 5 uuid -                                    path subv1
>   ID 257 gen 13 top level 5 uuid -                                    path subv2
> 
> [CAUSE]
> Commit d729048be6ef ("btrfs-progs: stop using btrfs_root_item_v0")
> removed old btrfs_root_item_v0, but incorrectly changed the check for
> v0 root item.
> 
> Now we will treat v0 root items as latest root items, causing possible
> out-of-bound access. while treat current root items as older v0 root
> items, ignoring the UUID nor timestamp.
> 
> [FIX]
> Fix the bug by using correct checks, and add extra comments on the
> branches.
> 
> Issue: #562
> Fixes: d729048be6ef ("btrfs-progs: stop using btrfs_root_item_v0")
> Signed-off-by: Qu Wenruo <wqu@suse.com>



> ---
>   cmds/subvolume-list.c | 11 +++++++++--
>   1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/cmds/subvolume-list.c b/cmds/subvolume-list.c
> index 6d5ef509ae67..7cdb0402b8e5 100644
> --- a/cmds/subvolume-list.c
> +++ b/cmds/subvolume-list.c
> @@ -870,14 +870,21 @@ static int list_subvol_search(int fd, struct rb_root *root_lookup)
>   				ri = (struct btrfs_root_item *)(args.buf + off);
>   				gen = btrfs_root_generation(ri);
>   				flags = btrfs_root_flags(ri);
> -				if(sh.len <
> -				   sizeof(struct btrfs_root_item)) {
> +				if(sh.len >= sizeof(struct btrfs_root_item)) {
> +					/*
> +					 * The new full btrfs_root_item with
> +					 * timestamp and UUID.
> +					 */
>   					otime = btrfs_stack_timespec_sec(&ri->otime);
>   					ogen = btrfs_root_otransid(ri);
>   					memcpy(uuid, ri->uuid, BTRFS_UUID_SIZE);
>   					memcpy(puuid, ri->parent_uuid, BTRFS_UUID_SIZE);
>   					memcpy(ruuid, ri->received_uuid, BTRFS_UUID_SIZE);
>   				} else {
> +					/*
> +					 * The old v0 root item, which doesn't
> +					 * has timestamp nor UUID.
> +					 */

  Reviewed-by: Anand Jain <anand.jain@oracle.com>


>   					otime = 0;
>   					ogen = 0;
>   					memset(uuid, 0, BTRFS_UUID_SIZE);
Neal Gompa Dec. 28, 2022, 12:04 p.m. UTC | #2
On Tue, Dec 27, 2022 at 1:10 AM Qu Wenruo <wqu@suse.com> wrote:
>
> [BUG]
> Since commit d729048be6ef ("btrfs-progs: stop using
> btrfs_root_item_v0"), "btrfs subvolume list" not longer correctly report
> UUID nor timestamp, while older (btrfs-progs v6.0.2) still works
> correct:
>
>  v6.0.2:
>  # btrfs subv list -u  /mnt/btrfs/
>  ID 256 gen 12 top level 5 uuid ed4af580-d512-2644-b392-2a71aaeeb99e path subv1
>  ID 257 gen 13 top level 5 uuid a22ccba7-0a0a-a94f-af4b-5116ab58bb61 path subv2
>
>  v6.1:
>  # ./btrfs subv list -u /mnt/btrfs/
>  ID 256 gen 12 top level 5 uuid -                                    path subv1
>  ID 257 gen 13 top level 5 uuid -                                    path subv2
>
> [CAUSE]
> Commit d729048be6ef ("btrfs-progs: stop using btrfs_root_item_v0")
> removed old btrfs_root_item_v0, but incorrectly changed the check for
> v0 root item.
>
> Now we will treat v0 root items as latest root items, causing possible
> out-of-bound access. while treat current root items as older v0 root
> items, ignoring the UUID nor timestamp.
>
> [FIX]
> Fix the bug by using correct checks, and add extra comments on the
> branches.
>
> Issue: #562
> Fixes: d729048be6ef ("btrfs-progs: stop using btrfs_root_item_v0")
> Signed-off-by: Qu Wenruo <wqu@suse.com>
> ---
>  cmds/subvolume-list.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/cmds/subvolume-list.c b/cmds/subvolume-list.c
> index 6d5ef509ae67..7cdb0402b8e5 100644
> --- a/cmds/subvolume-list.c
> +++ b/cmds/subvolume-list.c
> @@ -870,14 +870,21 @@ static int list_subvol_search(int fd, struct rb_root *root_lookup)
>                                 ri = (struct btrfs_root_item *)(args.buf + off);
>                                 gen = btrfs_root_generation(ri);
>                                 flags = btrfs_root_flags(ri);
> -                               if(sh.len <
> -                                  sizeof(struct btrfs_root_item)) {
> +                               if(sh.len >= sizeof(struct btrfs_root_item)) {
> +                                       /*
> +                                        * The new full btrfs_root_item with
> +                                        * timestamp and UUID.
> +                                        */
>                                         otime = btrfs_stack_timespec_sec(&ri->otime);
>                                         ogen = btrfs_root_otransid(ri);
>                                         memcpy(uuid, ri->uuid, BTRFS_UUID_SIZE);
>                                         memcpy(puuid, ri->parent_uuid, BTRFS_UUID_SIZE);
>                                         memcpy(ruuid, ri->received_uuid, BTRFS_UUID_SIZE);
>                                 } else {
> +                                       /*
> +                                        * The old v0 root item, which doesn't
> +                                        * has timestamp nor UUID.
> +                                        */
>                                         otime = 0;
>                                         ogen = 0;
>                                         memset(uuid, 0, BTRFS_UUID_SIZE);
> --
> 2.39.0
>

Resolves: rhbz#2156710

Reviewed-by: Neal Gompa <neal@gompa.dev>
diff mbox series

Patch

diff --git a/cmds/subvolume-list.c b/cmds/subvolume-list.c
index 6d5ef509ae67..7cdb0402b8e5 100644
--- a/cmds/subvolume-list.c
+++ b/cmds/subvolume-list.c
@@ -870,14 +870,21 @@  static int list_subvol_search(int fd, struct rb_root *root_lookup)
 				ri = (struct btrfs_root_item *)(args.buf + off);
 				gen = btrfs_root_generation(ri);
 				flags = btrfs_root_flags(ri);
-				if(sh.len <
-				   sizeof(struct btrfs_root_item)) {
+				if(sh.len >= sizeof(struct btrfs_root_item)) {
+					/*
+					 * The new full btrfs_root_item with
+					 * timestamp and UUID.
+					 */
 					otime = btrfs_stack_timespec_sec(&ri->otime);
 					ogen = btrfs_root_otransid(ri);
 					memcpy(uuid, ri->uuid, BTRFS_UUID_SIZE);
 					memcpy(puuid, ri->parent_uuid, BTRFS_UUID_SIZE);
 					memcpy(ruuid, ri->received_uuid, BTRFS_UUID_SIZE);
 				} else {
+					/*
+					 * The old v0 root item, which doesn't
+					 * has timestamp nor UUID.
+					 */
 					otime = 0;
 					ogen = 0;
 					memset(uuid, 0, BTRFS_UUID_SIZE);