From nobody Sun Apr 19 10:44:24 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C5636C433EF for ; Sat, 2 Jul 2022 05:43:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231350AbiGBFnl (ORCPT ); Sat, 2 Jul 2022 01:43:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42122 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229446AbiGBFnj (ORCPT ); Sat, 2 Jul 2022 01:43:39 -0400 Received: from mail4.tencent.com (mail12.tencent.com [61.241.47.121]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E936212744 for ; Fri, 1 Jul 2022 22:43:23 -0700 (PDT) Received: from EX-SZ018.tencent.com (unknown [10.28.6.39]) by mail4.tencent.com (Postfix) with ESMTP id 76FD064CFB; Sat, 2 Jul 2022 13:43:19 +0800 (CST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tencent.com; s=s202002; t=1656740599; bh=Qr1/VoldSoDRmeq9sb7whdv1p5Xm3JSDTtVTXlfu2wA=; h=From:To:Subject:Date; b=dd2DpIaVXjNaEl3ZYK+8DPY+ZOAlwctIM1i99mpAEQI8ml4MIZfBObzMNptK56B/i IOajTHVVOM7JIlfpxiGADPUwd/RMAI9geqepMCM0BZG0xf7mM0Qi12LVZStzdb5Dod 8uUIpaj1kUhxnVj2Lx5IG+EHbIL8MBRAIpjQcGiM= Received: from EX-SZ007.tencent.com (10.28.6.31) by EX-SZ018.tencent.com (10.28.6.39) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Sat, 2 Jul 2022 13:43:19 +0800 Received: from EX-SZ006.tencent.com (10.28.6.30) by EX-SZ007.tencent.com (10.28.6.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Sat, 2 Jul 2022 13:43:19 +0800 Received: from EX-SZ006.tencent.com ([fe80::a84e:872e:7c90:2930]) by EX-SZ006.tencent.com ([fe80::a84e:872e:7c90:2930%2]) with mapi id 15.01.2242.008; Sat, 2 Jul 2022 13:43:19 +0800 From: =?gb2312?B?aGFpYmluemhhbmco1cW6o7HzKQ==?= To: Catalin Marinas , Will Deacon , Ard Biesheuvel , Martin Ma , "linux-arm-kernel@lists.infradead.org" , "linux-kernel@vger.kernel.org" , "hewenliang4@huawei.com" Subject: [PATCH V2] arm64: fix oops in concurrently setting insn_emulation sysctls Thread-Topic: [PATCH V2] arm64: fix oops in concurrently setting insn_emulation sysctls Thread-Index: AQHYjdaixOX+L2cpukiGMcsED+5ecw== Date: Sat, 2 Jul 2022 05:43:19 +0000 Message-ID: <9A004C03-250B-46C5-BF39-782D7551B00E@tencent.com> Accept-Language: zh-CN, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.99.17.209] Content-ID: <8B8ED50DE69E9742AA272A0F4141C2C9@tencent.com> Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" How to reproduce: launch two shell executions: #!/bin/bash while [ 1 ]; do echo 1 > /proc/sys/abi/swp done Oops info: Unable to handle kernel NULL pointer dereference at virtual address 000= 0000000000010 Internal error: Oops: 96000006 [#1] SMP Call trace: update_insn_emulation_mode+0xc0/0x148 emulation_proc_handler+0x64/0xb8 proc_sys_call_handler+0x9c/0xf8 proc_sys_write+0x18/0x20 __vfs_write+0x20/0x48 vfs_write+0xe4/0x1d0 ksys_write+0x70/0xf8 __arm64_sys_write+0x20/0x28 el0_svc_common.constprop.0+0x7c/0x1c0 el0_svc_handler+0x2c/0xa0 el0_svc+0x8/0x200 emulation_proc_handler changes table->data for proc_dointvec_minmax and so it isn't allowed to reenter before restoring table->data, which isn't right now. To fix this issue, keep the table->data as &insn->current_mode and use container_of() to retrieve the insn pointer. Another mutex is used to protect against the current_mode update but not for retrieving insn_emulation as table->data is no longer changing. Signed-off-by: hewenliang Signed-off-by: Haibin Zhang Reviewed-by: Catalin Marinas --- arch/arm64/kernel/armv8_deprecated.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8= _deprecated.c index 6875a16b09d2..fb0e7c7b2e20 100644 --- a/arch/arm64/kernel/armv8_deprecated.c +++ b/arch/arm64/kernel/armv8_deprecated.c @@ -59,6 +59,7 @@ struct insn_emulation { static LIST_HEAD(insn_emulation); static int nr_insn_emulated __initdata; static DEFINE_RAW_SPINLOCK(insn_emulation_lock); +static DEFINE_MUTEX(insn_emulation_mutex); =20 static void register_emulation_hooks(struct insn_emulation_ops *ops) { @@ -207,10 +208,10 @@ static int emulation_proc_handler(struct ctl_table *t= able, int write, loff_t *ppos) { int ret =3D 0; - struct insn_emulation *insn =3D (struct insn_emulation *) table->data; + struct insn_emulation *insn =3D container_of(table->data, struct insn_emu= lation, current_mode); enum insn_emulation_mode prev_mode =3D insn->current_mode; =20 - table->data =3D &insn->current_mode; + mutex_lock(&insn_emulation_mutex); ret =3D proc_dointvec_minmax(table, write, buffer, lenp, ppos); =20 if (ret || !write || prev_mode =3D=3D insn->current_mode) @@ -223,7 +224,7 @@ static int emulation_proc_handler(struct ctl_table *tab= le, int write, update_insn_emulation_mode(insn, INSN_UNDEF); } ret: - table->data =3D insn; + mutex_unlock(&insn_emulation_mutex); return ret; } =20 @@ -247,7 +248,7 @@ static void __init register_insn_emulation_sysctl(void) sysctl->maxlen =3D sizeof(int); =20 sysctl->procname =3D insn->ops->name; - sysctl->data =3D insn; + sysctl->data =3D &insn->current_mode; sysctl->extra1 =3D &insn->min; sysctl->extra2 =3D &insn->max; sysctl->proc_handler =3D emulation_proc_handler; --=20 2.34.1