Received: by 2002:ab2:7b86:0:b0:1f7:5705:b850 with SMTP id q6csp907229lqh; Sun, 5 May 2024 07:12:36 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVEr7WtTYpKxiAwd35GW9roiQngWKYVLx+tAx2pjao5CgnA58lwkIKlPcc3/dnKLEM844Kyb350xRd9RnX5bydxoLExTxODfQ5wYGLlMg== X-Google-Smtp-Source: AGHT+IGvkc3Tf3p+TvE1gY9wpdXMRCqBDz7k4NeyUC67YBAlol9Yb8oHc4jnq+DedZZ/XPfJp+RR X-Received: by 2002:aca:2b16:0:b0:3c9:6a26:5734 with SMTP id i22-20020aca2b16000000b003c96a265734mr1653565oik.56.1714918356643; Sun, 05 May 2024 07:12:36 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1714918356; cv=pass; d=google.com; s=arc-20160816; b=fOPTPv3lF0XFmHr6+BoM6boh+vPU9Vwt77SzDu87EmkZC8jE0qcSnJFIH3OCVHedTs I95YtCaG42WhVIWeexNPvtWNbp2uEKhtEwSWzm1roNDGHdnaY0nFrLDgwGoB977/0cer vzTII2EoEULGq9IuGAUizIOK0D/WQeIhUq0BhvcXHt4zrlW8tLz+61rQ5846nh/Y4zvf RhDb9S2Lf7/528etBNtAj1u9hnaZRuciW37uV7HbBx/HcGVXupLUCinfShkcNVR7t8qh OPCz10sehkXWY6nC8+N9hY0yUsNj4+KS+r9MvBAGweUZHny9jzpE9T3icN6X8HPV5agO LDkA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:date:subject:cc:to :from:dkim-signature; bh=S4U/X43YkLegfK1w+BnGBqag1/7RSz2ahKLlAYbFT9A=; fh=U83BEJ+KyYk5KsrcnFDOAIuexg3bZ65c7BPOZRm1VaE=; b=QTtbaZ2WMUCflkn75Ilyv2hEmtK6F+vWXcMz+K8/A1mD0ikAgkr0y9ct52/wiGm+SP Sg8of4g58AsUmam05QOJnKSXKaOqdpjkJXioNxCGBuEEYHuW5+A7QVgpWCq/laki4OHM 8lfNo7olCovoNvqTdvaeWryxhGUhMGopknTGEB1Jh30AbHe2chRV1GB/BUpDM37XArzC CPrAa0fUDk3fDteiZ24EpaY2/1oNf70quxK8cpEFLyYDM/HgmbizcPyIFueP/eoNzAAP OV4+laq3Nv2iCGsyLGzVZYVmkWsvZyA/rQLP9Ux1YBBQ3vNHXyUHD83O/c0VAgivAEwn BMkw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=nRrcGggf; arc=pass (i=1 spf=pass spfdomain=quicinc.com dkim=pass dkdomain=quicinc.com dmarc=pass fromdomain=quicinc.com); spf=pass (google.com: domain of linux-kernel+bounces-168993-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-168993-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id kd10-20020a056214400a00b0069b6d70816bsi6113500qvb.72.2024.05.05.07.12.36 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 05 May 2024 07:12:36 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-168993-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=nRrcGggf; arc=pass (i=1 spf=pass spfdomain=quicinc.com dkim=pass dkdomain=quicinc.com dmarc=pass fromdomain=quicinc.com); spf=pass (google.com: domain of linux-kernel+bounces-168993-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-168993-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 5F6DC1C208C1 for ; Sun, 5 May 2024 14:12:36 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 892A421364; Sun, 5 May 2024 14:12:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="nRrcGggf" Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BD9B61D555; Sun, 5 May 2024 14:12:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714918349; cv=none; b=gjXOAthkpnEdNaU4+wdH/T2lS/rytRegKdvP5eVHh020l4QQz4m2UBkKGkfsOvBI1yajQu5jo+Kv9Nta88rxK2LyTlX2ZiInfj2xc3I4s5oaASqGDCY17PuPieGD32e2Jmw1kjbQmryJVx2AZEKBreXoHm8gc1oXusHRrzCqji4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714918349; c=relaxed/simple; bh=emzJJ17/aDuuVmSG5B35PG0UAekpHMIWobxhcT3a2g0=; h=From:To:CC:Subject:Date:Message-ID:MIME-Version:Content-Type; b=jc3KsyeY6+kzA3yWhc08QLoZUoHUYskxiuFczC3igXabuf/1ka3lUK9de7IObF6KbBUM0vL1Vfvuvb/hu/X2c8kvjjK8d9IDeDFjzzJFCk+BzfSGfFzPj4bLhau4bpMTQyCEQuSaYeABgP8gCxQfAc6UoqHc4oYav5Eg5TIZuyo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=nRrcGggf; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 445DpbRI021432; Sun, 5 May 2024 14:12:18 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding:content-type; s=qcppdkim1; bh=S4U/X43 YkLegfK1w+BnGBqag1/7RSz2ahKLlAYbFT9A=; b=nRrcGggfGAfkY0vjI88AHaF Nh2sDnKRKjda1Sav/1/Y2MjO84JyRJmxY7D7lpfXl9jFE2JVryIui6lUpWIvcdis bNdxa7FxIm6Z/ZIINQbVO0IG+Au8rEvgHvjQNq05fweDHC9pJHCJqbMgafsQMMP4 D8M8LrbEZZ8NdAD9uQww7rBZjEMKTTMwOzf+fBqJXB2yVeBAbaaK6mgq3kajb7B9 r0d8YhHMGXHYq6Ae/BR8/pIpGsutTTeYaTwupw6ETfyM+LGPsHFVYdVa0auocHSb TzDiXeGpD10LG9fm4uDYBaAC1pSO4dB2yYhJKWj1pU0hvuIBUr8nBWFir+FQjxg= = Received: from nasanppmta03.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3xwaqjhy7d-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 05 May 2024 14:12:17 +0000 (GMT) Received: from nasanex01c.na.qualcomm.com (nasanex01c.na.qualcomm.com [10.45.79.139]) by NASANPPMTA03.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 445ECGCC005048 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 5 May 2024 14:12:16 GMT Received: from zhonhan-gv.qualcomm.com (10.80.80.8) by nasanex01c.na.qualcomm.com (10.45.79.139) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Sun, 5 May 2024 07:12:15 -0700 From: Zhongqiu Han To: , , CC: , , Subject: [PATCH v2] gpiolib: cdev: Fix use after free in lineinfo_changed_notify Date: Sun, 5 May 2024 22:11:56 +0800 Message-ID: <20240505141156.2944912-1-quic_zhonhan@quicinc.com> X-Mailer: git-send-email 2.25.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nasanex01c.na.qualcomm.com (10.45.79.139) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: N_f3MjERCFUfG3OuDXcmE2IpZZai13xr X-Proofpoint-ORIG-GUID: N_f3MjERCFUfG3OuDXcmE2IpZZai13xr X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1011,Hydra:6.0.650,FMLib:17.11.176.26 definitions=2024-05-05_09,2024-05-03_02,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 malwarescore=0 bulkscore=0 phishscore=0 impostorscore=0 suspectscore=0 lowpriorityscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2404010003 definitions=main-2405050064 The use-after-free issue occurs as follows: when the GPIO chip device file is being closed by invoking gpio_chrdev_release(), watched_lines is freed by bitmap_free(), but the unregistration of lineinfo_changed_nb notifier chain failed due to waiting write rwsem. Additionally, one of the GPIO chip's lines is also in the release process and holds the notifier chain's read rwsem. Consequently, a race condition leads to the use-after-free of watched_lines. Here is the typical stack when issue happened: [free] gpio_chrdev_release() --> bitmap_free(cdev->watched_lines) <-- freed --> blocking_notifier_chain_unregister() --> down_write(&nh->rwsem) <-- waiting rwsem --> __down_write_common() --> rwsem_down_write_slowpath() --> schedule_preempt_disabled() --> schedule() [use] st54spi_gpio_dev_release() --> gpio_free() --> gpiod_free() --> gpiod_free_commit() --> gpiod_line_state_notify() --> blocking_notifier_call_chain() --> down_read(&nh->rwsem); <-- held rwsem --> notifier_call_chain() --> lineinfo_changed_notify() --> test_bit(xxxx, cdev->watched_lines) <-- use after free The side effect of the use-after-free issue is that a GPIO line event is being generated for userspace where it shouldn't. However, since the chrdev is being closed, userspace won't have the chance to read that event anyway. To fix the issue, call the bitmap_free() function after the unregistration of lineinfo_changed_nb notifier chain. Fixes: 51c1064e82e7 ("gpiolib: add new ioctl() for monitoring changes in line info") Signed-off-by: Zhongqiu Han --- v1 -> v2: - Drop the excessive stack log from commit message to make it more readable. - Add a note regarding the side effects of the use-after-free on commit message. - Link to v1: https://lore.kernel.org/lkml/20240501022612.1787143-1-quic_zhonhan@quicinc.com/ drivers/gpio/gpiolib-cdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index d09c7d728365..6b3a43e3ba47 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -2799,11 +2799,11 @@ static int gpio_chrdev_release(struct inode *inode, struct file *file) struct gpio_chardev_data *cdev = file->private_data; struct gpio_device *gdev = cdev->gdev; - bitmap_free(cdev->watched_lines); blocking_notifier_chain_unregister(&gdev->device_notifier, &cdev->device_unregistered_nb); blocking_notifier_chain_unregister(&gdev->line_state_notifier, &cdev->lineinfo_changed_nb); + bitmap_free(cdev->watched_lines); gpio_device_put(gdev); kfree(cdev); -- 2.25.1