[PATCH] ext4fs: Fix: Read outside partition error (take 2)

Tony Dinh mibodhi at gmail.com
Wed May 28 21:48:39 CEST 2025


Use lbaint_t for blknr to avoid overflow in ext4fs_read_file().

Background:

blknr (block number) used in ext4fs_read_file() could be increased to a
very large value and causes a wrap around at 32 bit signed integer max,
thus becomes negative. This results in an out-of-normal range for sector
number (during the assignment delayed_start = blknr) where delayed_start
sector is typed uint64 lbaint_t. This causes the "Read outside partition"
error.

Looks like we also have this overflown problem in ext4_write.c that needs
to be addressed.

This patch was tested on the Synology DS116 (Armada 385) board, and a
4TB Seagate HDD.

Signed-off-by: Tony Dinh <mibodhi at gmail.com>
---

 fs/ext4/ext4fs.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c
index 1727da2dc6d..3d68d6c6394 100644
--- a/fs/ext4/ext4fs.c
+++ b/fs/ext4/ext4fs.c
@@ -101,17 +101,21 @@ int ext4fs_read_file(struct ext2fs_node *node, loff_t pos,
 	blockcnt = lldiv(((len + pos) + blocksize - 1), blocksize);
 
 	for (i = lldiv(pos, blocksize); i < blockcnt; i++) {
-		long int blknr;
+		lbaint_t blknr;
+		long blknr_and_status;
 		int blockoff = pos - (blocksize * i);
 		int blockend = blocksize;
 		int skipfirst = 0;
-		blknr = read_allocated_block(&node->inode, i, &cache);
-		if (blknr < 0) {
+		blknr_and_status = read_allocated_block(&node->inode, i, &cache);
+		if (blknr_and_status < 0) {
 			ext_cache_fini(&cache);
 			return -1;
 		}
 
-		blknr = blknr << log2_fs_blocksize;
+		/* Block number could becomes very large when CONFIG_SYS_64BIT_LBA is enabled
+		 * and wrap around at max long int
+		 */
+		blknr = (lbaint_t)blknr_and_status << log2_fs_blocksize;
 
 		/* Last block.  */
 		if (i == blockcnt - 1) {
-- 
2.39.5

base-commit: e04d137231f2e9e14708a32448c879125b8e308f
branch: master


More information about the U-Boot mailing list