On 22.10.20 21:24, Al Viro wrote:
> On Thu, Oct 22, 2020 at 12:04:52PM -0700, Nick Desaulniers wrote:
> 
>> Passing an `unsigned long` as an `unsigned int` does no such
>> narrowing: https://godbolt.org/z/TvfMxe (same vice-versa, just tail
>> calls, no masking instructions).
>> So if rw_copy_check_uvector() is inlined into import_iovec() (looking
>> at the mainline@1028ae406999), then children calls of
>> `rw_copy_check_uvector()` will be interpreting the `nr_segs` register
>> unmodified, ie. garbage in the upper 32b.
> 
> FWIW,
> 
> void f(unsinged long v)
> {
>       if (v != 1)
>               printf("failed\n");
> }
> 
> void g(unsigned int v)
> {
>       f(v);
> }
> 
> void h(unsigned long v)
> {
>       g(v);
> }
> 
> main()
> {
>       h(0x100000001);
> }
> 
> must not produce any output on a host with 32bit int and 64bit long, 
> regardless of
> the inlining, having functions live in different compilation units, etc.
> 
> Depending upon the calling conventions, compiler might do truncation in 
> caller or
> in a callee, but it must be done _somewhere_.

The interesting case is having g() in a separate compilation unit and
force-calling g() with 0x100000001 via inline ASM. So forcing garbage
into high bits.

I'll paly with it.

-- 
Thanks,

David / dhildenb

Reply via email to