All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paulo Miguel Almeida <paulo.miguel.almeida.rodenas@gmail.com>
To: Kees Cook <keescook@chromium.org>
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>,
	"Andy Shevchenko" <andy.shevchenko@gmail.com>,
	linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org
Subject: Re: [PATCH] [next] pcmcia: synclink_cs: replace 1-element array with flex-array member
Date: Thu, 15 Dec 2022 09:09:46 +1300	[thread overview]
Message-ID: <Y5otilaHc6HBPCAF@mail.google.com> (raw)
In-Reply-To: <202212141124.736E3DE2A8@keescook>

On Wed, Dec 14, 2022 at 11:29:37AM -0800, Kees Cook wrote:
> On Wed, Dec 14, 2022 at 09:42:00PM +1300, Paulo Miguel Almeida 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.
> > 
> > It's worth mentioning that doing a build before/after this patch
> > results in no binary output differences.
> > 
> > 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].
> > 
> > Link: https://github.com/KSPP/linux/issues/79
> > Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101836 [1]
> > 
> > Signed-off-by: Paulo Miguel Almeida <paulo.miguel.almeida.rodenas@gmail.com>
> > ---
> >  drivers/char/pcmcia/synclink_cs.c | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
> > index b2735be81ab2..1ab2d552f498 100644
> > --- a/drivers/char/pcmcia/synclink_cs.c
> > +++ b/drivers/char/pcmcia/synclink_cs.c
> > @@ -105,7 +105,7 @@ static MGSL_PARAMS default_params = {
> >  typedef struct {
> >  	int count;
> >  	unsigned char status;
> > -	char data[1];
> > +	char data[];
> >  } RXBUF;
> >  
> >  /* The queue of BH actions to be performed */
> > @@ -2611,7 +2611,8 @@ static int mgslpc_proc_show(struct seq_file *m, void *v)
> >  static int rx_alloc_buffers(MGSLPC_INFO *info)
> >  {
> >  	/* each buffer has header and data */
> > -	info->rx_buf_size = sizeof(RXBUF) + info->max_frame_size;
> > +	info->rx_buf_size = max(offsetof(typeof(RXBUF), data) + 1, sizeof(RXBUF))
> > +		+ info->max_frame_size;
> 
> It seems like there is an existing size bug here, and likely should be
> fixed separately?
> 
> i.e. this was already allocating 1 byte "too much". I'd expect this
> first:
> 
> -	info->rx_buf_size = sizeof(RXBUF) + info->max_frame_size;
> +	info->rx_buf_size = sizeof(RXBUF) - 1 + info->max_frame_size;
> 
> and then the next patch:
> 
> -	char data[1];
> +	char data[];
> ...
> -	info->rx_buf_size = sizeof(RXBUF) - 1 + info->max_frame_size;
> +	info->rx_buf_size = sizeof(RXBUF) + info->max_frame_size;
> 
> The above would induce a binary output change, and the second would not.
> 
> Though this results in what you had for the v2 patch (but I can't
> believe it had no binary changes...)
> 
> -- 
> Kees Cook

Hi Kees, Hi Andy, Thanks for taking the time to review this patch.

As both of you had similar points, I will reply them here.

The reasons why it had no binary changes was because of the combination
of this 2 things:

1) Existing padding - so sizeof(RXBUF) returned 8 bytes in both cases.

pahole -C RXBUF gcc/before/drivers/char/pcmcia/synclink_cs.ko
typedef struct {
	int                        count;                /*     0     4 */
	unsigned char              status;               /*     4     1 */
	char                       data[1];              /*     5     1 */

	/* size: 8, cachelines: 1, members: 3 */
	/* padding: 2 */
	/* last cacheline: 8 bytes */
} RXBUF;

pahole -C RXBUF gcc/after/drivers/char/pcmcia/synclink_cs.ko
typedef struct {
	int                        count;                /*     0     4 */
	unsigned char              status;               /*     4     1 */
	char                       data[];               /*     5     0 */

	/* size: 8, cachelines: 1, members: 3 */
	/* padding: 3 */
	/* last cacheline: 8 bytes */
} RXBUF;

2) RXBUF (as implemented now) is just  like a pair of lenses from which a
developer can have access to one of the circular buffers in MGSLPC_INFO
struct called 'rx_buf'. 

2611 static int rx_alloc_buffers(MGSLPC_INFO *info)
2612 {
2613         /* each buffer has header and data */
2614         info->rx_buf_size = sizeof(RXBUF) + info->max_frame_size;
2615
2616         /* calculate total allocation size for 8 buffers */
2617         info->rx_buf_total_size = info->rx_buf_size * 8;
2618
2619         /* limit total allocated memory */
2620         if (info->rx_buf_total_size > 0x10000)
2621                 info->rx_buf_total_size = 0x10000;
2622
2623         /* calculate number of buffers */
2624         info->rx_buf_count = info->rx_buf_total_size / info->rx_buf_size;
2625
2626         info->rx_buf = kmalloc(info->rx_buf_total_size, GFP_KERNEL);

To be honest, char data[_1_] in RXBUF was never required to be there.
The code base seems to make sure that it doesn't run past its limits by
keeping track of size buffer on MGSLPC_INFO->rx_buf_size (and sometimes
RXBUF->count)

(Addressing one point made by Andy about using of of the macros in
overflow.h)
	struct_size(buf, data, 1) would return 9 bytes which could
	potentially break the existing driver as it produces binary
	changes.

Let me know your thoughts

thanks!

- Paulo A.

  reply	other threads:[~2022-12-14 20:22 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 [this message]
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
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=Y5otilaHc6HBPCAF@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=keescook@chromium.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.