[<prev] [next>] [day] [month] [year] [list]
Message-ID: <CACpam_ZrXZwb-=EKc8HTyH7VPSWhuWBUgO0n6_z3H6wv8k6r3w@mail.gmail.com>
Date: Mon, 1 Dec 2025 17:17:20 +0800
From: yao xiao <xiangyaof4free@...il.com>
To: jaegeuk@...nel.org, chao@...nel.org
Cc: linux-f2fs-devel@...ts.sourceforge.net, linux-fsdevel@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: [PATCH v2] f2fs: add overflow/underflow checks to update_sit_entry
From: Yao Xiao <xiangyaof4free@...il.com>
To: Jaegeuk Kim <jaegeuk@...nel.org>, Chao Yu <chao@...nel.org>
Cc: linux-f2fs-devel@...ts.sourceforge.net,
linux-fsdevel@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: [PATCH v2] f2fs: add overflow/underflow checks to update_sit_entry
The update_sit_entry() function performs an arithmetic operation between
se->valid_blocks (a 10-bit unsigned bitfield) and a signed integer 'del'.
Under C integer promotion rules, the signed integer is converted to unsigned
before the addition, which can lead to wraparound behavior:
- If 'del' is negative and large, it becomes a large unsigned integer,
resulting in an unintended huge positive addition.
- If 'del' is positive and large, the result can exceed the bitfield's
maximum representable range.
To avoid undefined behavior caused by performing the arithmetic first and
validating the result afterwards, this patch adds explicit overflow/underflow
checks before computing the new value. This ensures the operation is safe
and prevents inconsistent SIT metadata updates.
This change follows the defensive overflow check style used in previous
f2fs fixes addressing similar boundary issues.
Signed-off-by: Yao Xiao <xiangyaof4free@...il.com>
---
fs/f2fs/segment.c | 28 +++++++++++++++++++++++-----
1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index b45eace879d7..05ab34600e32 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2569,13 +2569,33 @@ static void update_sit_entry(struct
f2fs_sb_info *sbi, block_t blkaddr, int del)
struct seg_entry *se;
unsigned int segno, offset;
long int new_vblocks;
+ unsigned int max_valid;
segno = GET_SEGNO(sbi, blkaddr);
if (segno == NULL_SEGNO)
return;
se = get_seg_entry(sbi, segno);
- new_vblocks = se->valid_blocks + del;
+ max_valid = f2fs_usable_blks_in_seg(sbi, segno);
+
+ /* Prevent overflow/underflow before performing arithmetic. */
+ if (del > 0) {
+ if ((unsigned int)del > max_valid ||
+ se->valid_blocks > max_valid - (unsigned int)del) {
+ f2fs_bug_on(sbi, 1);
+ return;
+ }
+ } else if (del < 0) {
+ if (se->valid_blocks < (unsigned int)(-del)) {
+ f2fs_bug_on(sbi, 1);
+ return;
+ }
+ }
+
+ new_vblocks = (long int)se->valid_blocks + del;
offset = GET_BLKOFF_FROM_SEG0(sbi, blkaddr);
f2fs_bug_on(sbi, (new_vblocks < 0 ||
--
2.34.1
Download attachment "f2fs-fix-update_sit_entry-overflow-checks.patch" of type "application/octet-stream" (1477 bytes)
Powered by blists - more mailing lists