summaryrefslogtreecommitdiff
path: root/fs/btrfs/reflink.c
diff options
context:
space:
mode:
authorFilipe Manana <fdmanana@suse.com>2022-02-17 15:12:08 +0300
committerDavid Sterba <dsterba@suse.com>2022-03-14 15:13:52 +0300
commitb2d9f2dc019fb739b8c0765ddcc184c31f7ae54b (patch)
treeefd6108e74d75282bc465756bea8d501f615eeb8 /fs/btrfs/reflink.c
parent1f4613cdbe7739ce291554b316bff8e551383389 (diff)
downloadlinux-b2d9f2dc019fb739b8c0765ddcc184c31f7ae54b.tar.xz
btrfs: deal with unexpected extent type during reflinking
Smatch complains about a possible dereference of a pointer that was not initialized: CC [M] fs/btrfs/reflink.o CHECK fs/btrfs/reflink.c fs/btrfs/reflink.c:533 btrfs_clone() error: potentially dereferencing uninitialized 'trans'. This is because we are not dealing with the case where the type of a file extent has an unexpected value (not regular, not prealloc and not inline), in which case the transaction handle pointer is not initialized. Such unexpected type should be impossible, except in case of some memory corruption caused either by bad hardware or some software bug causing something like a buffer overrun. So ASSERT that if the extent type is neither regular nor prealloc, then it must be inline. Bail out with -EUCLEAN and a warning in case it is not. This silences smatch. Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/reflink.c')
-rw-r--r--fs/btrfs/reflink.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/fs/btrfs/reflink.c b/fs/btrfs/reflink.c
index 07e19e069c84..03d60db0c5a3 100644
--- a/fs/btrfs/reflink.c
+++ b/fs/btrfs/reflink.c
@@ -494,7 +494,8 @@ process_slot:
&clone_info, &trans);
if (ret)
goto out;
- } else if (type == BTRFS_FILE_EXTENT_INLINE) {
+ } else {
+ ASSERT(type == BTRFS_FILE_EXTENT_INLINE);
/*
* Inline extents always have to start at file offset 0
* and can never be bigger then the sector size. We can
@@ -505,7 +506,8 @@ process_slot:
*/
ASSERT(key.offset == 0);
ASSERT(datal <= fs_info->sectorsize);
- if (WARN_ON(key.offset != 0) ||
+ if (WARN_ON(type != BTRFS_FILE_EXTENT_INLINE) ||
+ WARN_ON(key.offset != 0) ||
WARN_ON(datal > fs_info->sectorsize)) {
ret = -EUCLEAN;
goto out;