mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
ocfs2: fix readdir position truncation on 32-bit kernels
In ocfs2_dir_foreach_blk_el(), the directory cookie position is rebuilt with ctx->pos = (ctx->pos & ~(sb->s_blocksize - 1)) | offset; `ctx->pos` is loff_t (signed 64-bit), while `sb->s_blocksize` is unsigned long. On 32-bit kernels unsigned long is 32-bit, so the mask ~(sb->s_blocksize - 1) is computed as a 32-bit unsigned value (e.g. 0xfffff000 for a 4 KiB block size). In the AND expression with the 64-bit `ctx->pos`, that unsigned operand is zero-extended to 64 bits per the usual arithmetic conversions, yielding 0x00000000fffff000. The high 32 bits of `ctx->pos` are silently cleared, even though directory size is allowed to exceed 4 GiB. When readdir() crosses the 4 GiB boundary on a 32-bit kernel the position is reset back into the first 4 GiB block, making the re-validation path re-enumerate already-returned dirents indefinitely. This is ocfs2_dir_foreach_blk_el(), the extent-list readdir path taken for all non-inline directories, so a directory large enough to cross 4 GiB reaches it. This is the same class of bug that commit3dce5bb82c("exfat: Fix bitwise operation having different size") fixed in exfat, and the fix mirrors the equivalent ext4 fix in this series. Cast the operand to loff_t so the mask is 64-bit before the AND: ctx->pos = (ctx->pos & ~((loff_t)sb->s_blocksize - 1)) | offset; 64-bit kernels are unaffected. Link: https://lore.kernel.org/20260806022044.167962-3-zhanxusheng@xiaomi.com Fixes:ccd979bdbc("[PATCH] OCFS2: The Second Oracle Cluster Filesystem") Signed-off-by: Zhan Xusheng <zhanxusheng@xiaomi.com> Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com> Cc: Mark Fasheh <mark@fasheh.com> Cc: Joel Becker <jlbec@evilplan.org> Cc: Junxiao Bi <junxiao.bi@oracle.com> Cc: Changwei Ge <gechangwei@live.cn> Cc: Jun Piao <piaojun@huawei.com> Cc: Heming Zhao <heming.zhao@suse.com> Cc: Andreas Dilger <adilger.kernel@dilger.ca> Cc: Jan Kara <jack@suse.cz> Cc: Ojaswin Mujoo <ojaswin@linux.ibm.com> Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com> Cc: Ted Ts'o <tytso@mit.edu> Cc: "zhangyi (F)" <yi.zhang@huawei.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
621c2bcb87
commit
a63308ab42
|
|
@ -1959,7 +1959,7 @@ static int ocfs2_dir_foreach_blk_el(struct inode *inode,
|
|||
i += le16_to_cpu(de->rec_len);
|
||||
}
|
||||
offset = i;
|
||||
ctx->pos = (ctx->pos & ~(sb->s_blocksize - 1))
|
||||
ctx->pos = (ctx->pos & ~((loff_t)sb->s_blocksize - 1))
|
||||
| offset;
|
||||
*f_version = inode_query_iversion(inode);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user