From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Hou Tao <houtao1@huawei.com>,
Thomas Gleixner <tglx@linutronix.de>,
syzbot+72aa0161922eba61b50e@syzkaller.appspotmail.com,
xingwei lee <xrivendell7@gmail.com>,
Sohil Mehta <sohil.mehta@intel.com>,
Alexei Starovoitov <ast@kernel.org>,
Sasha Levin <sashal@kernel.org>,
dave.hansen@linux.intel.com, luto@kernel.org,
peterz@infradead.org, mingo@redhat.com, bp@alien8.de,
x86@kernel.org, bpf@vger.kernel.org
Subject: [PATCH AUTOSEL 6.1 06/12] x86/mm: Disallow vsyscall page read for copy_from_kernel_nofault()
Date: Thu, 29 Feb 2024 15:40:28 -0500 [thread overview]
Message-ID: <20240229204039.2861519-6-sashal@kernel.org> (raw)
In-Reply-To: <20240229204039.2861519-1-sashal@kernel.org>
From: Hou Tao <houtao1@huawei.com>
[ Upstream commit 32019c659ecfe1d92e3bf9fcdfbb11a7c70acd58 ]
When trying to use copy_from_kernel_nofault() to read vsyscall page
through a bpf program, the following oops was reported:
BUG: unable to handle page fault for address: ffffffffff600000
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
PGD 3231067 P4D 3231067 PUD 3233067 PMD 3235067 PTE 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 1 PID: 20390 Comm: test_progs ...... 6.7.0+ #58
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) ......
RIP: 0010:copy_from_kernel_nofault+0x6f/0x110
......
Call Trace:
<TASK>
? copy_from_kernel_nofault+0x6f/0x110
bpf_probe_read_kernel+0x1d/0x50
bpf_prog_2061065e56845f08_do_probe_read+0x51/0x8d
trace_call_bpf+0xc5/0x1c0
perf_call_bpf_enter.isra.0+0x69/0xb0
perf_syscall_enter+0x13e/0x200
syscall_trace_enter+0x188/0x1c0
do_syscall_64+0xb5/0xe0
entry_SYSCALL_64_after_hwframe+0x6e/0x76
</TASK>
......
---[ end trace 0000000000000000 ]---
The oops is triggered when:
1) A bpf program uses bpf_probe_read_kernel() to read from the vsyscall
page and invokes copy_from_kernel_nofault() which in turn calls
__get_user_asm().
2) Because the vsyscall page address is not readable from kernel space,
a page fault exception is triggered accordingly.
3) handle_page_fault() considers the vsyscall page address as a user
space address instead of a kernel space address. This results in the
fix-up setup by bpf not being applied and a page_fault_oops() is invoked
due to SMAP.
Considering handle_page_fault() has already considered the vsyscall page
address as a userspace address, fix the problem by disallowing vsyscall
page read for copy_from_kernel_nofault().
Originally-by: Thomas Gleixner <tglx@linutronix.de>
Reported-by: syzbot+72aa0161922eba61b50e@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/bpf/CAG48ez06TZft=ATH1qh2c5mpS5BT8UakwNkzi6nvK5_djC-4Nw@mail.gmail.com
Reported-by: xingwei lee <xrivendell7@gmail.com>
Closes: https://lore.kernel.org/bpf/CABOYnLynjBoFZOf3Z4BhaZkc5hx_kHfsjiW+UWLoB=w33LvScw@mail.gmail.com
Signed-off-by: Hou Tao <houtao1@huawei.com>
Reviewed-by: Sohil Mehta <sohil.mehta@intel.com>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240202103935.3154011-3-houtao@huaweicloud.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/mm/maccess.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/x86/mm/maccess.c b/arch/x86/mm/maccess.c
index 6993f026adec9..42115ac079cfe 100644
--- a/arch/x86/mm/maccess.c
+++ b/arch/x86/mm/maccess.c
@@ -3,6 +3,8 @@
#include <linux/uaccess.h>
#include <linux/kernel.h>
+#include <asm/vsyscall.h>
+
#ifdef CONFIG_X86_64
bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
{
@@ -15,6 +17,14 @@ bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
if (vaddr < TASK_SIZE_MAX + PAGE_SIZE)
return false;
+ /*
+ * Reading from the vsyscall page may cause an unhandled fault in
+ * certain cases. Though it is at an address above TASK_SIZE_MAX, it is
+ * usually considered as a user space address.
+ */
+ if (is_vsyscall_vaddr(vaddr))
+ return false;
+
/*
* Allow everything during early boot before 'x86_virt_bits'
* is initialized. Needed for instruction decoding in early
--
2.43.0
next prev parent reply other threads:[~2024-02-29 20:40 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-29 20:40 [PATCH AUTOSEL 6.1 01/12] soc: microchip: Fix POLARFIRE_SOC_SYS_CTRL input prompt Sasha Levin
2024-02-29 20:40 ` [PATCH AUTOSEL 6.1 02/12] RDMA/mlx5: Fix fortify source warning while accessing Eth segment Sasha Levin
2024-02-29 20:40 ` [PATCH AUTOSEL 6.1 03/12] RDMA/mlx5: Relax DEVX access upon modify commands Sasha Levin
2024-02-29 20:40 ` [PATCH AUTOSEL 6.1 04/12] riscv: dts: sifive: add missing #interrupt-cells to pmic Sasha Levin
2024-02-29 20:40 ` Sasha Levin
2024-02-29 20:40 ` [PATCH AUTOSEL 6.1 05/12] x86/mm: Move is_vsyscall_vaddr() into asm/vsyscall.h Sasha Levin
2024-02-29 20:40 ` Sasha Levin [this message]
2024-02-29 20:40 ` [PATCH AUTOSEL 6.1 07/12] net/iucv: fix the allocation size of iucv_path_table array Sasha Levin
2024-02-29 20:40 ` [PATCH AUTOSEL 6.1 08/12] parisc/ftrace: add missing CONFIG_DYNAMIC_FTRACE check Sasha Levin
2024-02-29 20:40 ` [PATCH AUTOSEL 6.1 09/12] block: sed-opal: handle empty atoms when parsing response Sasha Levin
2024-02-29 20:40 ` [PATCH AUTOSEL 6.1 10/12] enic: Avoid false positive under FORTIFY_SOURCE Sasha Levin
2024-03-11 21:03 ` Pavel Machek
2024-03-18 12:50 ` Sasha Levin
2024-02-29 20:40 ` [PATCH AUTOSEL 6.1 11/12] dm-verity, dm-crypt: align "struct bvec_iter" correctly Sasha Levin
2024-02-29 20:40 ` [PATCH AUTOSEL 6.1 12/12] arm64: dts: Fix dtc interrupt_provider warnings Sasha Levin
2024-02-29 20:40 ` Sasha Levin
2024-03-11 21:04 ` Pavel Machek
2024-03-11 21:04 ` Pavel Machek
2024-03-12 8:20 ` Geert Uytterhoeven
2024-03-12 8:20 ` Geert Uytterhoeven
2024-03-12 8:38 ` Pavel Machek
2024-03-12 8:38 ` Pavel Machek
2024-03-12 8:43 ` Geert Uytterhoeven
2024-03-12 8:43 ` Geert Uytterhoeven
2024-03-12 9:12 ` AngeloGioacchino Del Regno
2024-03-12 9:12 ` AngeloGioacchino Del Regno
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=20240229204039.2861519-6-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=ast@kernel.org \
--cc=bp@alien8.de \
--cc=bpf@vger.kernel.org \
--cc=dave.hansen@linux.intel.com \
--cc=houtao1@huawei.com \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=sohil.mehta@intel.com \
--cc=stable@vger.kernel.org \
--cc=syzbot+72aa0161922eba61b50e@syzkaller.appspotmail.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
--cc=xrivendell7@gmail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.