From: wanglinhui <wanglinhui@huawei.com>
To: "Russell King (Oracle)" <linux@armlinux.org.uk>
Cc: Andrew Morton <akpm@linux-foundation.org>,
Kees Cook <kees@kernel.org>,
Kefeng Wang <wangkefeng.wang@huawei.com>,
Suren Baghdasaryan <surenb@google.com>,
Linus Walleij <linus.walleij@linaro.org>,
Catalin Marinas <catalin.marinas@arm.com>,
<linux-arm-kernel@lists.infradead.org>,
<linux-kernel@vger.kernel.org>, <wangfangpeng1@huawei.com>,
<zhangxun38@huawei.com>, <yangzhuohao1@huawei.com>
Subject: Re: [PATCH] ARM: Fix "external abort on non-linefetch" kernel panic caused by userspace
Date: Sat, 6 Jul 2024 18:21:36 +0800 [thread overview]
Message-ID: <2eda33ba-b0ee-498c-979a-e35ae1f41ba4@huawei.com> (raw)
In-Reply-To: <ZojxN5iOHhGAt3A5@shell.armlinux.org.uk>
The original problem is that the device address is mapped through UIO.
Then something unexpected happens that causes an unaligned access to the
device address.
For simplicity, I used /dev/mem for testing.
Yes, it's a privileged operation. But I don't think it should crash the
kernel.
It would be more better to have the process exit on an exception signal.
What do you think?
And the coredump file can be obtained when the process exits.
In this way, more information can be obtained to fix the bug.
在 2024/7/6 15:24, Russell King (Oracle) 写道:
> On Sat, Jul 06, 2024 at 11:20:05AM +0800, wanglinhui wrote:
>> 0x16800000 is a peripheral physical address that supports only
>> 4-byte-aligned access.
>>
>> Use /dev/mem to enable the user space to access 0x16800000. Then userspace
>> unexpectedly tried to read four bytes from 0x16800001 (actually access
>> its virtual address), which caused the kernel to trigger an
>> "external abort on non-linefetch" panic:
>>
>> Unhandled fault: external abort on non-linefetch (0x1018) at 0x0100129b
>> [0100129b] *pgd=85038831, *pte=16801703, *ppte=16801e33
>> Internal error: : 1018 [#1] SMP ARM
>> ...
>> CPU: 2 PID: xxxx Comm: xxxx Tainted: G O 5.10.0 #1
>> Hardware name: Hisilicon A9
>> PC is at do_alignment_ldrstr+0xb8/0x100
>> LR is at 0xc1f203fc
>> psr: 200f0313
>> sp : c7081ed4 ip : 00000008 fp : 00000011
>> r10: b42250c8 r9 : c7081f0c r8 : c7081fb0
>> r7 : 0100129b r6 : 00000004 r5 : 00000000 r4 : e5908000
>> r3 : 00000000 r2 : c7081f0c r1 : 200f0210 r0 : 0100129b
>> Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
>> Control: 1ac5387d Table: 82c3c04a DAC: 55555555
>> Process LcnNCoreTask (pid: 4049, stack limit = 0x14066b0e)
>> Call trace:
>> do_alignment_ldrstr
>> --do_alignment
>> ----do_DataAbort
>> ------__dabt_usr
>>
>> It triggers a data abort exception twice. The first time occurs when
>> an unaligned address is accessed in user mode. The second time occurs
>> when the peripheral address is actually accessed in kernel mode,
>> and it crashes the kernel. However, the code location for the second
>> data abort is as follows:
>>
>> ```
>> #define __get8_unaligned_check(ins, val, addr, err) \
>> __asm__(\
>> ARM("1: "ins" %1, [%2], #1\n") \ <-- Second data abort is triggered here
>> THUMB("1: "ins" %1, [%2]\n") \
>> THUMB(" add %2, %2, #1\n") \
>> "2:\n" \
>> " .pushsection .text.fixup,\"ax\"\n" \
>> ```
>>
>> It is an exception table entry that can be fixed up.
>>
>> There is another test that indicates that
>> "external abort on non-linefetch" needs to be fixed up.
>>
>> Similarly, use /dev/mem to map 0x16800000 to the user space.
>> Pass 0x16800001 (actually passes its virtual address) to the
>> kernel via the write() system call and write 1 byte.
>> It also causes the kernel to trigger an
>> "external abort on non-linefetch" panic:
>>
>> Unhandled fault: external abort on non-linefetch (0x1018) at 0xb6f95000
>> [b6f95000] *pgd=83fb6831, *pte=16800783, *ppte=16800e33
>> Internal error: : 1018 [#1] SMP ARM
>> ...
>> CPU: 1 PID: xxxx Comm: xxxx Tainted: G O 5.10.0 #1
>> Hardware name: Hisilicon A9
>> PC is at __get_user_1+0x14/0x20
>> LR is at iov_iter_fault_in_readable+0x7c/0x198
>> psr: 800b0213
>> sp : c195be18 ip : 00000001 fp : c35a2478
>> r10: c06b5260 r9 : 00000000 r8 : c356fee0
>> r7 : ffffe000 r6 : b6f95000 r5 : 00000001 r4 : c195bf10
>> r3 : b6f95000 r2 : f7f95000 r1 : beffffff r0 : b6f95000
>> Call trace looks like:
>> __get_user_1
>> --iov_iter_fault_in_readable
>> ----generic_perform_write
>> ------__generic_file_write_iter
>> --------generic_file_write_iter
>>
>> The location of the instruction that triggers the data abort
>> is as follows:
>> ```
>> ENTRY(__get_user_1)
>> check_uaccess r0, 1, r1, r2, __get_user_bad
>> 1: TUSER(ldrb) r2, [r0] <-- Data abort is triggered here
>> mov r0, #0
>> ret lr
>> ENDPROC(__get_user_1)
>> _ASM_NOKPROBE(__get_user_1)
>> ```
>> It is also an exception table entry that can be fixed up.
>>
>> Address passed in from user space should not crash the kernel.
>> Therefore, fixup_exception() is added to fix up such exception.
> NAK because:
>
> 1) you're using /dev/mem which requires privileges - you're holding
> the gun, pointing it at your foot.
>
> 2) you're performing an unaligned access to a device which is
> architecturally not permitted - you're pulling the trigger.
>
> It's not surprising that the result is you've shot yourself in the
> foot!
>
> If you access /dev/mem, then you need to know what you're doing and
> you must access it according to the requirements of the memory space
> you are accessing, otherwise undefined behaviour will occur - not
> only architecturally, but also by the kernel.
>
prev parent reply other threads:[~2024-07-06 10:22 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-06 3:20 [PATCH] ARM: Fix "external abort on non-linefetch" kernel panic caused by userspace wanglinhui
2024-07-06 7:24 ` Russell King (Oracle)
2024-07-06 10:21 ` wanglinhui [this message]
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=2eda33ba-b0ee-498c-979a-e35ae1f41ba4@huawei.com \
--to=wanglinhui@huawei.com \
--cc=akpm@linux-foundation.org \
--cc=catalin.marinas@arm.com \
--cc=kees@kernel.org \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=surenb@google.com \
--cc=wangfangpeng1@huawei.com \
--cc=wangkefeng.wang@huawei.com \
--cc=yangzhuohao1@huawei.com \
--cc=zhangxun38@huawei.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).