linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* Memory protection keys: Signal handlers crash if pkey0 is write-disabled
@ 2023-09-07 21:22 Robert Kueffner
  2023-09-07 21:31 ` Dave Hansen
  0 siblings, 1 reply; 5+ messages in thread
From: Robert Kueffner @ 2023-09-07 21:22 UTC (permalink / raw)
  To: Kyle Huey, Dave Hansen, Thomas Gleixner, Borislav Petkov
  Cc: linux-kernel, linux-mm, Robert Kueffner

I am trying to establish memory protection domains in x86/linux using memory protection keys and the protection key register PKRU. 
Briefly:
(1) My program allocates a new protection key pkey1 and associated memory, and installs custom signal handlers for FPE+SEGV
(2) I define "user code" as code that should only operate in that memory, i.e. I want to disable write on pages with pkey0 by setting PKRU.WD0=true
(3) In this setup, if the user code causes an exception, the kernel causes an additional SEGV when switching to my signal handler
		(a) in case of user code causing SEGV this occurs upon return from sigprocmask()
		(b) in case of user code causing FPE this occurs right upon switching to the signal handler
(3) only happens when user code runs with WD0=true, my example code tests successfully as long as WD0=false

Is there some way to make this work, or is it generally not possible to successfully handle exceptions if WD0=true?

More details and a minimal implementation: https://unix.stackexchange.com/questions/755160/memory-protection-keys-exception-handler-crashes-if-pkey0-is-write-disabled

Robert

---

12th Gen Intel(R) Core(TM) i7-12700

Linux version 6.2.0-32-generic (buildd@lcy02-amd64-023) (x86_64-linux-gnu-gcc-12 (Ubuntu 12.3.0-1ubuntu1~23.04) 12.3.0, GNU ld (GNU Binutils for Ubuntu) 2.40) #32-Ubuntu SMP PREEMPT_DYNAMIC Mon Aug 14 10:03:50 UTC 2023

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Memory protection keys: Signal handlers crash if pkey0 is write-disabled
  2023-09-07 21:22 Memory protection keys: Signal handlers crash if pkey0 is write-disabled Robert Kueffner
@ 2023-09-07 21:31 ` Dave Hansen
  2023-09-07 23:07   ` Robert Kueffner
  0 siblings, 1 reply; 5+ messages in thread
From: Dave Hansen @ 2023-09-07 21:31 UTC (permalink / raw)
  To: Robert Kueffner, Kyle Huey, Dave Hansen, Thomas Gleixner,
	Borislav Petkov
  Cc: linux-kernel, linux-mm

On 9/7/23 14:22, Robert Kueffner wrote:
> Is there some way to make this work, or is it generally not possible
> to successfully handle exceptions if WD0=true?

It's theoretically possible, but it's in a grey area.  The kernel can't
easily try to respect PKRU *and* override it for things like decoding
userspace instructions.

PKRU should get reset to a value that permits reads and writes to pkey-0
before the signal frame is created.  But you're obviously tripping over
it anyway.

I assume that *something* is trying to access pkey-0-protected memory.
Any idea what that is?  Which entity is doing that access and what are
they accessing?  The page fault tracepoints might come in handy.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Memory protection keys: Signal handlers crash if pkey0 is write-disabled
  2023-09-07 21:31 ` Dave Hansen
@ 2023-09-07 23:07   ` Robert Kueffner
  2023-09-08 15:14     ` Dave Hansen
  0 siblings, 1 reply; 5+ messages in thread
From: Robert Kueffner @ 2023-09-07 23:07 UTC (permalink / raw)
  To: Dave Hansen
  Cc: Kyle Huey, Dave Hansen, Thomas Gleixner, Borislav Petkov,
	linux-kernel, linux-mm, Robert Kueffner

> I assume that *something* is trying to access pkey-0-protected memory.
> Any idea what that is?  Which entity is doing that access and what are
> they accessing?  The page fault tracepoints might come in handy.

If I understand correctly, the kernel (a) pushes the processor state onto the stack and (b) resets PKRU=0x55555554 some time before switching to the signal handler. And may try between (a) and (b) to write pkey-0-protected memory. 

This would be compatible with what I see when my user code causes a FPE, upon which there is a SEGV before the kernel switches to my signal handler. 

If the user code causes SEGV my signal handler actually executes and only fails later when returning from syscall 14 in sigprocmask(), i.e. sigprocmask() => __GI___sigprocmask => __GI___pthread_sigmask => syscall 14

I will look into tracepoints - but that would be diagnostic rather

As a farfetched solution, would there be a way, perhaps via a kernel hook, to reset PKRU before the kernel actually starts processing the signal?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Memory protection keys: Signal handlers crash if pkey0 is write-disabled
  2023-09-07 23:07   ` Robert Kueffner
@ 2023-09-08 15:14     ` Dave Hansen
  2023-09-08 15:43       ` Robert Kueffner
  0 siblings, 1 reply; 5+ messages in thread
From: Dave Hansen @ 2023-09-08 15:14 UTC (permalink / raw)
  To: Robert Kueffner
  Cc: Kyle Huey, Dave Hansen, Thomas Gleixner, Borislav Petkov,
	linux-kernel, linux-mm

On 9/7/23 16:07, Robert Kueffner wrote:
>> I assume that *something* is trying to access pkey-0-protected
>> memory. Any idea what that is?  Which entity is doing that access
>> and what are they accessing?  The page fault tracepoints might come
>> in handy.
> If I understand correctly, the kernel (a) pushes the processor state
> onto the stack and (b) resets PKRU=0x55555554 some time before
> switching to the signal handler. And may try between (a) and (b) to
> write pkey-0-protected memory.
Well, the "pushes the processor state onto the stack" part is probably
the problem.  That processor state _includes_ PKRU and it's also
eventually the only place that processor state exists.

That means that there's no simple solution.  You can't just move up
where PKRU gets reset because that will blow away the PKRU that you need
to save on the stack.

There are tons of complicated ways to fix this.  But the easiest way is
just to say that you need to keep PKRU set so that the signal frame can
be written at any time.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Memory protection keys: Signal handlers crash if pkey0 is write-disabled
  2023-09-08 15:14     ` Dave Hansen
@ 2023-09-08 15:43       ` Robert Kueffner
  0 siblings, 0 replies; 5+ messages in thread
From: Robert Kueffner @ 2023-09-08 15:43 UTC (permalink / raw)
  To: Dave Hansen
  Cc: Kyle Huey, Dave Hansen, Thomas Gleixner, Borislav Petkov,
	linux-kernel, linux-mm

> There are tons of complicated ways to fix this.  But the easiest way is
> just to say that you need to keep PKRU set so that the signal frame can
> be written at any time.

Just for completeness sake, the signal frame was actually written successfully since I moved the stack pointer to pkey-1 associated memory before any exceptions, details in unix.stackexchange I <https://unix.stackexchange.com/questions/755160/memory-protection-keys-exception-handler-crashes-if-pkey0-is-write-disabled> posted in the beginning.
And it’s probably that the kernel wants to write something else into pkey-0 associated memory. 

I understand that there is no easy solution, so my idea of isolating a user from corrupting pkey-0 memory is probably moot.

Thanks Dave, that helped me a lot to understand the problem

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-09-08 15:43 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-07 21:22 Memory protection keys: Signal handlers crash if pkey0 is write-disabled Robert Kueffner
2023-09-07 21:31 ` Dave Hansen
2023-09-07 23:07   ` Robert Kueffner
2023-09-08 15:14     ` Dave Hansen
2023-09-08 15:43       ` Robert Kueffner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox