linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Pasha Tatashin <pasha.tatashin@soleen.com>
To: Matthew Wilcox <willy@infradead.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
	linux-mm <linux-mm@kvack.org>,
	 linux-m68k@lists.linux-m68k.org,
	 Anshuman Khandual <anshuman.khandual@arm.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	 william.kucharski@oracle.com,
	Mike Kravetz <mike.kravetz@oracle.com>,
	 Vlastimil Babka <vbabka@suse.cz>,
	Geert Uytterhoeven <geert@linux-m68k.org>,
	schmitzmic@gmail.com,  Steven Rostedt <rostedt@goodmis.org>,
	Ingo Molnar <mingo@redhat.com>,
	 Johannes Weiner <hannes@cmpxchg.org>,
	Roman Gushchin <guro@fb.com>,
	songmuchun@bytedance.com,  weixugc@google.com,
	Greg Thelen <gthelen@google.com>
Subject: Re: [RFC 0/8] Hardening page _refcount
Date: Tue, 26 Oct 2021 17:24:12 -0400	[thread overview]
Message-ID: <CA+CK2bBhMHv=G0Hd=rmCHUjKDOw0sYhOX2q3DfBXSJWFdQj8BQ@mail.gmail.com> (raw)
In-Reply-To: <YXhhbSSRQrG5Av6P@casper.infradead.org>

On Tue, Oct 26, 2021 at 4:14 PM Matthew Wilcox <willy@infradead.org> wrote:
>
> On Tue, Oct 26, 2021 at 02:30:25PM -0400, Pasha Tatashin wrote:
> > On Tue, Oct 26, 2021 at 2:24 PM Matthew Wilcox <willy@infradead.org> wrote:
> > > I think this is overkill.  Won't we get exactly the same protection
> > > by simply testing that page->_refcount == 0 in set_page_count()?
> > > Anything which triggers that BUG_ON would already be buggy because
> > > it can race with speculative gets.
> >
> > We can't because set_page_count(v) is used for
> > 1. changing _refcount form a current value to unconstrained v
> > 2.  initialize _refcount from undefined state to v.
> >
> > In this work we forbid the first case, and reduce the second case to
> > initialize only to 1.
>
> Anything that is calling set_page_refcount() on something which is
> not 0 is buggy today

For performance reasons the memblock allocator does not zero struct
page memory, we initialize every field in struct page individually,
that includes page->_refcount. Most of the time the boot memory is
zeroed by firmware, but it is not guaranteed, non-zero pages can come
from bootloader, or from freed firmware pages. Also, after kexec
memory state is not zeroed as well, and struct pages can contain
garbage until fields are initialized.

This is a valid reason to do set_page_recount() with non-zero
refcounts, but the function is too generic, as in this case we really
need to set it only to 1: so instead rename it to page_ref_init() and
set it only to 1.

Another example:
In __free_pages_core() and in init_cma_reserved_pageblock() we do
set_page_refcount() when _ref_count is 1 and we change it to 0.

In this case doing dec_return check makes more sense in order to
verify that the ref_count was indeed 1, and we won't have a double
free.

>  There are several ways to increment the page
> refcount speculatively if it is not 0.  eg lockless GUP and page cache
> reads.  So we could have:
>
> CPU 0: alloc_page() (refcount now 1)
> CPU 1: get_page_unless_zero() (refcount now 2)
> CPU 0: set_page_refcount(5) (refcount now 5)
> CPU 1: put_page() (refcount now 4)
>
> Now the refcount is wrong.  So it is *only* safe to call
> set_page_refcount() if the refcount is 0.  If you can find somewhere
> that's calling set_page_refcount() on a non-0 refcount, that's a bug
> that needs to be fixed.

Right, add_return/sub_return() with check after operation ensures that
there are no races where we could have some writes to refcount between
knowing it is 0 and calling set_page_refcount().

Thanks,
Pasha


      reply	other threads:[~2021-10-26 21:24 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-26 17:38 [RFC 0/8] Hardening page _refcount Pasha Tatashin
2021-10-26 17:38 ` [RFC 1/8] mm: add overflow and underflow checks for page->_refcount Pasha Tatashin
2021-10-26 19:48   ` Matthew Wilcox
2021-10-26 21:34     ` Pasha Tatashin
2021-10-27  1:21       ` Pasha Tatashin
2021-10-27  3:04         ` Matthew Wilcox
2021-10-27 18:22           ` Pasha Tatashin
2021-10-27  7:46   ` Muchun Song
2021-10-27 18:22     ` Pasha Tatashin
2021-10-28  4:08       ` Muchun Song
2021-10-26 17:38 ` [RFC 2/8] mm/hugetlb: remove useless set_page_count() Pasha Tatashin
2021-10-26 18:44   ` Mike Kravetz
2021-10-26 18:50     ` Pasha Tatashin
2021-10-26 21:19       ` Mike Kravetz
2021-10-26 17:38 ` [RFC 3/8] mm: Avoid using set_page_count() in set_page_recounted() Pasha Tatashin
2021-10-26 17:53   ` John Hubbard
2021-10-26 18:01     ` John Hubbard
2021-10-26 18:14       ` Pasha Tatashin
2021-10-26 18:21     ` Pasha Tatashin
2021-10-27  5:12       ` John Hubbard
2021-10-27 18:27         ` Pasha Tatashin
2021-10-28  1:20           ` John Hubbard
2021-10-28  1:35             ` John Hubbard
2021-11-01 14:30               ` Pasha Tatashin
2021-11-01 19:35                 ` John Hubbard
2021-11-01 14:22             ` Pasha Tatashin
2021-11-01 19:31               ` John Hubbard
2021-11-01 19:42               ` John Hubbard
2021-10-26 17:38 ` [RFC 4/8] mm: remove set_page_count() from page_frag_alloc_align Pasha Tatashin
2021-10-26 17:38 ` [RFC 5/8] mm: avoid using set_page_count() when pages are freed into allocator Pasha Tatashin
2021-10-26 17:38 ` [RFC 6/8] mm: rename init_page_count() -> page_ref_init() Pasha Tatashin
2021-10-27  6:46   ` Geert Uytterhoeven
2021-10-26 17:38 ` [RFC 7/8] mm: remove set_page_count() Pasha Tatashin
2021-10-26 17:38 ` [RFC 8/8] mm: simplify page_ref_* functions Pasha Tatashin
2021-10-26 18:23 ` [RFC 0/8] Hardening page _refcount Matthew Wilcox
2021-10-26 18:30   ` Pasha Tatashin
2021-10-26 20:13     ` Matthew Wilcox
2021-10-26 21:24       ` Pasha Tatashin [this message]

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='CA+CK2bBhMHv=G0Hd=rmCHUjKDOw0sYhOX2q3DfBXSJWFdQj8BQ@mail.gmail.com' \
    --to=pasha.tatashin@soleen.com \
    --cc=akpm@linux-foundation.org \
    --cc=anshuman.khandual@arm.com \
    --cc=geert@linux-m68k.org \
    --cc=gthelen@google.com \
    --cc=guro@fb.com \
    --cc=hannes@cmpxchg.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-m68k@lists.linux-m68k.org \
    --cc=linux-mm@kvack.org \
    --cc=mike.kravetz@oracle.com \
    --cc=mingo@redhat.com \
    --cc=rostedt@goodmis.org \
    --cc=schmitzmic@gmail.com \
    --cc=songmuchun@bytedance.com \
    --cc=vbabka@suse.cz \
    --cc=weixugc@google.com \
    --cc=william.kucharski@oracle.com \
    --cc=willy@infradead.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).