Re: [GIT PULL] SPI fixes for v5.17-rc7

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Linus,

On Tue, Mar 15, 2022 at 5:48 PM Linus Torvalds
<torvalds@xxxxxxxxxxxxxxxxxxxx> wrote:
> On Tue, Mar 15, 2022 at 2:08 AM Geert Uytterhoeven <geert@xxxxxxxxxxxxxx> wrote:
> > I had noticed while reviewing the patch, but changing to size_t wouldn't
> > help much, as other related code paths treat the value as unsigned int
> > anyway.
>
> .. but it really would.
>
> Note that the paths *after* this code don't matter. Because the result
> is guaranteed to fit in 'unsigned int' anyway.
>
> Put another way:
>
>     min_t(unsigned int,x,y)
>
> is buggy if one of x/y is 'size_t'. Why? Because if that one gets
> truncated, you're doing 'min()' with a value that may be artificially
> much too small (that was exactly the problem commit 1a4e53d2fc4f:
> "spi: Fix invalid sgs value")fixed).
>
> But the situation is _not_ true in the reverse. Look:
>
>     min(size_t,x,y)
>
> is guaranteed to fit in 'unsigned int' as long as _one_ of x,y fits in
> 'unsigned int' - even if the other doesn't. Because then 'min()' will
> just pick the one that already had the right size.
>
> To make it really concrete, compare
>
>     min_t(unsigned int, 5, 0x100000001);
>     min_t(size_t, 5, 0x100000001);
>
> on a 64-bit machine (ie size_t is 64-bits, and unsigned int is 32-bit).
>
> One returns 1. The other returns 5. Both fit the result in 'unsigned
> int', but one of them is wrong.

You're absolutely right. So the code should be changed to:

        if (vmalloced_buf || kmap_buf) {
-                desc_len = min_t(unsigned int, max_seg_size, PAGE_SIZE);
+               desc_len = min_t(unsigned long, max_seg_size, PAGE_SIZE);
                sgs = DIV_ROUND_UP(len + offset_in_page(buf), desc_len);
        } else if (virt_addr_valid(buf)) {
-               desc_len = min_t(unsigned int, max_seg_size, ctlr->max_dma_len);
+               desc_len = min_t(size_t, max_seg_size, ctlr->max_dma_len);
                sgs = DIV_ROUND_UP(len, desc_len);
        } else {
                return -EINVAL;
        }

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@xxxxxxxxxxxxxx

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds



[Index of Archives]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux