public inbox for linux-hardening@vger.kernel.org
 help / color / mirror / Atom feed
* Re: rcar-dmac.c: race condition regarding cookie handling?
       [not found] ` <CAMuHMdW=igXesjxvNk=+in62neW=kipnFW2BUH3P7sfDnqXzEQ@mail.gmail.com>
@ 2024-01-29 17:38   ` Kees Cook
  2024-01-29 19:08     ` Geert Uytterhoeven
  0 siblings, 1 reply; 3+ messages in thread
From: Kees Cook @ 2024-01-29 17:38 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Behme Dirk (CM/ESO2), Linux-Renesas, Yoshihiro Shimoda,
	linux-hardening

On Mon, Jan 29, 2024 at 10:57:40AM +0100, Geert Uytterhoeven wrote:
> Hi Dirk,
> 
> CC Kees (for the wrap-around in dma_cookie_assign() not handled in [A])
> [...]
> Was the system running for a very long time?
> dma_cookie_assign() relies on 2-complement signed wrap-around:
> 
>         cookie = chan->cookie + 1;
>         if (cookie < DMA_MIN_COOKIE)
>                 cookie = DMA_MIN_COOKIE;
> 
> but given the kernel is compiled with -fno-strict-overflow (which
> implies -fwrapv) that should work.

For my own reference:

typedef s32 dma_cookie_t;
#define DMA_MIN_COOKIE  1

struct dma_chan {
	...
        dma_cookie_t cookie;

Correct, as you say, with -fno-strict-overflow this is well defined, and
will wrap the value around negative if chan->cookie was S32_MAX.

In the future, when the signed integer wrap-around sanitizer works
again, we'll want to change the math to something like:

	cookie = add_wrap(typeof(cookie), chan->cookie, 1);

But that will be an ongoing conversion once folks have agreed on the
semantics of the wrapping helpers, which is not settled yet.

If you want to handle this today without depending on wrap-around,
it's a little bit more involved to do it open coded, but it's possible:

	if (chan->cookie == type_max(typeof(chan->cookie)))
		cookie = DMA_MIN_COOKIE;
	else
		cookie = chan->cookie + 1;

the "type_max(...)" part could also just be written as S32_MAX.

-Kees

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: rcar-dmac.c: race condition regarding cookie handling?
  2024-01-29 17:38   ` rcar-dmac.c: race condition regarding cookie handling? Kees Cook
@ 2024-01-29 19:08     ` Geert Uytterhoeven
  2024-01-29 19:28       ` Kees Cook
  0 siblings, 1 reply; 3+ messages in thread
From: Geert Uytterhoeven @ 2024-01-29 19:08 UTC (permalink / raw)
  To: Kees Cook
  Cc: Behme Dirk (CM/ESO2), Linux-Renesas, Yoshihiro Shimoda,
	linux-hardening

Hi Kees,

