Linux Hardening
 help / color / mirror / Atom feed
From: Kevin Brodsky <kevin.brodsky@arm.com>
To: Qi Zheng <zhengqi.arch@bytedance.com>
Cc: linux-hardening@vger.kernel.org, linux-kernel@vger.kernel.org,
	Andrew Morton <akpm@linux-foundation.org>,
	Mark Brown <broonie@kernel.org>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	Jann Horn <jannh@google.com>, Jeff Xu <jeffxu@chromium.org>,
	Joey Gouly <joey.gouly@arm.com>, Kees Cook <kees@kernel.org>,
	Linus Walleij <linus.walleij@linaro.org>,
	Andy Lutomirski <luto@kernel.org>, Marc Zyngier <maz@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Pierre Langlois <pierre.langlois@arm.com>,
	Quentin Perret <qperret@google.com>,
	"Mike Rapoport (IBM)" <rppt@kernel.org>,
	Ryan Roberts <ryan.roberts@arm.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Will Deacon <will@kernel.org>,
	Matthew Wilcox <willy@infradead.org>,
	linux-arm-kernel@lists.infradead.org, x86@kernel.org
Subject: Re: [RFC PATCH v2 13/15] arm64: mm: Guard page table writes with kpkeys
Date: Fri, 10 Jan 2025 15:05:15 +0100	[thread overview]
Message-ID: <705c7fec-8e3c-4d4d-b3c2-c1f75d10db42@arm.com> (raw)
In-Reply-To: <6b4c4abb-8d53-4b17-8a1c-1d28fb4d5f88@bytedance.com>

On 09/01/2025 08:17, Qi Zheng wrote:
> [...]
>
>> @@ -314,6 +315,7 @@ static inline pte_t pte_clear_uffd_wp(pte_t pte)
>>     static inline void __set_pte_nosync(pte_t *ptep, pte_t pte)
>>   {
>> +    guard(kpkeys_hardened_pgtables)();
>>       WRITE_ONCE(*ptep, pte);
>>   }
>>   @@ -758,6 +760,7 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
>>       }
>>   #endif /* __PAGETABLE_PMD_FOLDED */
>>   +    guard(kpkeys_hardened_pgtables)();
>>       WRITE_ONCE(*pmdp, pmd);
>>         if (pmd_valid(pmd)) {
>
> I noticed a long time ago that set_pte/set_pmd/... was implemented
> separately by each architecture without a unified entry point. This
> makes it difficult to add some hooks for them.
>
> Taking set_pte() as an example, is it possible to do the following:
>
> 1) add a generic set_pte() in include/asm-generic/tlb.h (Or other more
>    appropriate files)
>
> static inline void set_pte(pte_t *ptep, pte_t pte)
> {
>     arch_set_pte(ptep, pte);
> }
>
> 2) let each architecture include this file and rename the original
>    set_pte() to arch_set_pte().
>
> 3) then we can add hooks for generic set_pte():
>
> static inline void set_pte(pte_t *ptep, pte_t pte)
> {
>     guard(kpkeys_hardened_pgtables)();
>     arch_set_pte(ptep, pte);
> }
>
> 4) in this way, the architecture that supports
>    ARCH_HAS_KPKEYS_HARDENED_PGTABLES only needs to implement
>    the kpkeys_hardened_pgtables(), otherwise it is no-op.

Thanks for chiming in, it is an interesting idea for sure. I think the
issue here might be the benefit/churn ratio, because this would simply
be adding a layer of (generic) function calls without unifying any
existing arch code. Unfortunately, unlike the pagetable_alloc/tlb stuff,
the majority of what happens in the page table modifiers is arch-specific.

For set_p*(), we could potentially have it call a generic __set_p*()
that does a WRITE_ONCE(), which is what most architectures do (in
addition to various other things, like DSB/ISB on arm64). Adding the
kpkeys_hardened_pgtables guard there would be better, as it reduces the
"privileged" window to just the write itself. However for the other
modifiers, say ptep_get_and_clear(), the implementation seems to vary
wildly between arch's, including the atomic operation itself. Any
unification of those seems therefore difficult.

