All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paulo Miguel Almeida <paulo.miguel.almeida.rodenas@gmail.com>
To: Andy Shevchenko <andy.shevchenko@gmail.com>
Cc: "Arnd Bergmann" <arnd@arndb.de>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
	"Jiri Slaby" <jirislaby@kernel.org>,
	"Haowen Bai" <baihaowen@meizu.com>,
	linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org,
	paulo.miguel.almeida.rodenas@gmail.com
Subject: Re: [PATCH v3] [next] pcmcia: synclink_cs: replace 1-element array with flex-array member
Date: Sun, 18 Dec 2022 09:05:51 +1300	[thread overview]
Message-ID: <Y54hHyoUW/tGioLx@mail.google.com> (raw)
In-Reply-To: <CAHp75VeNcPjngJcF96Y9hV=Y+NeaGadSMGMvgCTD6kdBi=+9fg@mail.gmail.com>

On Sat, Dec 17, 2022 at 01:43:40PM +0200, Andy Shevchenko wrote:
> On Sat, Dec 17, 2022 at 12:59 AM Paulo Miguel Almeida
> <paulo.miguel.almeida.rodenas@gmail.com> wrote:
> >
> > One-element arrays are deprecated, and we are replacing them with
> > flexible array members instead. So, replace one-element array with
> > flexible-array member in struct RXBUF and refactor the rest of the code
> > accordingly. While at it, fix an edge case which could cause
> > rx_buf_count to be 0 when max_frame_size was set to the maximum
> > allowed value (65535).
> >
> > It's worth mentioning that struct RXBUF was allocating 1 byte "too much"
> > for what is required (ignoring bytes added by padding).
> >
> > This helps with the ongoing efforts to tighten the FORTIFY_SOURCE
> > routines on memcpy() and help us make progress towards globally
> > enabling -fstrict-flex-arrays=3 [1].
> 
> ...
> 
> >  static int rx_alloc_buffers(MGSLPC_INFO *info)
> >  {
> >         /* each buffer has header and data */
> > -       info->rx_buf_size = sizeof(RXBUF) + info->max_frame_size;
> > +       if (check_add_overflow(sizeof(RXBUF), info->max_frame_size, &info->rx_buf_size))
> > +               return -EINVAL;
> >
> > -       /* calculate total allocation size for 8 buffers */
> > -       info->rx_buf_total_size = info->rx_buf_size * 8;
> 
> > +       /* try to alloc as many buffers that can fit within RXBUF_MAX_SIZE (up to 8) */
> > +       if (check_mul_overflow(info->rx_buf_size, 8, &info->rx_buf_total_size))
> > +               return -EINVAL;
> 
> This check is implied by kcalloc(). But to make it effective we
> probably need to get a count first.
> 
> > -       /* limit total allocated memory */
> > -       if (info->rx_buf_total_size > 0x10000)
> > -               info->rx_buf_total_size = 0x10000;
> > +       if (info->rx_buf_total_size > RXBUF_MAX_SIZE)
> > +               info->rx_buf_total_size = RXBUF_MAX_SIZE;
> 
> If max_frame_size > 8192 - sizeof(RXBUF), we bump into this condition...
> 
> >         /* calculate number of buffers */
> >         info->rx_buf_count = info->rx_buf_total_size / info->rx_buf_size;
> 
> ...which means that rx_buf_count < 8...

that's correct. My reading of what the original author intended is the
following:

- rx_buf_count can be < 8 if max_frame_size needs to be > 8192 so that
  userspace tools don't need to collate the different packets together
  then again, SyncLink_CS supports a variety of protocols.

- the more circular buffers, the better, but it looks perfectly acceptable
  to have 1 big rx_buf (max_frame_size possible) if the communication is
  orchestrated nicely (which part sends what and when) especially for
  RS-232-based communications.


> (and if max_frame_size > RXBUF_MAX_SIZE - sizeof(RXBUF), count becomes
> 0, I don't know if below clamp_val() is the only place to guarantee
> that)
> 

I can confirm that the clamp_val() below is the only place that
guarantees the max_frame_size isn't greater than RXBUF_MAX_SIZE. That
happens at the device probing stage: 

( mgslpc_probe > mgslpc_add_device > clamp_val-like routine )

As max_frame_size can only be set as a module parameter and no other way
is exposed to userspace to tweak that afterwards, my 2 cents is that 
clamp_val() routine should be fine as rx_buf_count will always be > 0 
after this fix.

> > -       info->rx_buf = kmalloc(info->rx_buf_total_size, GFP_KERNEL);
> > +       info->rx_buf = kcalloc(info->rx_buf_count, info->rx_buf_size, GFP_KERNEL);
> 
> ...hence rx_buf size will be less than rx_buf_total_size.
> 
> That is probably not an issue per se, but I'm wondering if the
> (bigger) value of rx_buf_total_size is the problem further in the
> code.
> 

rx_buf_total_size isn't used outside of this function so it
could be a local variable IMO.. so I would say that this wouldn't be a
problem.

I had noticed that rx_buf_total_size could be moved into a local
variable before but I thought that removing it from MGSLPC struct
should be part of a separate patch instead.

> >         if (info->rx_buf == NULL)
> >                 return -ENOMEM;
> 
> Maybe something like
> 
> static int rx_alloc_buffers(MGSLPC_INFO *info)
> {
>     /* Prevent count from being 0 */
>     if (->max_frame_size > MAX_FRAME_SIZE)
>         return -EINVAL;

This boils down to whether having the clamp_val() on the probe method is
sufficient in your point of view. You make the final call on this :-)

>     ...
>    count = ...;
>    ...
>    rx_total_size = ...
>    rx_buf = kcalloc(...);
> 
> Then you don't need to check overflow with check_add_overflow() and
> check_mul_overflow() will be inside the kcalloc.
> 

check_mul_overflow point -> agreed.

check_add_overflow -> similar suggestion as my previous point, if the
clamp_val on probe is sufficient for you, I would say that we don't need
it as of now too. But if you still think that we need it, I'm flexible
with that too.

> ...
> 
> > -       if (info->max_frame_size < 4096)
> > -               info->max_frame_size = 4096;
> > -       else if (info->max_frame_size > 65535)
> > -               info->max_frame_size = 65535;
> > +       if (info->max_frame_size < MGSLPC_MIN_FRAME_SIZE)
> > +               info->max_frame_size = MGSLPC_MIN_FRAME_SIZE;
> > +       else if (info->max_frame_size > MGSLPC_MAX_FRAME_SIZE)
> > +               info->max_frame_size = MGSLPC_MAX_FRAME_SIZE;
> 
> You can use clamp_val() macro here.
> 

Nice, I didn't know about this macro. I will make that change for v4.

All really nice points you've made Andy, I'm learning heaps of new
things with this patch :-)