On Mon, Jan 29, 2024 at 6:38 PM Kees Cook <keescook@chromium.org> wrote>
> On Mon, Jan 29, 2024 at 10:57:40AM +0100, Geert Uytterhoeven wrote:
> > CC Kees (for the wrap-around in dma_cookie_assign() not handled in [A])
> > [...]
> > Was the system running for a very long time?
> > dma_cookie_assign() relies on 2-complement signed wrap-around:
> >
> >         cookie = chan->cookie + 1;
> >         if (cookie < DMA_MIN_COOKIE)
> >                 cookie = DMA_MIN_COOKIE;
> >
> > but given the kernel is compiled with -fno-strict-overflow (which
> > implies -fwrapv) that should work.
>
> For my own reference:
>
> typedef s32 dma_cookie_t;
> #define DMA_MIN_COOKIE  1
>
> struct dma_chan {
>         ...
>         dma_cookie_t cookie;
>
> Correct, as you say, with -fno-strict-overflow this is well defined, and
> will wrap the value around negative if chan->cookie was S32_MAX.
>
> In the future, when the signed integer wrap-around sanitizer works
> again, we'll want to change the math to something like:
>
>         cookie = add_wrap(typeof(cookie), chan->cookie, 1);
>
> But that will be an ongoing conversion once folks have agreed on the
> semantics of the wrapping helpers, which is not settled yet.
>
> If you want to handle this today without depending on wrap-around,
> it's a little bit more involved to do it open coded, but it's possible:
>
>         if (chan->cookie == type_max(typeof(chan->cookie)))
>                 cookie = DMA_MIN_COOKIE;
>         else
>                 cookie = chan->cookie + 1;
>
> the "type_max(...)" part could also just be written as S32_MAX.

It's actually more complicated: this code is also used to make sure
any other values outside the valid range (e.g. initial zero are
converted to DMA_MIN_COOKIE.  So the above would not be correct
replacements for the current logic.

DMA cookies can also contain negative error values, hence the signed
type. However, I don't think that can be the case for the chan->cookie
counter, only for cookies stored in descriptors.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

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

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: rcar-dmac.c: race condition regarding cookie handling?
  2024-01-29 19:08     ` Geert Uytterhoeven
@ 2024-01-29 19:28       ` Kees Cook
  0 siblings, 0 replies; 3+ messages in thread
From: Kees Cook @ 2024-01-29 19:28 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Behme Dirk (CM/ESO2), Linux-Renesas, Yoshihiro Shimoda,
	linux-hardening

On Mon, Jan 29, 2024 at 08:08:28PM +0100, Geert Uytterhoeven wrote:
> Hi Kees,
> 
> On Mon, Jan 29, 2024 at 6:38 PM Kees Cook <keescook@chromium.org> wrote>
> > On Mon, Jan 29, 2024 at 10:57:40AM +0100, Geert Uytterhoeven wrote:
> > > CC Kees (for the wrap-around in dma_cookie_assign() not handled in [A])
> > > [...]
> > > Was the system running for a very long time?
> > > dma_cookie_assign() relies on 2-complement signed wrap-around:
> > >
> > >         cookie = chan->cookie + 1;
> > >         if (cookie < DMA_MIN_COOKIE)
> > >                 cookie = DMA_MIN_COOKIE;
> > >
> > > but given the kernel is compiled with -fno-strict-overflow (which
> > > implies -fwrapv) that should work.
> >
> > For my own reference:
> >
> > typedef s32 dma_cookie_t;
> > #define DMA_MIN_COOKIE  1
> >
> > struct dma_chan {
> >         ...
> >         dma_cookie_t cookie;
> >
> > Correct, as you say, with -fno-strict-overflow this is well defined, and
> > will wrap the value around negative if chan->cookie was S32_MAX.
> >
> > In the future, when the signed integer wrap-around sanitizer works
> > again, we'll want to change the math to something like:
> >
> >         cookie = add_wrap(typeof(cookie), chan->cookie, 1);
> >
> > But that will be an ongoing conversion once folks have agreed on the
> > semantics of the wrapping helpers, which is not settled yet.
> >
> > If you want to handle this today without depending on wrap-around,
> > it's a little bit more involved to do it open coded, but it's possible:
> >
> >         if (chan->cookie == type_max(typeof(chan->cookie)))
> >                 cookie = DMA_MIN_COOKIE;
> >         else
> >                 cookie = chan->cookie + 1;
> >
> > the "type_max(...)" part could also just be written as S32_MAX.
> 
> It's actually more complicated: this code is also used to make sure
> any other values outside the valid range (e.g. initial zero are
> converted to DMA_MIN_COOKIE.  So the above would not be correct
> replacements for the current logic.
> 
> DMA cookies can also contain negative error values, hence the signed
> type. However, I don't think that can be the case for the chan->cookie
> counter, only for cookies stored in descriptors.

Ah! Okay, well, if it was true here too, then the "if" would just need
to be expanded:

         if (chan->cookie < DMA_MIN_COOKIE ||
	     chan->cookie == type_max(typeof(chan->cookie)))
                 cookie = DMA_MIN_COOKIE;
         else
                 cookie = chan->cookie + 1;

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-01-29 19:28 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <12ff20eb-d4b5-41f4-a494-cfb6b7abe617@de.bosch.com>
     [not found] ` <CAMuHMdW=igXesjxvNk=+in62neW=kipnFW2BUH3P7sfDnqXzEQ@mail.gmail.com>
2024-01-29 17:38   ` rcar-dmac.c: race condition regarding cookie handling? Kees Cook
2024-01-29 19:08     ` Geert Uytterhoeven
2024-01-29 19:28       ` Kees Cook

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox