linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: yao xiao <xiangyaof4free@gmail.com>
To: jaegeuk@kernel.org, chao@kernel.org
Cc: linux-f2fs-devel@lists.sourceforge.net,
	linux-fsdevel@vger.kernel.org,  linux-kernel@vger.kernel.org
Subject: [PATCH v2] f2fs: add overflow/underflow checks to update_sit_entry
Date: Mon, 1 Dec 2025 17:17:20 +0800	[thread overview]
Message-ID: <CACpam_ZrXZwb-=EKc8HTyH7VPSWhuWBUgO0n6_z3H6wv8k6r3w@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 2397 bytes --]

From: Yao Xiao <xiangyaof4free@gmail.com>
To: Jaegeuk Kim <jaegeuk@kernel.org>, Chao Yu <chao@kernel.org>
Cc: linux-f2fs-devel@lists.sourceforge.net,
    linux-fsdevel@vger.kernel.org,
    linux-kernel@vger.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@gmail.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

[-- Attachment #2: f2fs-fix-update_sit_entry-overflow-checks.patch --]
[-- Type: application/octet-stream, Size: 1477 bytes --]

From 4acb10c7517b0a2bd9fd6f1ab3337cfc1b90f99b Mon Sep 17 00:00:00 2001
From: Yao Xiao <xiangyaof4free@gmail.com>
Date: Wed, 4 Dec 2024 12:00:00 +0800
Subject: [PATCH v2] f2fs: add overflow/underflow checks to update_sit_entry

Signed-off-by: Yao Xiao <xiangyaof4free@gmail.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

                 reply	other threads:[~2025-12-01  9:17 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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='CACpam_ZrXZwb-=EKc8HTyH7VPSWhuWBUgO0n6_z3H6wv8k6r3w@mail.gmail.com' \
    --to=xiangyaof4free@gmail.com \
    --cc=chao@kernel.org \
    --cc=jaegeuk@kernel.org \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@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;
as well as URLs for NNTP newsgroup(s).