70 lines
2.4 KiB
Diff
70 lines
2.4 KiB
Diff
From fd138f8678808717635a145832c1b13320ce6cd2 Mon Sep 17 00:00:00 2001
|
|
From: Qu Wenruo <wqu@suse.com>
|
|
Date: Tue, 27 Dec 2022 13:25:12 +0800
|
|
Subject: [PATCH] btrfs-progs: fix the wrong timestamp and UUID check for root
|
|
items
|
|
|
|
[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 6d5ef509a..7cdb0402b 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);
|