2023-12-15 12:32:04

by Petr Tesarik

[permalink] [raw]
Subject: [PATCH 0/2] um: improve UML page fault handling

From: Petr Tesarik <[email protected]>

Improve UML handling of segmentation faults in kernel mode. Although
such page faults are generally caused by a kernel bug, it is annoying
if they cause an infinite loop, or panic the kernel. More importantly,
a robust implementation allows to write KUnit tests for various guard
pages, preventing potential kernel self-protection regressions.

Petr Tesarik (2):
um: do not panic on kernel mode faults
um: oops on accessing an non-present page in the vmalloc area

arch/um/kernel/trap.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)

--
2.34.1



2023-12-15 12:32:50

by Petr Tesarik

[permalink] [raw]
Subject: [PATCH 1/2] um: do not panic on kernel mode faults

From: Petr Tesarik <[email protected]>

Do not call panic() on unrecoverable page faults in kernel mode. Although
such page faults always indicate a bug in the kernel, other architectures
prefer to kill only the current process and continue.

The new behavior is useful for testing intentional kernel mode page faults
with KUnit.

Signed-off-by: Petr Tesarik <[email protected]>
---
arch/um/kernel/trap.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index 6d8ae86ae978..1124a382fd14 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -17,6 +17,14 @@
#include <os.h>
#include <skas.h>