That said, I'd be happy to look into adding that generic layer on top
(i.e. generic set_pte() calls arch_set_pte()) if there is enough
consensus that the churn is justified. We could potentially do a mix of
both as well (arch-defined set_pte() calls generic __set_pte(), while
generic ptep_get_and_clear() calls arch_ptep_get_and_clear()).

- Kevin

  reply	other threads:[~2025-01-10 14:05 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-08 10:32 [RFC PATCH v2 00/15] pkeys-based page table hardening Kevin Brodsky
2025-01-08 10:32 ` [RFC PATCH v2 01/15] mm: Introduce kpkeys Kevin Brodsky
2025-01-08 10:32 ` [RFC PATCH v2 02/15] set_memory: Introduce set_memory_pkey() stub Kevin Brodsky
2025-01-08 10:32 ` [RFC PATCH v2 03/15] arm64: mm: Enable overlays for all EL1 indirect permissions Kevin Brodsky
2025-01-08 10:32 ` [RFC PATCH v2 04/15] arm64: Introduce por_set_pkey_perms() helper Kevin Brodsky
2025-01-08 10:32 ` [RFC PATCH v2 05/15] arm64: Implement asm/kpkeys.h using POE Kevin Brodsky
2025-01-08 10:32 ` [RFC PATCH v2 06/15] arm64: set_memory: Implement set_memory_pkey() Kevin Brodsky
2025-01-08 10:32 ` [RFC PATCH v2 07/15] arm64: Enable kpkeys Kevin Brodsky
2025-01-08 10:32 ` [RFC PATCH v2 08/15] mm: Introduce kernel_pgtables_set_pkey() Kevin Brodsky
2025-01-08 10:32 ` [RFC PATCH v2 09/15] mm: Introduce kpkeys_hardened_pgtables Kevin Brodsky
2025-01-08 10:32 ` [RFC PATCH v2 10/15] mm: Allow __pagetable_ctor() to fail Kevin Brodsky
2025-01-08 10:32 ` [RFC PATCH v2 11/15] mm: Map page tables with privileged pkey Kevin Brodsky
2025-01-08 10:32 ` [RFC PATCH v2 12/15] arm64: kpkeys: Support KPKEYS_LVL_PGTABLES Kevin Brodsky
2025-01-08 10:32 ` [RFC PATCH v2 13/15] arm64: mm: Guard page table writes with kpkeys Kevin Brodsky
2025-01-09  7:17   ` Qi Zheng
2025-01-10 14:05     ` Kevin Brodsky [this message]
2025-01-08 10:32 ` [RFC PATCH v2 14/15] arm64: Enable kpkeys_hardened_pgtables support Kevin Brodsky
2025-01-08 10:32 ` [RFC PATCH v2 15/15] mm: Add basic tests for kpkeys_hardened_pgtables Kevin Brodsky
2025-01-09 16:30 ` [RFC PATCH v2 00/15] pkeys-based page table hardening Dave Hansen
2025-01-13 10:10   ` Kevin Brodsky

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=705c7fec-8e3c-4d4d-b3c2-c1f75d10db42@arm.com \
    --to=kevin.brodsky@arm.com \
    --cc=akpm@linux-foundation.org \
    --cc=broonie@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=jannh@google.com \
    --cc=jeffxu@chromium.org \
    --cc=joey.gouly@arm.com \
    --cc=kees@kernel.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=maz@kernel.org \
    --cc=peterz@infradead.org \
    --cc=pierre.langlois@arm.com \
    --cc=qperret@google.com \
    --cc=rppt@kernel.org \
    --cc=ryan.roberts@arm.com \
    --cc=tglx@linutronix.de \
    --cc=will@kernel.org \
    --cc=willy@infradead.org \
    --cc=x86@kernel.org \
    --cc=zhengqi.arch@bytedance.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