]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
f2fs: fix several potential integer overflows in file offsets
authorNikita Zhandarovich <n.zhandarovich@fintech.ru>
Wed, 24 Jul 2024 17:28:38 +0000 (10:28 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 4 Oct 2024 14:29:54 +0000 (16:29 +0200)
commit 1cade98cf6415897bf9342ee451cc5b40b58c638 upstream.

When dealing with large extents and calculating file offsets by
summing up according extent offsets and lengths of unsigned int type,
one may encounter possible integer overflow if the values are
big enough.

Prevent this from happening by expanding one of the addends to
(pgoff_t) type.

Found by Linux Verification Center (linuxtesting.org) with static
analysis tool SVACE.

Fixes: d323d005ac4a ("f2fs: support file defragment")
Cc: stable@vger.kernel.org
Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/f2fs/extent_cache.c
fs/f2fs/file.c

index 6a9a470345bfc772fca726a9c92e7ba73d222075..d6fb053b6dfbbe3966f02132c5c8acd543de947e 100644 (file)
@@ -367,7 +367,7 @@ static unsigned int __free_extent_tree(struct f2fs_sb_info *sbi,
 static void __drop_largest_extent(struct extent_tree *et,
                                        pgoff_t fofs, unsigned int len)
 {
-       if (fofs < et->largest.fofs + et->largest.len &&
+       if (fofs < (pgoff_t)et->largest.fofs + et->largest.len &&
                        fofs + len > et->largest.fofs) {
                et->largest.len = 0;
                et->largest_updated = true;
@@ -457,7 +457,7 @@ static bool __lookup_extent_tree(struct inode *inode, pgoff_t pgofs,
 
        if (type == EX_READ &&
                        et->largest.fofs <= pgofs &&
-                       et->largest.fofs + et->largest.len > pgofs) {
+                       (pgoff_t)et->largest.fofs + et->largest.len > pgofs) {
                *ei = et->largest;
                ret = true;
                stat_inc_largest_node_hit(sbi);
index f2969d8603421939b1d11952446192251e22cf68..cb7afdcbe45eef5d965d1ca52e249d7c6eb2e7a8 100644 (file)
@@ -2687,7 +2687,7 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
         * block addresses are continuous.
         */
        if (f2fs_lookup_read_extent_cache(inode, pg_start, &ei)) {
-               if (ei.fofs + ei.len >= pg_end)
+               if ((pgoff_t)ei.fofs + ei.len >= pg_end)
                        goto out;
        }