Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fs/jfs: cast inactags to s64 to prevent potential overflow

The expression "inactags << bmp->db_agl2size" in the function
dbFinalizeBmap() is computed using int operands. Although the
values (inactags and db_agl2size) are derived from filesystem
parameters and are usually small, there is a theoretical risk that
the shift could overflow a 32-bit int if extreme values occur.

According to the C standard, shifting a signed 32-bit int can lead
to undefined behavior if the result exceeds its range. In our
case, an overflow could miscalculate free blocks, potentially
leading to erroneous filesystem accounting.

To ensure the arithmetic is performed in 64-bit space, we cast
"inactags" to s64 before shifting. This defensive fix prevents any
risk of overflow and complies with kernel coding best practices.

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

Signed-off-by: Rand Deeb <rand.sec96@gmail.com>
Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>

authored by

Rand Deeb and committed by
Dave Kleikamp
70ca3246 9629d7d6

+2 -2
+2 -2
fs/jfs/jfs_dmap.c
··· 3666 3666 * system size is not a multiple of the group size). 3667 3667 */ 3668 3668 inactfree = (inactags && ag_rem) ? 3669 - ((inactags - 1) << bmp->db_agl2size) + ag_rem 3670 - : inactags << bmp->db_agl2size; 3669 + (((s64)inactags - 1) << bmp->db_agl2size) + ag_rem 3670 + : ((s64)inactags << bmp->db_agl2size); 3671 3671 3672 3672 /* determine how many free blocks are in the active 3673 3673 * allocation groups plus the average number of free blocks