thanks!

- Paulo A.


  reply	other threads:[~2022-12-17 20:06 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-14  8:42 [PATCH] [next] pcmcia: synclink_cs: replace 1-element array with flex-array member Paulo Miguel Almeida
2022-12-14  8:58 ` [PATCH v2] " Paulo Miguel Almeida
2022-12-14 10:43   ` Andy Shevchenko
2022-12-14 20:19     ` Paulo Miguel Almeida
2022-12-14 19:29 ` [PATCH] " Kees Cook
2022-12-14 20:09   ` Paulo Miguel Almeida
2022-12-14 20:26     ` Kees Cook
2022-12-14 20:39     ` Andy Shevchenko
2022-12-14 21:49       ` Kees Cook
2022-12-14 22:06         ` Andy Shevchenko
2022-12-15  4:29           ` Paulo Miguel Almeida
2022-12-15  6:35             ` Paulo Miguel Almeida
2022-12-15  8:57             ` Andy Shevchenko
2022-12-15 21:13               ` Paulo Miguel Almeida
2022-12-16 22:59                 ` [PATCH v3] " Paulo Miguel Almeida
2022-12-16 23:42                   ` Kees Cook
2022-12-17  0:11                     ` Paulo Miguel Almeida
2022-12-17 11:43                   ` Andy Shevchenko
2022-12-17 20:05                     ` Paulo Miguel Almeida [this message]
2022-12-14 20:14   ` [PATCH] " Paulo Miguel Almeida

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Y54hHyoUW/tGioLx@mail.google.com \
    --to=paulo.miguel.almeida.rodenas@gmail.com \
    --cc=andy.shevchenko@gmail.com \
    --cc=arnd@arndb.de \
    --cc=baihaowen@meizu.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=jirislaby@kernel.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.