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 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.