From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7B3F3C41604 for ; Tue, 6 Oct 2020 05:26:19 +0000 (UTC) Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 61EC620870 for ; Tue, 6 Oct 2020 05:26:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="CKMzlPc2" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 61EC620870 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.ibm.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=linuxppc-dev-bounces+linuxppc-dev=archiver.kernel.org@lists.ozlabs.org Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4C55Y35drLzDqKL for ; Tue, 6 Oct 2020 16:26:15 +1100 (AEDT) Received: from ozlabs.org (bilbo.ozlabs.org [IPv6:2401:3900:2:1::2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4C55W4744PzDqHh for ; Tue, 6 Oct 2020 16:24:32 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=CKMzlPc2; dkim-atps=neutral Received: from ozlabs.org (bilbo.ozlabs.org [IPv6:2401:3900:2:1::2]) by bilbo.ozlabs.org (Postfix) with ESMTP id 4C55W45vV0z8tWb for ; Tue, 6 Oct 2020 16:24:32 +1100 (AEDT) Received: by ozlabs.org (Postfix) id 4C55W45N0jz9sSG; Tue, 6 Oct 2020 16:24:32 +1100 (AEDT) Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=linux.ibm.com (client-ip=148.163.156.1; helo=mx0a-001b2d01.pphosted.com; envelope-from=mahesh@linux.ibm.com; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=CKMzlPc2; dkim-atps=neutral Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C55W42502z9s1t for ; Tue, 6 Oct 2020 16:24:32 +1100 (AEDT) Received: from pps.filterd (m0098404.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 09651dVl188108 for ; Tue, 6 Oct 2020 01:24:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=subject : from : to : cc : date : message-id : mime-version : content-type : content-transfer-encoding; s=pp1; bh=73hSblmBAeh+P5TYguzSurlyJN1SnOQdHPaOiZmRTdU=; b=CKMzlPc2In8YuX8CcTWHhzNSnToDo/1DUj1QVxrAZnlAfE6NNXx12bLgUjrCwgY1feKd u6pA+NPw5+uUVt0+dwF1T92iZUd7UJQMx3rPkeddl//U+Dcr26AwWI/Ce8uekZTV0sYb ZbFq6XXhJ5i6/jFgwbZCL4294IYKxlpGrrMV1eKrNITv9H5mCT46fCrqIYQpZkjTX8zt BUhBUE2RIDT9p6q4FM2kOF+iKwyUuj2mOdmxNZBVN3siGMHQACy4ux49HgQYPV3eARE0 iohOvpFEMXj+NVAJL/rmw8jzNW9VgyIk1bKgIj+UvI7w9+e5EyagimXevuxV8pzXzFct rg== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 340j2m8j41-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 06 Oct 2020 01:24:30 -0400 Received: from m0098404.ppops.net (m0098404.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 09653iF0004560 for ; Tue, 6 Oct 2020 01:24:29 -0400 Received: from ppma04ams.nl.ibm.com (63.31.33a9.ip4.static.sl-reverse.com [169.51.49.99]) by mx0a-001b2d01.pphosted.com with ESMTP id 340j2m8j3e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 06 Oct 2020 01:24:29 -0400 Received: from pps.filterd (ppma04ams.nl.ibm.com [127.0.0.1]) by ppma04ams.nl.ibm.com (8.16.0.42/8.16.0.42) with SMTP id 0965I9Fn012291; Tue, 6 Oct 2020 05:24:27 GMT Received: from b06cxnps4075.portsmouth.uk.ibm.com (d06relay12.portsmouth.uk.ibm.com [9.149.109.197]) by ppma04ams.nl.ibm.com with ESMTP id 33xgx82v5c-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 06 Oct 2020 05:24:27 +0000 Received: from d06av26.portsmouth.uk.ibm.com (d06av26.portsmouth.uk.ibm.com [9.149.105.62]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 0965OOGW25231620 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 6 Oct 2020 05:24:24 GMT Received: from d06av26.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 56BCFAE05D; Tue, 6 Oct 2020 05:24:24 +0000 (GMT) Received: from d06av26.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9851CAE04D; Tue, 6 Oct 2020 05:24:23 +0000 (GMT) Received: from [192.168.0.63] (unknown [9.85.71.114]) by d06av26.portsmouth.uk.ibm.com (Postfix) with ESMTP; Tue, 6 Oct 2020 05:24:23 +0000 (GMT) Subject: [PATCH v3] powernv/elog: Fix the race while processing OPAL error log event. From: Mahesh Salgaonkar To: linuxppc-dev Date: Tue, 06 Oct 2020 10:54:22 +0530 Message-ID: <160196186190.1803505.7293993132725212105.stgit@jupiter> User-Agent: StGit/0.21 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.235, 18.0.687 definitions=2020-10-06_01:2020-10-05, 2020-10-06 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 bulkscore=0 mlxscore=0 mlxlogscore=999 spamscore=0 lowpriorityscore=0 phishscore=0 suspectscore=2 priorityscore=1501 malwarescore=0 clxscore=1015 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2006250000 definitions=main-2010060025 X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Aneesh Kumar K.V" , Oliver O'Halloran , Vasant Hegde Errors-To: linuxppc-dev-bounces+linuxppc-dev=archiver.kernel.org@lists.ozlabs.org Sender: "Linuxppc-dev" Every error log reported by OPAL is exported to userspace through a sysfs interface and notified using kobject_uevent(). The userspace daemon (opal_errd) then reads the error log and acknowledges it error log is saved safely to disk. Once acknowledged the kernel removes the respective sysfs file entry causing respective resources getting released including kobject. However there are chances where user daemon may already be scanning elog entries while new sysfs elog entry is being created by kernel. User daemon may read this new entry and ack it even before kernel can notify userspace about it through kobject_uevent() call. If that happens then we have a potential race between elog_ack_store->kobject_put() and kobject_uevent which can lead to use-after-free issue of a kernfs object resulting into a kernel crash. This patch fixes this race by protecting a sysfs file creation/notification by holding an additional reference count on kobject until we safely send kobject_uevent(). The function create_elog_obj() returns the elog object which if used by caller function will end up in use-after-free problem again. However, the return value of create_elog_obj() function isn't being used today and there is need as well. Hence change it to return void to make this fix complete. Fixes: 774fea1a38c6 ("powerpc/powernv: Read OPAL error log and export it through sysfs") Cc: # v3.15+ Reported-by: Oliver O'Halloran Signed-off-by: Mahesh Salgaonkar Signed-off-by: Aneesh Kumar K.V Reviewed-by: Oliver O'Halloran Reviewed-by: Vasant Hegde --- Change in v3: - Change create_elog_obj function signature to return void. Change in v2: - Instead of mutex and use extra reference count on kobject to avoid the race. --- arch/powerpc/platforms/powernv/opal-elog.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c index 62ef7ad995da..e61cbf08e17e 100644 --- a/arch/powerpc/platforms/powernv/opal-elog.c +++ b/arch/powerpc/platforms/powernv/opal-elog.c @@ -179,14 +179,14 @@ static ssize_t raw_attr_read(struct file *filep, struct kobject *kobj, return count; } -static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type) +static void create_elog_obj(uint64_t id, size_t size, uint64_t type) { struct elog_obj *elog; int rc; elog = kzalloc(sizeof(*elog), GFP_KERNEL); if (!elog) - return NULL; + return; elog->kobj.kset = elog_kset; @@ -219,18 +219,33 @@ static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type) rc = kobject_add(&elog->kobj, NULL, "0x%llx", id); if (rc) { kobject_put(&elog->kobj); - return NULL; + return; } + /* + * As soon as sysfs file for this elog is created/activated there is + * chance opal_errd daemon might read and acknowledge this elog before + * kobject_uevent() is called. If that happens then we have a potential + * race between elog_ack_store->kobject_put() and kobject_uevent which + * leads to use-after-free issue of a kernfs object resulting into + * kernel crash. To avoid this race take an additional reference count + * on kobject until we safely send kobject_uevent(). + */ + + kobject_get(&elog->kobj); /* extra reference count */ rc = sysfs_create_bin_file(&elog->kobj, &elog->raw_attr); if (rc) { kobject_put(&elog->kobj); - return NULL; + /* Drop the extra reference count */ + kobject_put(&elog->kobj); + return; } kobject_uevent(&elog->kobj, KOBJ_ADD); + /* Drop the extra reference count */ + kobject_put(&elog->kobj); - return elog; + return; } static irqreturn_t elog_event(int irq, void *data)