+static void page_fault_oops(struct uml_pt_regs *regs, unsigned long address,
+ unsigned long ip)
+{
+ pr_alert("Kernel mode fault at addr 0x%lx, ip 0x%lx\n", address, ip);
+ show_regs(container_of(regs, struct pt_regs, regs));
+ make_task_dead(SIGKILL);
+}
+
/*
* Note this is constrained to return 0, -EFAULT, -EACCES, -ENOMEM by
* segv().
@@ -249,11 +257,8 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
else if (!is_user && arch_fixup(ip, regs))
goto out;

- if (!is_user) {
- show_regs(container_of(regs, struct pt_regs, regs));
- panic("Kernel mode fault at addr 0x%lx, ip 0x%lx",
- address, ip);
- }
+ if (!is_user)
+ page_fault_oops(regs, address, ip);

show_segv_info(regs);

--
2.34.1


2023-12-15 12:33:08

by Petr Tesarik

[permalink] [raw]
Subject: [PATCH 2/2] um: oops on accessing an non-present page in the vmalloc area

From: Petr Tesarik <[email protected]>

If a segmentation fault is caused by an address in the vmalloc area, check
that the target page is present.

Currently, if the kernel hits a guard page the vmalloc area, UML assumes
that the fault is caused merely by a stale mapping and will be fixed by
flush_tlb_kernel_vm(). Of course, this will not create any mapping for a
guard page, so the faulting instruction will cause exactly the same fault
when it is executed again, effectively creating a beautiful (but useless)
infinite loop.

Signed-off-by: Petr Tesarik <[email protected]>
---
arch/um/kernel/trap.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index 1124a382fd14..ca9b5fd83c52 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -214,11 +214,15 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
int err;
int is_write = FAULT_WRITE(fi);
unsigned long address = FAULT_ADDRESS(fi);
+ pte_t *pte;

if (!is_user && regs)
current->thread.segv_regs = container_of(regs, struct pt_regs, regs);

if (!is_user && (address >= start_vm) && (address < end_vm)) {
+ pte = virt_to_pte(&init_mm, address);
+ if (!pte_present(*pte))
+ page_fault_oops(regs, address, ip);
flush_tlb_kernel_vm();
goto out;
}
--
2.34.1


2024-01-03 13:02:09

by Petr Tesařík

[permalink] [raw]
Subject: Re: [PATCH 0/2] um: improve UML page fault handling

Happy New Year, everyone!

I can fully understand that you all have had other priorities around
the year end; it was no different with me. ;-)

However, may I kindly ask for some feedback on my proposed fixes?

Petr T

On Fri, 15 Dec 2023 13:14:29 +0100
Petr Tesarik <[email protected]> wrote:

> From: Petr Tesarik <[email protected]>
>
> Improve UML handling of segmentation faults in kernel mode. Although
> such page faults are generally caused by a kernel bug, it is annoying
> if they cause an infinite loop, or panic the kernel. More importantly,
> a robust implementation allows to write KUnit tests for various guard
> pages, preventing potential kernel self-protection regressions.
>
> Petr Tesarik (2):
> um: do not panic on kernel mode faults
> um: oops on accessing an non-present page in the vmalloc area
>
> arch/um/kernel/trap.c | 19 ++++++++++++++-----
> 1 file changed, 14 insertions(+), 5 deletions(-)
>


2024-01-04 23:22:31

by Richard Weinberger

[permalink] [raw]
Subject: Re: [PATCH 0/2] um: improve UML page fault handling

----- Ursprüngliche Mail -----
> Von: "Petr Tesarik" <[email protected]>
> An: "richard" <[email protected]>, "anton ivanov" <[email protected]>, "Johannes Berg"
> <[email protected]>, "linux-um" <[email protected]>, "linux-kernel" <[email protected]>
> CC: "Roberto Sassu" <[email protected]>, [email protected], "Petr Tesarik"
> <[email protected]>
> Gesendet: Freitag, 15. Dezember 2023 13:14:29
> Betreff: [PATCH 0/2] um: improve UML page fault handling

> From: Petr Tesarik <[email protected]>
>
> Improve UML handling of segmentation faults in kernel mode. Although
> such page faults are generally caused by a kernel bug, it is annoying
> if they cause an infinite loop, or panic the kernel. More importantly,
> a robust implementation allows to write KUnit tests for various guard
> pages, preventing potential kernel self-protection regressions.
>
> Petr Tesarik (2):
> um: do not panic on kernel mode faults
> um: oops on accessing an non-present page in the vmalloc area

I think this is a good thing to have.
For the implementation side, this needs to use the oops_* helpers
from kernel/panic.c and taint the kernel, etc...
See arch/x86/kernel/dumpstack.c die() and friends.

Thanks,
//richard

2024-01-05 06:51:31

by Petr Tesařík

[permalink] [raw]
Subject: Re: [PATCH 0/2] um: improve UML page fault handling

Helo Richard,

Am Fri, 5 Jan 2024 00:22:11 +0100 (CET)
schrieb Richard Weinberger <[email protected]>:

> ----- Ursprüngliche Mail -----
> > Von: "Petr Tesarik" <[email protected]>
> > An: "richard" <[email protected]>, "anton ivanov" <[email protected]>, "Johannes Berg"
> > <[email protected]>, "linux-um" <[email protected]>, "linux-kernel" <[email protected]>
> > CC: "Roberto Sassu" <[email protected]>, [email protected], "Petr Tesarik"
> > <[email protected]>
> > Gesendet: Freitag, 15. Dezember 2023 13:14:29
> > Betreff: [PATCH 0/2] um: improve UML page fault handling
>
> > From: Petr Tesarik <[email protected]>
> >
> > Improve UML handling of segmentation faults in kernel mode. Although
> > such page faults are generally caused by a kernel bug, it is annoying
> > if they cause an infinite loop, or panic the kernel. More importantly,
> > a robust implementation allows to write KUnit tests for various guard
> > pages, preventing potential kernel self-protection regressions.
> >
> > Petr Tesarik (2):
> > um: do not panic on kernel mode faults
> > um: oops on accessing an non-present page in the vmalloc area
>
> I think this is a good thing to have.

Thanks for the feedback.

> For the implementation side, this needs to use the oops_* helpers
> from kernel/panic.c and taint the kernel, etc...

Yes, I did see that coming but wanted to get some confirmation that
it's worth the effort.

> See arch/x86/kernel/dumpstack.c die() and friends.

This implementation also calls die notifiers, but AFAICS different
architectures are not very consistent in their use. Do you also
require die notifiers for the UML implementation?

Petr T

2024-01-26 10:27:08

by Petr Tesařík

[permalink] [raw]
Subject: Re: [PATCH 0/2] um: improve UML page fault handling

On Fri, 5 Jan 2024 07:51:09 +0100
Petr Tesařík <[email protected]> wrote:

> Helo Richard,
>
> Am Fri, 5 Jan 2024 00:22:11 +0100 (CET)
> schrieb Richard Weinberger <[email protected]>:
>
> > ----- Ursprüngliche Mail -----
> > > Von: "Petr Tesarik" <[email protected]>
> > > An: "richard" <[email protected]>, "anton ivanov" <[email protected]>, "Johannes Berg"
> > > <[email protected]>, "linux-um" <[email protected]>, "linux-kernel" <[email protected]>
> > > CC: "Roberto Sassu" <[email protected]>, [email protected], "Petr Tesarik"
> > > <[email protected]>
> > > Gesendet: Freitag, 15. Dezember 2023 13:14:29
> > > Betreff: [PATCH 0/2] um: improve UML page fault handling
> >
> > > From: Petr Tesarik <[email protected]>
> > >
> > > Improve UML handling of segmentation faults in kernel mode. Although
> > > such page faults are generally caused by a kernel bug, it is annoying
> > > if they cause an infinite loop, or panic the kernel. More importantly,
> > > a robust implementation allows to write KUnit tests for various guard
> > > pages, preventing potential kernel self-protection regressions.
> > >
> > > Petr Tesarik (2):
> > > um: do not panic on kernel mode faults
> > > um: oops on accessing an non-present page in the vmalloc area
> >
> > I think this is a good thing to have.
>
> Thanks for the feedback.
>
> > For the implementation side, this needs to use the oops_* helpers
> > from kernel/panic.c and taint the kernel, etc...
>
> Yes, I did see that coming but wanted to get some confirmation that
> it's worth the effort.
>
> > See arch/x86/kernel/dumpstack.c die() and friends.
>
> This implementation also calls die notifiers, but AFAICS different
> architectures are not very consistent in their use. Do you also
> require die notifiers for the UML implementation?

It seems I won't have time for this in the near future... Can I start
by sending a trivial patch that panics the kernel if kernel mode tries
to access a vmalloc guard page? That's something I can do immediately,
and it's still better than getting page faults in an infinite loop...

Petr T