Compare commits

...

10 Commits

Author SHA1 Message Date
openeuler-ci-bot
5397fe7c66
!73 [sync] PR-72: btrfs-progs: image: fix the bug that filename sanitization not working
From: @openeuler-sync-bot 
Reviewed-by: @swf504 
Signed-off-by: @swf504
2024-09-25 08:59:00 +00:00
liuh
ccf8e506ad btrfs-progs: image: fix the bug that filename sanitization not working
(cherry picked from commit f0bb91c62aede9faabf09f74a5cc1fb2f164feea)
2024-09-14 15:08:49 +08:00
openeuler-ci-bot
0b4e4982ac
!71 [sync] PR-70: btrfs-progs: corrupt-block: fix memory leak in debug_corrupt_sector()
From: @openeuler-sync-bot 
Reviewed-by: @swf504 
Signed-off-by: @swf504
2024-09-13 02:58:21 +00:00
cenhuilin
5b44747ee5 btrfs-progs: corrupt-block: fix memory leak in debug_corrupt_sector()
(cherry picked from commit 0557147f4186302bf243186c313a61e2a8377cd4)
2024-09-06 14:57:07 +08:00
openeuler-ci-bot
199d0486df
!68 [sync] PR-66: btrfs-progs: convert: 修复ext2/4文件系统转换成btrfs文件系统BUG
From: @openeuler-sync-bot 
Reviewed-by: @swf504 
Signed-off-by: @swf504
2024-09-06 06:55:53 +00:00
liuh
f75ed21b01 btrfs-progs: convert: insert a dummy inode item before inode ref for ext2/4
(cherry picked from commit a518b0932c70bfd79143d402bb110cf6fd831466)
2024-09-06 09:45:24 +08:00
openeuler-ci-bot
53d9523266
!63 [sync] PR-61: btrfs-progs: fix the conflicting super block flags
From: @openeuler-sync-bot 
Reviewed-by: @swf504 
Signed-off-by: @swf504
2024-08-31 01:21:02 +00:00
liuh
61c135fc6c btrfs-progs: fix the conflicting super block flags
(cherry picked from commit f57a68cd065320c35302a1eb8adbd80a0988536a)
2024-08-27 19:41:24 +08:00
openeuler-ci-bot
3088a02b27
!59 [sync] PR-57: btrfs-progs: error out immediately if an unknown backref type is found
From: @openeuler-sync-bot 
Reviewed-by: @swf504 
Signed-off-by: @swf504
2024-07-26 08:04:57 +00:00
liuh
85612ed50b btrfs-progs: error out immediately if an unknown backref type is found
(cherry picked from commit 77c42223277a6b225d3a7ce0ded0a907688b0639)
2024-07-26 15:38:06 +08:00
7 changed files with 668 additions and 1 deletions

View File

@ -0,0 +1,42 @@
From 0eeb12aef5ed18b3ecb5346440742971d5b11703 Mon Sep 17 00:00:00 2001
From: Qu Wenruo <wqu@suse.com>
Date: Tue, 4 Jun 2024 14:17:51 +0930
Subject: [PATCH] btrfs-progs: error out immediately if an unknown backref type
is found
There is a bug report that for fuzzed image
bko-155621-bad-block-group-offset.raw, "btrfs check --mode=lowmem
--repair" would lead to an endless loop.
Unlike original mode, lowmem mode relies on the backref walk to properly
go through each root, but unfortunately inside __add_inline_refs() we
doesn't handle unknown backref types correctly, causing it never moving
forward thus deadloop.
Fix it by erroring out to prevent an endless loop.
Issue: #788
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
---
kernel-shared/backref.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel-shared/backref.c b/kernel-shared/backref.c
index d9e8d2f..6866d6d 100644
--- a/kernel-shared/backref.c
+++ b/kernel-shared/backref.c
@@ -650,7 +650,8 @@ static int __add_inline_refs(struct btrfs_fs_info *fs_info,
break;
}
default:
- WARN_ON(1);
+ error("invalid backref type: %u", type);
+ ret = -EUCLEAN;
}
if (ret)
return ret;
--
2.43.0

