Re: [PATCH 2/2] ocfs2: fix readdir position truncation on 32-bit kernels

Joseph Qi <[email protected]>
Newsgroups dev.linux.lists.ocfs2-devel,org.kernel.vger.linux-ext4,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>

On 8/6/26 12:42 PM, Andrew Morton wrote:
> On Thu,  6 Aug 2026 10:20:44 +0800 Zhan Xusheng <[email protected]> wrote:
> 
>> 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 commit 3dce5bb82c97 ("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.
> 
> AI review had no comment on your change, but it might have found a
> bunch of unrelated ocfs2 issues:
> 
> 	https://sashiko.dev/#/patchset/[email protected]

It looks fine.
Reviewed-by: Joseph Qi <[email protected]>

For the issues founded by sashiko, I'd rather track them in a separate
thread.
So Xusheng, could you please send a new fix for that? It seems enough
to do the same check like ocfs2_check_dir_entry(). e.g.

i + OCFS2_DIR_REC_LEN(1) <= sb->s_blocksize

Thanks,
Joseph
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.