linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Robin Murphy <robin.murphy@arm.com>
To: Matthew Wilcox <willy@infradead.org>
Cc: Yury Norov <yury.norov@gmail.com>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Nicholas Piggin <npiggin@gmail.com>,
	Ding Tianhong <dingtianhong@huawei.com>,
	Anshuman Khandual <anshuman.khandual@arm.com>,
	Alexey Klimov <aklimov@redhat.com>,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-mm@kvack.org
Subject: Re: [PATCH] vmap(): don't allow invalid pages
Date: Wed, 19 Jan 2022 18:43:10 +0000	[thread overview]
Message-ID: <e9226eb4-4ecf-ac01-e823-ff507a354ac5@arm.com> (raw)
In-Reply-To: <Yeg79CcofyNuVLid@casper.infradead.org>

On 2022-01-19 16:27, Matthew Wilcox wrote:
> On Wed, Jan 19, 2022 at 01:28:14PM +0000, Robin Murphy wrote:
>>> +		if (WARN_ON(!pfn_valid(page_to_pfn(page))))
>>
>> Is it page_to_pfn() guaranteed to work without blowing up if page is invalid
>> in the first place? Looking at the CONFIG_SPARSEMEM case I'm not sure that's
>> true...
> 
> Even if it does blow up, at least it's blowing up here where someone
> can start to debug it, rather than blowing up on first access, where
> we no longer have the invlid struct page pointer.

But if that were the case then we'd blow up on the following line when 
mk_pte(page, prot) ends up calling it same anyway. Indeed it's arguably 
the best-case scenario since it would also blow up in page_address() if 
we hit the vmap_range loop rather than going down the 
vmap_small_pages_range_noflush() path.

Furthermore, if you *are* lucky enough to take a fault upon accessing a 
bogus mapping, then surely a phys_to_page() calculation on whatever 
ended up in the PTE should get you back the original "pointer" anyway, 
shouldn't it? Sure it's a bit more work to extract the caller out of the 
VMA if necessary, but hey, that's debugging! Maybe vmap() failing means 
you then pass the offending nonsense to __free_pages() and that ruins 
your day anyway...

The implications are infinitely worse if you've mapped something that 
did happen to be a valid page, but wasn't the *right* page, such that 
you don't fault but corrupt things or trigger a fatal system error 
instead. I'd echo Mark's point that if we can't trust a page pointer to 
be correct then we've already lost. In general the proportion of "wrong" 
pointers one can viably attempt to detect is so small that it's rarely 
ever worth trying, and the cases that are so obviously wrong tend to 
show up well enough in normal operation (although NULL-safety is of 
course a bit of a special case when it can simplify API usage).

> I don't think we have a 'page_valid' function which will tell us whether
> a random pointer is actually a struct page or not.

Indeed, my impression is that the only legitimate way to get hold of a 
page pointer without assumed provenance is via pfn_to_page(), which is 
where pfn_valid() comes in. Thus pfn_valid(page_to_pfn()) really 
*should* be a tautology.

I guess in this instance it would be technically feasible to implement a 
function which checks "is this a correctly-aligned pointer within memmap 
bounds", but IMO that would be a massive step in the wrong direction. 
We're developers; sometimes we introduce bugs when developing code, and 
it takes effort to debug them, but that still doesn't make it a good 
idea to optimise normal code paths for the expectation of writing new 
catastrophically-bad bugs. Plus logically if such a "page_valid()" check 
could be justified at all then that should rightfully lead to a 
churn-fest of adding it to pretty much every interface which accepts 
page pointers - one half of vmap() is hardly special.

FWIW, If anything I reckon a DEBUG_VM option that made checks within 
page_to_x/x_to_page as appropriate would help Yury's issue just as much, 
while having the potential to be considerably more useful in general.

Cheers,
Robin.


  parent reply	other threads:[~2022-01-19 18:43 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-18 23:52 [PATCH] vmap(): don't allow invalid pages Yury Norov
2022-01-19  0:51 ` Matthew Wilcox
2022-01-19  6:17   ` Anshuman Khandual
2022-01-19 17:22     ` Yury Norov
2022-01-20  3:37       ` Anshuman Khandual
2022-01-20  4:27         ` Matthew Wilcox
2022-01-21  2:56         ` Yury Norov
2022-01-19 11:16 ` Mark Rutland
2022-01-19 17:00   ` Yury Norov
2022-01-19 18:06     ` Mark Rutland
2022-01-19 13:28 ` Robin Murphy
2022-01-19 16:27   ` Matthew Wilcox
2022-01-19 17:54     ` Russell King (Oracle)
2022-01-19 18:01       ` Matthew Wilcox
2022-01-19 18:57         ` Russell King (Oracle)
2022-01-19 19:35           ` Matthew Wilcox
2022-01-19 22:38             ` Russell King (Oracle)
2022-01-19 18:43     ` Robin Murphy [this message]
2022-01-19 19:12       ` Russell King (Oracle)
2022-01-20 12:22         ` Robin Murphy
2022-01-20 13:03           ` Russell King (Oracle)
2022-01-20 16:37             ` Robin Murphy
2022-01-20 16:54               ` Russell King (Oracle)
2022-01-20 19:04                 ` Matthew Wilcox
2022-01-21  5:26               ` Yury Norov
2022-01-26  2:50   ` Matthew Wilcox

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=e9226eb4-4ecf-ac01-e823-ff507a354ac5@arm.com \
    --to=robin.murphy@arm.com \
    --cc=aklimov@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=anshuman.khandual@arm.com \
    --cc=catalin.marinas@arm.com \
    --cc=dingtianhong@huawei.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=npiggin@gmail.com \
    --cc=will@kernel.org \
    --cc=willy@infradead.org \
    --cc=yury.norov@gmail.com \
    /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).