View File

@ -0,0 +1,93 @@
From 2f8a6ee294e070427a54cacce571d06062390e02 Mon Sep 17 00:00:00 2001
From: Qu Wenruo <wqu@suse.com>
Date: Sat, 8 Jun 2024 13:29:34 +0930
Subject: [PATCH] btrfs-progs: fix the conflicting super block flags
[BUG]
There is a bug report that a canceled checksum conversion (still
experimental feature) resulted in unexpected super flags:
csum_type 0 (crc32c)
csum_size 4
csum 0x14973811 [match]
bytenr 65536
flags 0x1000000001
( WRITTEN |
CHANGING_FSID_V2 )
magic _BHRfS_M [match]
While for a filesystem under checksum conversion it should have either
CHANGING_DATA_CSUM or CHANGING_META_CSUM.
[CAUSE]
It turns out that, due to btrfs-progs keeps its own extra flags inside
its own ctree.h headers, not the shared uapi headers, we have
conflicting super flags:
kernel-shared/uapi/btrfs_tree.h:#define BTRFS_SUPER_FLAG_METADUMP_V2 (1ULL << 34)
kernel-shared/uapi/btrfs_tree.h:#define BTRFS_SUPER_FLAG_CHANGING_FSID (1ULL << 35)
kernel-shared/uapi/btrfs_tree.h:#define BTRFS_SUPER_FLAG_CHANGING_FSID_V2 (1ULL << 36)
kernel-shared/ctree.h:#define BTRFS_SUPER_FLAG_CHANGING_DATA_CSUM (1ULL << 36)
kernel-shared/ctree.h:#define BTRFS_SUPER_FLAG_CHANGING_META_CSUM (1ULL << 37)
Note that CHANGING_FSID_V2 is conflicting with CHANGING_DATA_CSUM.
[FIX]
Cross port the proper updated uapi headers into btrfs-progs, and remove
the definition from ctree.h.
This would change the value for CHANGING_DATA_CSUM and
CHANGING_META_CSUM, but considering they are experimental features, and
kernel would reject them anyway, the damage is not that huge and we can
accept such change before exposing it to end users.
Pull-request: #810
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
---
kernel-shared/ctree.h | 10 ----------
kernel-shared/uapi/btrfs_tree.h | 7 +++++++
2 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h
index bcf11d8..080c8c1 100644
--- a/kernel-shared/ctree.h
+++ b/kernel-shared/ctree.h
@@ -59,16 +59,6 @@ static inline unsigned long btrfs_chunk_item_size(int num_stripes)
sizeof(struct btrfs_stripe) * (num_stripes - 1);
}
-#define BTRFS_SUPER_FLAG_CHANGING_DATA_CSUM (1ULL << 36)
-#define BTRFS_SUPER_FLAG_CHANGING_META_CSUM (1ULL << 37)
-
-/*
- * The fs is undergoing block group tree feature change.
- * If no BLOCK_GROUP_TREE compat ro flag, it's changing from regular
- * bg item in extent tree to new bg tree.
- */
-#define BTRFS_SUPER_FLAG_CHANGING_BG_TREE (1ULL << 38)
-
static inline u32 __BTRFS_LEAF_DATA_SIZE(u32 nodesize)
{
return nodesize - sizeof(struct btrfs_header);
diff --git a/kernel-shared/uapi/btrfs_tree.h b/kernel-shared/uapi/btrfs_tree.h
index e2ac228..2713462 100644
--- a/kernel-shared/uapi/btrfs_tree.h
+++ b/kernel-shared/uapi/btrfs_tree.h
@@ -758,6 +758,13 @@ struct btrfs_free_space_header {
#define BTRFS_SUPER_FLAG_CHANGING_FSID (1ULL << 35)
#define BTRFS_SUPER_FLAG_CHANGING_FSID_V2 (1ULL << 36)
+/*
+ * Temporaray flags utilized by btrfs-progs to do offline conversion. They are
+ * rejected by kernel. Keep them all here to avoid conflicts.
+ */
+#define BTRFS_SUPER_FLAG_CHANGING_BG_TREE (1ULL << 38)
+#define BTRFS_SUPER_FLAG_CHANGING_DATA_CSUM (1ULL << 39)
+#define BTRFS_SUPER_FLAG_CHANGING_META_CSUM (1ULL << 40)
/*
* items in the extent btree are used to record the objectid of the
--
2.43.0

View File

@ -0,0 +1,106 @@
From 631ee666394a36ec36abf1042956cdb2e6058b86 Mon Sep 17 00:00:00 2001
From: Qu Wenruo <wqu@suse.com>
Date: Fri, 12 Jan 2024 16:13:27 +1030
Subject: [PATCH] btrfs-progs: convert: for ext2, fix possible tree-checker
error when converting a large fs
[BUG]
There is a report about failed btrfs-convert, which shows the following
error:
corrupt leaf: root=5 block=5001928998912 slot=1 ino=89911763, invalid previous key objectid, have 89911762 expect 89911763
ERROR: failed to copy ext2 inode 89911320: -5
ERROR: error during copy_inodes -5
WARNING: error during conversion, the original filesystem is not modified
[CAUSE]
Above error is triggered when checking the following items inside a
subvolume:
- inode ref
- dir item/index
- file extent
- xattr
This is to make sure these items have correct previous key.
However btrfs-convert is not following this requirement, it always
inserts those items first, then creates a btrfs_inode for it.
Thus it can lead to the error.
This can only happen for large fs, as for most cases we have all these
modified tree blocks cached, thus tree-checker won't be triggered.
But when the tree block cache is not hit, and we have to read from disk,
then such behavior can lead to above tree-checker error.
[FIX]
Make sure we insert the inode item first, then the file extents/dir
items/xattrs. And after the file extents/dir items/xattrs inserted, we
update the existing inode (to update its size and bytes).
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
---
convert/source-ext2.c | 31 ++++++++++++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/convert/source-ext2.c b/convert/source-ext2.c
index cfffc9e..ad7aeda 100644
--- a/convert/source-ext2.c
+++ b/convert/source-ext2.c
@@ -854,6 +854,8 @@ static int ext2_copy_single_inode(struct btrfs_trans_handle *trans,
int ret;
int s_inode_size;
struct btrfs_inode_item btrfs_inode;
+ struct btrfs_key inode_key;
+ struct btrfs_path path = { 0 };
if (ext2_inode->i_links_count == 0)
return 0;
@@ -875,6 +877,15 @@ static int ext2_copy_single_inode(struct btrfs_trans_handle *trans,
}
ext2_convert_inode_flags(&btrfs_inode, ext2_inode);
+ /*
+ * The inode item must be inserted before any file extents/dir items/xattrs,
+ * or we may trigger tree-checker. File extents/dir items/xattrs require
+ * the previous item has the same key objectid.
+ */
+ ret = btrfs_insert_inode(trans, root, objectid, &btrfs_inode);
+ if (ret < 0)
+ return ret;
+
switch (ext2_inode->i_mode & S_IFMT) {
case S_IFREG:
ret = ext2_create_file_extents(trans, root, objectid,
@@ -901,7 +912,25 @@ static int ext2_copy_single_inode(struct btrfs_trans_handle *trans,
if (ret)
return ret;
}
- return btrfs_insert_inode(trans, root, objectid, &btrfs_inode);
+
+ /*
+ * Update the inode item, as above insert never updates the inode's
+ * nbytes and size.
+ */
+ inode_key.objectid = objectid;
+ inode_key.type = BTRFS_INODE_ITEM_KEY;
+ inode_key.offset = 0;
+
+ ret = btrfs_lookup_inode(trans, root, &path, &inode_key, 1);
+ if (ret > 0)
+ ret = -ENOENT;
+ if (ret < 0)
+ return ret;
+ write_extent_buffer(path.nodes[0], &btrfs_inode,
+ btrfs_item_ptr_offset(path.nodes[0], path.slots[0]),
+ sizeof(btrfs_inode));
+ btrfs_release_path(&path);
+ return 0;
}
static bool ext2_is_special_inode(ext2_filsys ext2_fs, ext2_ino_t ino)
--
2.43.0

View File

@ -0,0 +1,210 @@
From 517ba2d9e58aa50c4dbfe873ac4634cfd9c07ff2 Mon Sep 17 00:00:00 2001
From: Qu Wenruo <wqu@suse.com>
Date: Sat, 13 Jan 2024 19:07:06 +1030
Subject: [PATCH] btrfs-progs: convert: insert a dummy inode item before inode
ref for ext2/4
[BUG]
There is a report about failed btrfs-convert, which shows the following
error:
Create btrfs metadata
corrupt leaf: root=5 block=5001931145216 slot=1 ino=89911763, invalid previous key objectid, have 89911762 expect 89911763
leaf 5001931145216 items 336 free space 7 generation 90 owner FS_TREE
leaf 5001931145216 flags 0x1(WRITTEN) backref revision 1
fs uuid 8b69f018-37c3-4b30-b859-42ccfcbe2449
chunk uuid 448ce78c-ea41-49f6-99dc-46ad80b93da9
item 0 key (89911762 INODE_REF 3858733) itemoff 16222 itemsize 61
index 171 namelen 51 name: [FILENAME1]
item 1 key (89911763 INODE_REF 3858733) itemoff 16161 itemsize 61
index 103 namelen 51 name: [FILENAME2]
[CAUSE]
When iterating a directory, btrfs-convert would insert the DIR_ITEMs,
along with the INODE_REF of that inode.
This leads to above stray INODE_REFs, and trigger the tree-checker.
This can only happen for large fs, as for most cases we have all these
modified tree blocks cached, thus tree-checker won't be triggered.
But when the tree block cache is not hit, and we have to read from disk,
then such behavior can lead to above tree-checker error.
[FIX]
Insert a dummy INODE_ITEM for the INODE_REF first, the inode items would
be updated when iterating the child inode of the directory.
Issue: #731
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
---
check/mode-common.h | 15 ---------------
common/utils.h | 16 ++++++++++++++++
convert/source-ext2.c | 30 ++++++++++++++++++++----------
convert/source-fs.c | 20 ++++++++++++++++++++
4 files changed, 56 insertions(+), 25 deletions(-)
diff --git a/check/mode-common.h b/check/mode-common.h
index 894bbbb..80672e5 100644
--- a/check/mode-common.h
+++ b/check/mode-common.h
@@ -167,21 +167,6 @@ static inline bool is_valid_imode(u32 imode)
int recow_extent_buffer(struct btrfs_root *root, struct extent_buffer *eb);
-static inline u32 btrfs_type_to_imode(u8 type)
-{
- static u32 imode_by_btrfs_type[] = {
- [BTRFS_FT_REG_FILE] = S_IFREG,
- [BTRFS_FT_DIR] = S_IFDIR,
- [BTRFS_FT_CHRDEV] = S_IFCHR,
- [BTRFS_FT_BLKDEV] = S_IFBLK,
- [BTRFS_FT_FIFO] = S_IFIFO,
- [BTRFS_FT_SOCK] = S_IFSOCK,
- [BTRFS_FT_SYMLINK] = S_IFLNK,
- };
-
- return imode_by_btrfs_type[(type)];
-}
-
int get_extent_item_generation(u64 bytenr, u64 *gen_ret);
/*
diff --git a/common/utils.h b/common/utils.h
index e267814..85f086e 100644
--- a/common/utils.h
+++ b/common/utils.h
@@ -22,6 +22,7 @@
#include "kerncompat.h"
#include <stdbool.h>
#include <stddef.h>
+#include <sys/stat.h>
#include "kernel-lib/list.h"
#include "kernel-shared/volumes.h"
#include "common/fsfeatures.h"
@@ -40,6 +41,21 @@ enum exclusive_operation {
BTRFS_EXCLOP_UNKNOWN = -1,
};
+static inline u32 btrfs_type_to_imode(u8 type)
+{
+ static u32 imode_by_btrfs_type[] = {
+ [BTRFS_FT_REG_FILE] = S_IFREG,
+ [BTRFS_FT_DIR] = S_IFDIR,
+ [BTRFS_FT_CHRDEV] = S_IFCHR,
+ [BTRFS_FT_BLKDEV] = S_IFBLK,
+ [BTRFS_FT_FIFO] = S_IFIFO,
+ [BTRFS_FT_SOCK] = S_IFSOCK,
+ [BTRFS_FT_SYMLINK] = S_IFLNK,
+ };
+
+ return imode_by_btrfs_type[(type)];
+}
+
/* 2 for "0x", 2 for each byte, plus nul */
#define BTRFS_CSUM_STRING_LEN (2 + 2 * BTRFS_CSUM_SIZE + 1)
void btrfs_format_csum(u16 csum_type, const u8 *data, char *output);
diff --git a/convert/source-ext2.c b/convert/source-ext2.c
index ad7aeda..2186b25 100644
--- a/convert/source-ext2.c
+++ b/convert/source-ext2.c
@@ -857,6 +857,10 @@ static int ext2_copy_single_inode(struct btrfs_trans_handle *trans,
struct btrfs_key inode_key;
struct btrfs_path path = { 0 };
+ inode_key.objectid = objectid;
+ inode_key.type = BTRFS_INODE_ITEM_KEY;
+ inode_key.offset = 0;
+
if (ext2_inode->i_links_count == 0)
return 0;
@@ -878,13 +882,23 @@ static int ext2_copy_single_inode(struct btrfs_trans_handle *trans,
ext2_convert_inode_flags(&btrfs_inode, ext2_inode);
/*
- * The inode item must be inserted before any file extents/dir items/xattrs,
- * or we may trigger tree-checker. File extents/dir items/xattrs require
- * the previous item has the same key objectid.
+ * The inode may already be created (with dummy contents), in that
+ * case we don't need to do anything yet.
+ * The inode item would be updated at the end anyway.
*/
- ret = btrfs_insert_inode(trans, root, objectid, &btrfs_inode);
- if (ret < 0)
- return ret;
+ ret = btrfs_lookup_inode(trans, root, &path, &inode_key, 1);
+ btrfs_release_path(&path);
+ if (ret > 0) {
+ /*
+ * No inode item yet, the inode item must be inserted before
+ * any file extents/dir items/xattrs, or we may trigger
+ * tree-checker. File extents/dir items/xattrs require the
+ * previous item to have the same key objectid.
+ */
+ ret = btrfs_insert_inode(trans, root, objectid, &btrfs_inode);
+ if (ret < 0)
+ return ret;
+ }
switch (ext2_inode->i_mode & S_IFMT) {
case S_IFREG:
@@ -917,10 +931,6 @@ static int ext2_copy_single_inode(struct btrfs_trans_handle *trans,
* Update the inode item, as above insert never updates the inode's
* nbytes and size.
*/
- inode_key.objectid = objectid;
- inode_key.type = BTRFS_INODE_ITEM_KEY;
- inode_key.offset = 0;
-
ret = btrfs_lookup_inode(trans, root, &path, &inode_key, 1);
if (ret > 0)
ret = -ENOENT;
diff --git a/convert/source-fs.c b/convert/source-fs.c
index fe1ff7d..6656143 100644
--- a/convert/source-fs.c
+++ b/convert/source-fs.c
@@ -23,6 +23,8 @@
#include "kernel-shared/ctree.h"
#include "kernel-shared/disk-io.h"
#include "kernel-shared/volumes.h"
+#include "kernel-shared/transaction.h"
+#include "common/utils.h"
#include "common/internal.h"
#include "common/messages.h"
#include "common/extent-cache.h"
@@ -183,6 +185,7 @@ int convert_insert_dirent(struct btrfs_trans_handle *trans,
{
int ret;
u64 inode_size;
+ struct btrfs_inode_item dummy_iitem = { 0 };
struct btrfs_key location = {
.objectid = objectid,
.offset = 0,
@@ -193,6 +196,23 @@ int convert_insert_dirent(struct btrfs_trans_handle *trans,
dir, &location, file_type, index_cnt);
if (ret)
return ret;
+
+ btrfs_set_stack_inode_mode(&dummy_iitem, btrfs_type_to_imode(file_type));
+ btrfs_set_stack_inode_generation(&dummy_iitem, trans->transid);
+ btrfs_set_stack_inode_transid(&dummy_iitem, trans->transid);
+ /*
+ * We must have an INOTE_ITEM before INODE_REF, or tree-checker won't
+ * be happy.
+ * The content of the INODE_ITEM would be properly updated when iterating
+ * that child inode, but we should still try to make it as valid as
+ * possible, or we may still trigger some tree checker.
+ */
+ ret = btrfs_insert_inode(trans, root, objectid, &dummy_iitem);
+ /* The inode item is already there, just skip it. */
+ if (ret == -EEXIST)
+ ret = 0;
+ if (ret < 0)
+ return ret;
ret = btrfs_insert_inode_ref(trans, root, name, name_len,
objectid, dir, index_cnt);
if (ret)
--
2.43.0

View File

@ -0,0 +1,56 @@
From fd5a80e5bfb472c31eeab4caa4f4907b803b1b60 Mon Sep 17 00:00:00 2001
From: Qu Wenruo <wqu@suse.com>
Date: Fri, 6 Sep 2024 12:30:45 +0800
Subject: [PATCH] btrfs-progs: corrupt-block: fix memory leak in debug_corrupt_sector().
ASAN build (make D=asan) detects a memory leak in
btrfs-corrupt-block inside debug_corrupt_sector().
This can be reproduced by fsck/013 test case.
The cause is pretty simple, we just malloc a sector and forgot to free
it.
Issue: #806
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
---
btrfs-corrupt-block.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c
index 1245973..e883198 100644
--- a/btrfs-corrupt-block.c
+++ b/btrfs-corrupt-block.c
@@ -70,7 +70,7 @@ static int debug_corrupt_sector(struct btrfs_root *root, u64 logical, int mirror
if (ret < 0) {
errno = -ret;
error("cannot read bytenr %llu: %m", logical);
- return ret;
+ goto out;
}
printf("corrupting %llu copy %d\n", logical, mirror_num);
memset(buf, 0, sectorsize);
@@ -78,7 +78,7 @@ static int debug_corrupt_sector(struct btrfs_root *root, u64 logical, int mirror
if (ret < 0) {
errno = -ret;
error("cannot write bytenr %llu: %m", logical);
- return ret;
+ goto out;
}
}
@@ -90,7 +90,8 @@ static int debug_corrupt_sector(struct btrfs_root *root, u64 logical, int mirror
if (mirror_num > num_copies)
break;
}
-
+out:
+ free(buf);
return 0;
}
--
2.23.0

View File

@ -0,0 +1,138 @@
From a2c6c5933368b573b6509b0104b1b3da916a2ee1 Mon Sep 17 00:00:00 2001
From: Qu Wenruo <wqu@suse.com>
Date: Mon, 8 Jul 2024 13:33:54 +0930
Subject: [PATCH] btrfs-progs: image: fix the bug that filename sanitization
not working
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[BUG]
There is a bug report that image dump taken by "btrfs-image -s" doesn't
really sanitize the filenames:
# truncates -s 1G source.raw
# mkfs.btrfs -f source.raw
# mount source.raw $mnt
# touch $mnt/top_secret_filename
# touch $mnt/secret_filename
# umount $mnt
# btrfs-image -s source.raw dump.img
# string dump.img | grep filename
top_secret_filename
secret_filename
top_secret_filename
secret_filename
top_secret_filename
[CAUSE]
Using above image to store the fs, and we got the following result in fs
tree:
item 0 key (256 INODE_ITEM 0) itemoff 16123 itemsize 160
generation 3 transid 7 size 68 nbytes 16384
block group 0 mode 40755 links 1 uid 0 gid 0 rdev 0
sequence 2 flags 0x0(none)
item 1 key (256 INODE_REF 256) itemoff 16111 itemsize 12
index 0 namelen 2 name: ..
item 2 key (256 DIR_ITEM 439756795) itemoff 16062 itemsize 49
location key (257 INODE_ITEM 0) type FILE
transid 7 data_len 0 name_len 19
name: top_secret_filename
item 3 key (256 DIR_ITEM 693462946) itemoff 16017 itemsize 45
location key (258 INODE_ITEM 0) type FILE
transid 7 data_len 0 name_len 15
name: secret_filename
item 4 key (256 DIR_INDEX 2) itemoff 15968 itemsize 49
location key (257 INODE_ITEM 0) type FILE
transid 7 data_len 0 name_len 19
name: top_secret_filename
item 5 key (256 DIR_INDEX 3) itemoff 15923 itemsize 45
location key (258 INODE_ITEM 0) type FILE
transid 7 data_len 0 name_len 15
name: secret_filename
item 6 key (257 INODE_ITEM 0) itemoff 15763 itemsize 160
generation 7 transid 7 size 0 nbytes 0
block group 0 mode 100644 links 1 uid 0 gid 0 rdev 0
sequence 1 flags 0x0(none)
item 7 key (257 INODE_REF 256) itemoff 15734 itemsize 29
index 2 namelen 19 name: top_secret_filename
item 8 key (258 INODE_ITEM 0) itemoff 15574 itemsize 160
generation 7 transid 7 size 0 nbytes 0
block group 0 mode 100644 links 1 uid 0 gid 0 rdev 0
sequence 1 flags 0x0(none)
item 9 key (258 INODE_REF 256) itemoff 15549 itemsize 25
index 3 namelen 15 name: 1<><31><EFBFBD>'<27>gc*&R
The result shows, only the last INODE_REF got sanitized, all the
remaining are not touched at all.
This is caused by how we sanitize the filenames:
copy_buffer()
|- memcpy(dst, src->data, src->len);
| This means we copy the whole eb into our buffer already.
|
|- zero_items()
|- sanitize_name()
|- eb = alloc_dummy_eb();
|- memcpy(eb->data, src->data, src->len);
| This means we generate a dummy eb with the same contents of
| the source eb.
|
|- sanitize_dir_item();
| We override the dir item of the given item (specified by the
| slot number) inside our dummy eb.
|
|- memcpy(dst, eb->data, eb->lem);
The last one copy the dummy eb into our buffer, with only the slot
corrupted.
But when the whole work flow hits the next slot, we only corrupt the
next slot, but still copy the whole dummy eb back to buffer.
This means the previous slot would be overwritten by the old unsanitized
data.
Resulting only the last slot is corrupted.
[FIX]
Fix the bug by only copying back the corrupted item to the buffer.
So that other slots won't be overwritten by unsanitized data.
Reported-by: Andrea Gelmini <andrea.gelmini@gmail.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
image/sanitize.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/image/sanitize.c b/image/sanitize.c
index 084da22..ef4f6e5 100644
--- a/image/sanitize.c
+++ b/image/sanitize.c
@@ -449,6 +449,8 @@ void sanitize_name(enum sanitize_mode sanitize, struct rb_root *name_tree,
int slot)
{
struct extent_buffer *eb;
+ u32 item_ptr_off = btrfs_item_ptr_offset(src, slot);
+ u32 item_ptr_size = btrfs_item_size(src, slot);
eb = alloc_dummy_eb(src->start, src->len);
if (!eb) {
@@ -476,7 +478,11 @@ void sanitize_name(enum sanitize_mode sanitize, struct rb_root *name_tree,
break;
}
- memcpy(dst, eb->data, eb->len);
+ /*
+ * Only overwrite the sanitized part, or we can overwrite previous
+ * sanitized value with the old values from @src.
+ */
+ memcpy(dst + item_ptr_off, eb->data + item_ptr_off, item_ptr_size);
free(eb);
}
--
2.43.0

View File

@ -1,6 +1,6 @@
Name: btrfs-progs
Version: 6.6.3
Release: 9
Release: 14
Summary: btrfs userspace programs
License: GPLv2 and GPL+ and LGPL-2.1+ and GPL-3.0+ and LGPL-2.1 and MIT
URL: https://btrfs.wiki.kernel.org/index.php/Main_Page
@ -14,6 +14,12 @@ Patch0005: 0005-btrfs-progs-fix-freeing-of-device-after-error-in-btr.patch
Patch0006: 0006-fix-double-free-on-error-in-read_raid56.patch
Patch0007: 0007-btrfs-progs-fi-show-canonicalize-path-when-using-blk.patch
Patch0008: 0008-btrfs-progs-tune-fix-the-missing-close-of-filesystem.patch
Patch0009: 0009-btrfs-progs-error-out-immediately-if-an-unknown-back.patch
Patch0010: 0010-btrfs-progs-fix-the-conflicting-super-block-flags.patch
Patch0011: 0011-btrfs-progs-convert-for-ext2-fix-possible-tree-check.patch
Patch0012: 0012-btrfs-progs-convert-insert-a-dummy-inode-item-before.patch
Patch0013: 0013-btrfs-progs-corrupt-block-fix-memory-leak-in-debug_c.patch
Patch0014: 0014-btrfs-progs-image-fix-the-bug-that-filename-sanitiza.patch
BuildRequires: python3-devel >= 3.4
BuildRequires: libacl-devel, e2fsprogs-devel, libblkid-devel, libuuid-devel, zlib-devel, libzstd-devel, lzo-devel, systemd-devel
@ -79,6 +85,22 @@ make mandir=%{_mandir} bindir=%{_sbindir} libdir=%{_libdir} incdir=%{_includedir
%{_mandir}/man8/*.gz
%changelog
* Tue Sep 10 2024 liuh <liuhuan01@kylinos.cn> - 6.6.3-14
- btrfs-progs: image: fix the bug that filename sanitization not working
* Fri Sep 6 2024 cenhuilin <cenhuilin@kylinos.cn> - 6.6.3-13
- btrfs-progs: corrupt-block: fix memory leak in debug_corrupt_sector()
* Tue Sep 3 2024 liuh <liuhuan01@kylinos.cn> - 6.6.3-12
- btrfs-progs: convert: insert a dummy inode item before inode ref for ext2/4
- btrfs-progs: convert: for ext2, fix possible tree-checker error when converting a large fs
* Tue Aug 27 2024 liuh <liuhuan01@kylinos.cn> - 6.6.3-11
- btrfs-progs: fix the conflicting super block flags
* Wed Jul 17 2024 liuh <liuhuan01@kylinos.cn> - 6.6.3-10
- btrfs-progs: error out immediately if an unknown backref type is found
* Tue Jul 2 2024 cenhuilin <cenhuilin@kylinos.cn> - 6.6.3-9
- btrfs-progs: tune: fix the missing close() of filesystem fd