Re: [PATCH V7] squashfs: Add symlink size check in squash_read_inode

From: Al Viro
Date: Tue Aug 06 2024 - 00:59:44 EST


On Tue, Aug 06, 2024 at 10:56:09AM +0800, Lizhi Xu wrote:

> > Please, show me an unsigned int value N such that
> >
> > _Bool mismatch(unsigned int N)
> > {
> > u32 v32 = N;
> > loff_t v64 = N;
> >
> > return (v32 > PAGE_SIZE) != (v64 > PAGE_SIZE);
> > }
> This always return 0, why are you asking this?

Because that implies the equivalence between

symlink_size = le32_to_cpu(something);
if (symlink_size > PAGE_SIZE)
return -EINVAL;
inode->i_size = symlink_size;

and

inode->i_size = le32_to_cpu(something);
if (inode->i_size > PAGE_SIZE)
return -EINVAL;

However, you seem to find some problem in the latter form, and
your explanations of the reasons have been hard to understand.

> > Again, on all architectures inode->i_size is capable of representing
> > all values in range 0..4G-1 (for rather obvious reasons - we want the
> > kernel to be able to work with files larger than 4Gb). There is
> > no wraparound of any kind on that assignment.

> The type of loff_t is long long, so its values range is not 0..4G-1.

6.3.1.3[1] When a value with integer type is converted to another integer type
other than _Bool, if the value can be represented by the new type, it is unchanged.

Possible values of u32 are all in range 0..4G-1. All numbers in that range
(and many others as well, but that is irrelevant here) can be represented by
loff_t. In other words, nothing overflow-related is happening.