From: Dan Carpenter <error27@gmail.com>
To: Filipe Manana <fdmanana@suse.com>
Cc: linux-btrfs@vger.kernel.org
Subject: [bug report] btrfs: fix corrupt read due to bad offset of a compressed extent map
Date: Mon, 15 Jun 2026 15:46:56 +0300 [thread overview]
Message-ID: <ai_0QHRa0y-_d72k@stanley.mountain> (raw)
Hello Filipe Manana,
Commit de9f46cb0044 ("btrfs: fix corrupt read due to bad offset of a
compressed extent map") from Jul 11, 2024 (linux-next), leads to the
following Smatch static checker warning:
fs/btrfs/tests/extent-map-tests.c:979 test_case_8()
error: dereferencing freed memory 'em' (line 973 btrfs_free_extent_map())
fs/btrfs/tests/extent-map-tests.c
912 static int test_case_8(struct btrfs_fs_info *fs_info, struct btrfs_inode *inode)
913 {
914 struct extent_map_tree *em_tree = &inode->extent_tree;
915 struct extent_map *em;
916 int ret;
917 int ret2;
918
919 em = btrfs_alloc_extent_map();
920 if (!em) {
921 test_std_err(TEST_ALLOC_EXTENT_MAP);
922 return -ENOMEM;
923 }
924
925 /* Compressed extent for the file range [120K, 128K). */
926 em->start = SZ_1K * 120;
927 em->len = SZ_8K;
928 em->disk_num_bytes = SZ_4K;
929 em->ram_bytes = SZ_8K;
930 em->flags |= EXTENT_FLAG_COMPRESS_ZLIB;
931 write_lock(&em_tree->lock);
932 ret = btrfs_add_extent_mapping(inode, &em, em->start, em->len);
933 write_unlock(&em_tree->lock);
934 btrfs_free_extent_map(em);
935 if (ret < 0) {
936 test_err("couldn't add extent map for range [120K, 128K)");
937 goto out;
938 }
939
940 em = btrfs_alloc_extent_map();
941 if (!em) {
942 test_std_err(TEST_ALLOC_EXTENT_MAP);
943 ret = -ENOMEM;
944 goto out;
945 }
946
947 /*
948 * Compressed extent for the file range [108K, 144K), which overlaps
949 * with the [120K, 128K) we previously inserted.
950 */
951 em->start = SZ_1K * 108;
952 em->len = SZ_1K * 36;
953 em->disk_num_bytes = SZ_4K;
954 em->ram_bytes = SZ_1K * 36;
955 em->flags |= EXTENT_FLAG_COMPRESS_ZLIB;
956
957 /*
958 * Try to add the extent map but with a search range of [140K, 144K),
959 * this should succeed and adjust the extent map to the range
960 * [128K, 144K), with a length of 16K and an offset of 20K.
961 *
962 * This simulates a scenario where in the subvolume tree of an inode we
963 * have a compressed file extent item for the range [108K, 144K) and we
964 * have an overlapping compressed extent map for the range [120K, 128K),
965 * which was created by an encoded write, but its ordered extent was not
966 * yet completed, so the subvolume tree doesn't have yet the file extent
967 * item for that range - we only have the extent map in the inode's
968 * extent map tree.
969 */
970 write_lock(&em_tree->lock);
971 ret = btrfs_add_extent_mapping(inode, &em, SZ_1K * 140, SZ_4K);
972 write_unlock(&em_tree->lock);
973 btrfs_free_extent_map(em);
This looks like btrfs_free_extent_map() frees "em".
974 if (ret < 0) {
975 test_err("couldn't add extent map for range [108K, 144K)");
976 goto out;
977 }
978
--> 979 if (em->start != SZ_128K) {
^^^^^^^^^
980 test_err("unexpected extent map start %llu (should be 128K)", em->start);
^^^^^^^^^
981 ret = -EINVAL;
982 goto out;
983 }
984 if (em->len != SZ_16K) {
^^^^^^^
985 test_err("unexpected extent map length %llu (should be 16K)", em->len);
^^^^^^^
986 ret = -EINVAL;
987 goto out;
988 }
989 if (em->offset != SZ_1K * 20) {
^^^^^^^^^^
990 test_err("unexpected extent map offset %llu (should be 20K)", em->offset);
^^^^^^^^^^
991 ret = -EINVAL;
992 goto out;
993 }
994 out:
995 ret2 = free_extent_map_tree(inode);
996 if (ret == 0)
997 ret = ret2;
998
999 return ret;
1000 }
This email is a free service from the Smatch-CI project [smatch.sf.net].
regards,
dan carpenter
next reply other threads:[~2026-06-15 12:47 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-15 12:46 Dan Carpenter [this message]
2026-06-15 12:56 ` [bug report] btrfs: fix corrupt read due to bad offset of a compressed extent map Filipe Manana
2026-06-15 13:12 ` Dan Carpenter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ai_0QHRa0y-_d72k@stanley.mountain \
--to=error27@gmail.com \
--cc=fdmanana@suse.com \
--cc=linux-btrfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox