From: "Gustavo A. R. Silva" <gustavoars@kernel.org>
To: Kees Cook <keescook@chromium.org>
Cc: Dave Hansen <dave.hansen@linux.intel.com>,
Andy Lutomirski <luto@kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
"H. Peter Anvin" <hpa@zytor.com>,
x86@kernel.org, linux-kernel@vger.kernel.org,
linux-hardening@vger.kernel.org
Subject: Re: [PATCH v2][next] x86/mm/pgtable: Fix -Wstringop-overflow warnings
Date: Tue, 10 May 2022 09:54:15 -0500 [thread overview]
Message-ID: <20220510145415.GA8111@embeddedor> (raw)
In-Reply-To: <20220510141202.GA6878@embeddedor>
On Tue, May 10, 2022 at 09:12:02AM -0500, Gustavo A. R. Silva wrote:
> > > > > --- a/arch/x86/mm/pgtable.c
> > > > > +++ b/arch/x86/mm/pgtable.c
> > > > > @@ -434,14 +434,18 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
> > > > >
> > > > > mm->pgd = pgd;
> > > > >
> > > > > - if (preallocate_pmds(mm, pmds, PREALLOCATED_PMDS) != 0)
> > > > > - goto out_free_pgd;
> > > > > + if (MAX_PREALLOCATED_PMDS != 0 && MAX_PREALLOCATED_USER_PMDS != 0) {
> > > > > + if (preallocate_pmds(mm, pmds, PREALLOCATED_PMDS) != 0)
> > > > > + goto out_free_pgd;
> > > > >
> > > > > - if (preallocate_pmds(mm, u_pmds, PREALLOCATED_USER_PMDS) != 0)
> > > > > - goto out_free_pmds;
> > > > > + if (preallocate_pmds(mm, u_pmds, PREALLOCATED_USER_PMDS) != 0)
> > > > > + goto out_free_pmds;
> > > > >
> > > > > - if (paravirt_pgd_alloc(mm) != 0)
> > > > > - goto out_free_user_pmds;
> > > > > + if (paravirt_pgd_alloc(mm) != 0)
> > > > > + goto out_free_user_pmds;
> > > > > + } else {
> > > > > + goto out_free_pgd;
> > > >
> > > > The "all 0" case shouldn't be a failure mode; it should just skip the
> > > > preallocate_pmds() calls.
> > >
> > > Do you mean something like this:
> > >
> > > diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
> > > index f16059e9a85e..4dae168408f1 100644
> > > --- a/arch/x86/mm/pgtable.c
> > > +++ b/arch/x86/mm/pgtable.c
> > > @@ -434,11 +434,13 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
> > >
> > > mm->pgd = pgd;
> > >
> > > - if (preallocate_pmds(mm, pmds, PREALLOCATED_PMDS) != 0)
> > > - goto out_free_pgd;
> > > + if (MAX_PREALLOCATED_PMDS != 0 && MAX_PREALLOCATED_USER_PMDS != 0) {
> > > + if (preallocate_pmds(mm, pmds, PREALLOCATED_PMDS) != 0)
> > > + goto out_free_pgd;
> > >
> > > - if (preallocate_pmds(mm, u_pmds, PREALLOCATED_USER_PMDS) != 0)
> > > - goto out_free_pmds;
> > > + if (preallocate_pmds(mm, u_pmds, PREALLOCATED_USER_PMDS) != 0)
> > > + goto out_free_pmds;
> > > + }
> > >
> > > if (paravirt_pgd_alloc(mm) != 0)
> > > goto out_free_user_pmds;
> > >
> > > It seems that the above is not enough, because we have the same issue
> > > when calling pgd_prepopulate_pmd(), pgd_prepopulate_user_pmd() and
> > > free_pmds():
> > >
> > > CC arch/x86/mm/pgtable.o
> > > arch/x86/mm/pgtable.c: In function 'pgd_alloc':
> > > arch/x86/mm/pgtable.c:464:9: warning: 'free_pmds' accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]
> > > 464 | free_pmds(mm, u_pmds, PREALLOCATED_USER_PMDS);
> > > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >
> > Ugh. Perhaps just marking both preallocate_pmds() and free_pmds() as
> > inline is enough to let the compiler "see" everything correctly?
>
> It doesn't seem to work... however, the following piece of code implies
> that pmds and u_pmds should be first preallocated through preallocate_pmds(),
> which cannot happen if (MAX_PREALLOCATED_PMDS != 0 && MAX_PREALLOCATED_USER_PMDS != 0)
I wanted to say: which cannot happen if MAX_PREALLOCATED_PMDS == 0 && MAX_PREALLOCATED_USER_PMDS == 0
>
> 448 /*
> 449 * Make sure that pre-populating the pmds is atomic with
> 450 * respect to anything walking the pgd_list, so that they
> 451 * never see a partially populated pgd.
> 452 */
> 453 spin_lock(&pgd_lock);
> 454
> 455 pgd_ctor(mm, pgd);
> 456 pgd_prepopulate_pmd(mm, pgd, pmds);
> 457 pgd_prepopulate_user_pmd(mm, pgd, u_pmds);
> 458
> 459 spin_unlock(&pgd_lock);
> 460
> 461 return pgd;
>
> So, my question here is why do you think the "all 0" case should only skip the
> preallocate_pmds() calls and not the pgd_prepopulate_pmd() calls too?
>
> >
> > Otherwise, they'll likely each need the same check that was added to
> > pgd_prepopulate_pmd() ages ago for a similar situation...
>
> uhm... that doesn't seem to have an impact nowadays, or at least now
> Wstringop-overflow sees the problem first, because now the issue is
> detected at the moment of passing the arguments to the the function
> and not when actually executing the function?
>
> otherwise, I think we wouldn't see this error:
>
> arch/x86/mm/pgtable.c:454:9: warning: 'pgd_prepopulate_pmd' accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]
> 454 | pgd_prepopulate_pmd(mm, pgd, pmds);
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> arch/x86/mm/pgtable.c:454:9: note: referencing argument 3 of type 'pmd_t *[0]'
> arch/x86/mm/pgtable.c:296:13: note: in a call to function 'pgd_prepopulate_pmd'
> 296 | static void pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmds[])
> | ^~~~~~~~~~~~~~~~~~~
>
Thanks
--
Gustavo
next prev parent reply other threads:[~2022-05-10 15:08 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-09 19:45 [PATCH v2][next] x86/mm/pgtable: Fix -Wstringop-overflow warnings Gustavo A. R. Silva
2022-05-09 19:59 ` Kees Cook
2022-05-09 20:50 ` Gustavo A. R. Silva
2022-05-09 20:54 ` Kees Cook
2022-05-10 14:12 ` Gustavo A. R. Silva
2022-05-10 14:54 ` Gustavo A. R. Silva [this message]
2022-05-11 18:41 ` Kees Cook
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=20220510145415.GA8111@embeddedor \
--to=gustavoars@kernel.org \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=keescook@chromium.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=x86@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.