On Tue, 06 Oct 2020 09:49:33 PDT (-0700), [email protected] wrote:
From: Guo Ren <[email protected]>

As Aurelien has reported:

[    3.484586] AppArmor: AppArmor sha1 policy hashing enabled
[    4.749835] Freeing unused kernel memory: 492K
[    4.752017] Run /init as init process
[    4.753571] usercopy: Kernel memory overwrite attempt detected to kernel 
text (offset 507879, size 11)!
[    4.754838] ------------[ cut here ]------------
[    4.755651] kernel BUG at mm/usercopy.c:99!
[    4.756445] Kernel BUG [#1]
[    4.756815] Modules linked in:
[    4.757542] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.8.0-1-riscv64 #1 
Debian 5.8.7-1
[    4.758372] epc: ffffffe0003b5120 ra : ffffffe0003b5120 sp : ffffffe07f783ca0
[    4.758960]  gp : ffffffe000cc7230 tp : ffffffe07f77cec0 t0 : 
ffffffe000cdafc0
[    4.759772]  t1 : 0000000000000064 t2 : 0000000000000000 s0 : 
ffffffe07f783cf0
[    4.760534]  s1 : ffffffe00095d780 a0 : 000000000000005b a1 : 
0000000000000020
[    4.761309]  a2 : 0000000000000005 a3 : 0000000000000000 a4 : 
ffffffe000c1f340
[    4.761848]  a5 : ffffffe000c1f340 a6 : 0000000000000000 a7 : 
0000000000000087
[    4.762684]  s2 : ffffffe000941848 s3 : 000000000007bfe7 s4 : 
000000000000000b
[    4.763500]  s5 : 0000000000000000 s6 : ffffffe00091cc00 s7 : 
fffffffffffff000
[    4.764376]  s8 : 0000003ffffff000 s9 : ffffffe0769f3200 s10: 
000000000000000b
[    4.765208]  s11: ffffffe07d548c40 t3 : 0000000000000000 t4 : 
000000000001dcd0
[    4.766059]  t5 : ffffffe000cc8510 t6 : ffffffe000cd64aa
[    4.766712] status: 0000000000000120 badaddr: 0000000000000000 cause: 
0000000000000003
[    4.768308] ---[ end trace 1f8e733e834d4c3e ]---
[    4.769129] Kernel panic - not syncing: Attempted to kill init! 
exitcode=0x0000000b
[    4.770070] SMP: stopping secondary CPUs
[    4.771110] ---[ end Kernel panic - not syncing: Attempted to kill init! 
exitcode=0x0000000b ]---

Above failure is relate to commit: a0fa4027dc911 (riscv: Fixup

That commit isn't in Linus' tree (at least, as far as I see it).  I have
6184358da000 ("riscv: Fixup static_obj() fail"), so I'm going to fix that -- in
fact, I'm going to essentially just replace most of this rationale with what I
wrote up in my revert as this is all a bit too long for a commit message.

I was kind of worried the initdata move was a bit too risky, but after reading
the users of __init_{begin,end} I think it's safe.  Here's what I ended up with
on fixes.

Thanks!

commit 84814460eef9af0fb56a4698341c9cb7996a6312 (HEAD -> fixes, riscv/fixes)
gpg: Signature made Tue 06 Oct 2020 09:11:35 PM PDT
gpg:                using RSA key 2B3C3747446843B24A943A7A2E1319F35FBB1889
gpg:                issuer "[email protected]"
gpg: Good signature from "Palmer Dabbelt <[email protected]>" [ultimate]
gpg:                 aka "Palmer Dabbelt <[email protected]>" [ultimate]
Author: Guo Ren <[email protected]>
Date:   Tue Oct 6 16:49:33 2020 +0000

   riscv: Fixup bootup failure with HARDENED_USERCOPY
6184358da000 ("riscv: Fixup static_obj() fail") attempted to elide a lockdep
   failure by rearranging our kernel image to place all initdata within [_stext,
   _end], thus triggering lockdep to treat these as static objects.  These 
objects
   are released and eventually reallocated, causing check_kernel_text_object() 
to
   trigger a BUG().
This backs out the change to make [_stext, _end] all-encompassing, instead just
   moving initdata.  This results in initdata being outside of [__init_begin,
   __init_end], which means initdata can't be freed.
Link: https://lore.kernel.org/linux-riscv/[email protected]/T/#t
   Signed-off-by: Guo Ren <[email protected]>
   Reported-by: Aurelien Jarno <[email protected]>
   Tested-by: Aurelien Jarno <[email protected]>
   [Palmer: Clean up commit text]
   Signed-off-by: Palmer Dabbelt <[email protected]>

static_obj() fail). When we expand static_obj include INIT_DATA,
we also include INIT_TEXT into usercopy check kernel text:

/* Is this address range in the kernel text area? */
static inline void check_kernel_text_object(const unsigned long ptr,
                                            unsigned long n, bool to_user)
{
        unsigned long textlow = (unsigned long)_stext;
        unsigned long texthigh = (unsigned long)_etext;
        unsigned long textlow_linear, texthigh_linear;

        if (overlaps(ptr, n, textlow, texthigh))
                usercopy_abort("kernel text", NULL, to_user, ptr - textlow, n);

When INIT_TEXT/DATA are freed, new allocation will reuse these
memory and overlaps check will be triggered.

The patch met static_obj and check_kernel_text_object requirements.

Link: 
https://lore.kernel.org/linux-riscv/[email protected]/T/#t
Signed-off-by: Guo Ren <[email protected]>
Reported-by: Aurelien Jarno <[email protected]>
Tested-by: Aurelien Jarno <[email protected]>
Cc: Palmer Dabbelt <[email protected]>
Cc: Atish Patra <[email protected]>
Cc: Andreas Schwab <[email protected]>
---
 arch/riscv/kernel/vmlinux.lds.S | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
index f3586e3..34d00d9 100644
--- a/arch/riscv/kernel/vmlinux.lds.S
+++ b/arch/riscv/kernel/vmlinux.lds.S
@@ -22,13 +22,11 @@ SECTIONS
        /* Beginning of code and text segment */
        . = LOAD_OFFSET;
        _start = .;
-       _stext = .;
        HEAD_TEXT_SECTION
        . = ALIGN(PAGE_SIZE);

        __init_begin = .;
        INIT_TEXT_SECTION(PAGE_SIZE)
-       INIT_DATA_SECTION(16)
        . = ALIGN(8);
        __soc_early_init_table : {
                __soc_early_init_table_start = .;
@@ -55,6 +53,7 @@ SECTIONS
        . = ALIGN(SECTION_ALIGN);
        .text : {
                _text = .;
+               _stext = .;
                TEXT_TEXT
                SCHED_TEXT
                CPUIDLE_TEXT
@@ -67,6 +66,8 @@ SECTIONS
                _etext = .;
        }

+       INIT_DATA_SECTION(16)
+
        /* Start of data section */
        _sdata = .;
        RO_DATA(SECTION_ALIGN)

Reply via email to