All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kees Cook <keescook@chromium.org>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [PATCH v2][next] dlm: Replace one-element array with flexible-array member
Date: Sat, 8 Oct 2022 21:03:28 -0700	[thread overview]
Message-ID: <202210082044.51106145BD@keescook> (raw)
In-Reply-To: <Y0IsXXYnS4DnWkMW@mail.google.com>

On Sun, Oct 09, 2022 at 03:05:17PM +1300, Paulo Miguel Almeida wrote:
> On Sat, Oct 08, 2022 at 05:18:35PM -0700, Kees Cook wrote:
> > This is allocating 1 more byte than before, since the struct size didn't change. But this has always allocated too much space, due to the struct padding. For a "no binary changes" patch, the above "+ 1" needs to be left off.
> 
> That's true. I agree that leaving "+ 1" would work and produce a
> no-binary-changes patch due to the existing padding that the structure
> has. OTOH, I thought that relying on that space could bite us in the
> future if anyone tweaks the struct again...so my reaction was to ensure 
> that the NUL-terminator space was always guaranteed to be there.
> Hence, the change on c693 (objdump above).
> 
> What do you think? Should we keep or leave the above
> "+ 1" after the rationale above?

I think it depends on what's expected from this allocation. Christine or
David, can you speak to this?

> > I would expect the correct allocation size to be:
> > offsetof(typeof(*ls), ls_name) + namelen
> 
> Fair point, I will make this change.

Well, only do that if we don't depend on the padding nor a trailing
%NUL. :)

> > Question, though: is ls_name _expected_ to be %NUL terminated
> 
> Yes, it is. I tracked down ls_name's utilisations and it is passed down to 
> a bunch of routines that expects it to be NUL-terminated such as
> snprintf and vsnprintf.

Agreed: I see the string functions it gets passed to. So, then the next
question I have is does "namelen" take into account the %NUL, and is
"name" %NUL terminated? Those answers appear to be "no" and "yes",
respectively:

static int new_lockspace(const char *name, ...)
{
	...
        int namelen = strlen(name);


The comparisons for ls->ls_namelen are all done without the %NUL count:

                if (ls->ls_namelen != namelen)
                        continue;
                if (memcmp(ls->ls_name, name, namelen))
                        continue;

> >, and was the prior 3 bytes of extra allocation accidentally required?
> > 
> 
> I am assuming that you are refering to ls_namelen in the struct dlm_ls
> (please correct me if this isn't what you meant).

No, I meant ls_name (the pahole output shows the trailing 3 bytes of
padding before. And with your patch it becomes 4 bytes of trailing
padding.

So I think this is "accidentally correct", since it's so carefully using
memcmp() and not strcmp().

Given the existing padding on the structure, through, it likely needs
to keep a certain amount of minimum padding.

original size was actually this, so you could use this for the new
calculation to get the same values as before:

	offsetof(typeof(*ls), ls_name) + 4 + namelen;

In reality, it may be possible to do this to get exactly what is needed,
but no less than the struct itself:

	max(offsetof(typeof(*ls), ls_name) + 1 + namelen, sizeof(*ls));

-Kees

-- 
Kees Cook


WARNING: multiple messages have this Message-ID (diff)
From: Kees Cook <keescook@chromium.org>
To: Paulo Miguel Almeida <paulo.miguel.almeida.rodenas@gmail.com>
Cc: Christine Caulfield <ccaulfie@redhat.com>,
	David Teigland <teigland@redhat.com>,
	cluster-devel@redhat.com, linux-kernel@vger.kernel.org,
	linux-hardening@vger.kernel.org
Subject: Re: [PATCH v2][next] dlm: Replace one-element array with flexible-array member
Date: Sat, 8 Oct 2022 21:03:28 -0700	[thread overview]
Message-ID: <202210082044.51106145BD@keescook> (raw)
In-Reply-To: <Y0IsXXYnS4DnWkMW@mail.google.com>

On Sun, Oct 09, 2022 at 03:05:17PM +1300, Paulo Miguel Almeida wrote:
> On Sat, Oct 08, 2022 at 05:18:35PM -0700, Kees Cook wrote:
> > This is allocating 1 more byte than before, since the struct size didn't change. But this has always allocated too much space, due to the struct padding. For a "no binary changes" patch, the above "+ 1" needs to be left off.
> 
> That's true. I agree that leaving "+ 1" would work and produce a
> no-binary-changes patch due to the existing padding that the structure
> has. OTOH, I thought that relying on that space could bite us in the
> future if anyone tweaks the struct again...so my reaction was to ensure 
> that the NUL-terminator space was always guaranteed to be there.
> Hence, the change on c693 (objdump above).
> 
> What do you think? Should we keep or leave the above
> "+ 1" after the rationale above?

I think it depends on what's expected from this allocation. Christine or
David, can you speak to this?

> > I would expect the correct allocation size to be:
> > offsetof(typeof(*ls), ls_name) + namelen
> 
> Fair point, I will make this change.

Well, only do that if we don't depend on the padding nor a trailing
%NUL. :)

> > Question, though: is ls_name _expected_ to be %NUL terminated
> 
> Yes, it is. I tracked down ls_name's utilisations and it is passed down to 
> a bunch of routines that expects it to be NUL-terminated such as
> snprintf and vsnprintf.

Agreed: I see the string functions it gets passed to. So, then the next
question I have is does "namelen" take into account the %NUL, and is
"name" %NUL terminated? Those answers appear to be "no" and "yes",
respectively:

static int new_lockspace(const char *name, ...)
{
	...
        int namelen = strlen(name);


The comparisons for ls->ls_namelen are all done without the %NUL count:

                if (ls->ls_namelen != namelen)
                        continue;
                if (memcmp(ls->ls_name, name, namelen))
                        continue;

> >, and was the prior 3 bytes of extra allocation accidentally required?
> > 
> 
> I am assuming that you are refering to ls_namelen in the struct dlm_ls
> (please correct me if this isn't what you meant).

No, I meant ls_name (the pahole output shows the trailing 3 bytes of
padding before. And with your patch it becomes 4 bytes of trailing
padding.

So I think this is "accidentally correct", since it's so carefully using
memcmp() and not strcmp().

Given the existing padding on the structure, through, it likely needs
to keep a certain amount of minimum padding.

original size was actually this, so you could use this for the new
calculation to get the same values as before:

	offsetof(typeof(*ls), ls_name) + 4 + namelen;

In reality, it may be possible to do this to get exactly what is needed,
but no less than the struct itself:

	max(offsetof(typeof(*ls), ls_name) + 1 + namelen, sizeof(*ls));

-Kees

-- 
Kees Cook

  reply	other threads:[~2022-10-09  4:03 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-08 23:17 [Cluster-devel] [PATCH v2][next] dlm: Replace one-element array with flexible-array member Paulo Miguel Almeida
2022-10-08 23:17 ` Paulo Miguel Almeida
2022-10-09  0:18 ` [Cluster-devel] " Kees Cook
2022-10-09  0:18   ` Kees Cook
2022-10-09  2:05   ` [Cluster-devel] " Paulo Miguel Almeida
2022-10-09  2:05     ` Paulo Miguel Almeida
2022-10-09  4:03     ` Kees Cook [this message]
2022-10-09  4:03       ` Kees Cook
2022-10-10 21:00       ` [Cluster-devel] " David Teigland
2022-10-10 21:00         ` David Teigland
2022-10-10 22:35         ` [Cluster-devel] " Kees Cook
2022-10-10 22:35           ` Kees Cook
2022-10-11 15:20           ` [Cluster-devel] " David Teigland
2022-10-11 15:20             ` David Teigland
2022-10-11 18:44             ` [Cluster-devel] " Paulo Miguel Almeida
2022-10-11 18:44               ` Paulo Miguel Almeida
2022-10-11 20:04               ` [Cluster-devel] [PATCH v4] [next] dlm: replace one-element array with fixed size array Paulo Miguel Almeida
2022-10-11 20:04                 ` Paulo Miguel Almeida
2022-10-11 20:06                 ` [Cluster-devel] " Kees Cook
2022-10-11 20:06                   ` Kees Cook
2022-10-11 20:11                   ` [Cluster-devel] " Paulo Miguel Almeida
2022-10-11 20:11                     ` Paulo Miguel Almeida
2022-10-11 20:23                   ` [Cluster-devel] [PATCH v5] " Paulo Miguel Almeida
2022-10-11 20:23                     ` Paulo Miguel Almeida
2022-10-11 20:26                     ` [Cluster-devel] " Gustavo A. R. Silva
2022-10-11 20:26                       ` Gustavo A. R. Silva
2022-10-11 22:18                     ` [Cluster-devel] " Kees Cook
2022-10-11 22:18                       ` Kees Cook
2022-11-04  5:00                     ` [Cluster-devel] " Paulo Miguel Almeida
2022-11-04  5:00                       ` Paulo Miguel Almeida
2022-11-04 17:50                       ` [Cluster-devel] " Alexander Aring
2022-11-04 17:50                         ` Alexander Aring

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=202210082044.51106145BD@keescook \
    --to=keescook@chromium.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.