Received: by 2002:ab2:60d1:0:b0:1f7:5705:b850 with SMTP id i17csp214207lqm; Tue, 30 Apr 2024 19:27:31 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCWsHgS42kVorvLqKpo0tMNpYolfNLIqI8yOomdc9Ollf+t6igWI/ufEmfTI0Yv7Y+HFFStUDfz5+F3du27bJZ2uuAJ5P71UKK933el6Dw== X-Google-Smtp-Source: AGHT+IFwbAU9KARw85B6PBrgYv5xNKqrbwLeKL4vV4kXVC+IEYoNzNe10YBZWvrRa+PkmPGIA1eM X-Received: by 2002:ac8:5905:0:b0:43a:bee9:ebc with SMTP id 5-20020ac85905000000b0043abee90ebcmr2641291qty.19.1714530451231; Tue, 30 Apr 2024 19:27:31 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1714530451; cv=pass; d=google.com; s=arc-20160816; b=oyBHEO/4oE+pH2Bdgff2RDRK211J1tKbpItoUsiW6QMczai80GDhQsuIbQHykNMJrb KyD8Wkf/4RhDdDBXxgv5L+E2UQ1lUV72TpDuTzRaRIfa4S/SZuHPLBC9JeoHf/+n1NJf B1ycwydEfi9UPVZ/FIXcMn+Gd6eR42SN7lnks4v72Uk1DqLKel9QoDN7hY+FNhOuUEi8 7SfS7BpQk41m9D3CuUaoNPvqwRtvmWgH7xmeIuT1MANw0ANfwVdLROqj/0WA8sX0YXXW PqBD7RcWJ6/6ur/FrS7wr2Wz9rlwv1LO2Ai7tubUwye3BNjyRbWEcKM6t3S8/sPn344M CIxw== 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=7fjKpIVCrG16rPBfMRo3DetkYGl8dg4mfjzHivxICDc=; fh=U83BEJ+KyYk5KsrcnFDOAIuexg3bZ65c7BPOZRm1VaE=; b=yoQ83IBU5M7u9kOFpnNKx2egIbnE0PE/x/ipoEW2/xfdHP5WzH7iC+GooYl0ELv1RQ 2rfMmfvdBtCUsNz9qIEn5GtPb4JWJcR2M28G+hVuGmw6bxaGTWcrLkz0clNls/BmkJAc aVWHSWH6UtRjEisvyCjt3gvd6FO0g56CY5ZtHEpUrYBCYngZPQ62kUEtOjMFvUjf2Z5w 8zOHs78sYEaUMesPdEjkDkncPqKLYwL6uDoG4x2RQhifGkCTPZ8Sn3mbbjUkTmtmEl8F 9T3S81QUyyGuCXUVWKzCsunbTgMjIkb2Cf0tcPIgJHZ8MiabZqw8lsQ0uvzq1hS7afms 8Njg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=l8sES53+; 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-164876-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-164876-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. [147.75.199.223]) by mx.google.com with ESMTPS id g4-20020ac87f44000000b0043b000870bbsi4715226qtk.217.2024.04.30.19.27.31 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Apr 2024 19:27:31 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-164876-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=l8sES53+; 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-164876-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-164876-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 DDC4E1C22430 for ; Wed, 1 May 2024 02:27:30 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 7956612E4D; Wed, 1 May 2024 02:27:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="l8sES53+" 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 C497510A03; Wed, 1 May 2024 02:27:22 +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=1714530444; cv=none; b=igSlpwyehDVbNubQl0KA+QAbjtqNubhIld2Rpxdgz1WAqYjqp7v5NIdZpl/HICJiE6lTITAbu5wmtp12tzb1CsKQAb/N5YFoRLJOg64eeRxEjdNAdje2pqIPL9ukhtTdXD4HdkL/+SQtyohGQW/qHpbn8tlAfcun6/gfd1i+Tbk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714530444; c=relaxed/simple; bh=FRsGkPHSoydqvdyIJ0MAzb+gXp7P2C0gjeuRsN5UjrM=; h=From:To:CC:Subject:Date:Message-ID:MIME-Version:Content-Type; b=OQgxlgfoFxPwHUR7OlDp6g8DkSMNIfVF8cpbRVsnVMgxD0cdyUXOYchqE8sb33GabSFyYL9q4TFf8GHbJ067iKDUvAml2v3gL5YhLXKou2mw3K/LPvuoio6FIUP3kefH4oZnG9ORnktTgk1DPnQJnP+r5u0AoKXLPg7q/gzAYW8= 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=l8sES53+; 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 (m0279866.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 4410ro4A010509; Wed, 1 May 2024 02:27:19 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=7fjKpIV CrG16rPBfMRo3DetkYGl8dg4mfjzHivxICDc=; b=l8sES53+3JznQl8ZRRyH/mU BQiTnakv3qSEZ/RU0aOiA9GrGT2eox2L8ROC/rEeCpwCeJ2dBJ9cWl0lithwkIS9 N5be88KxcjQHPYWu/3+AbttBUZ50sOFFlGdAY+HMtYh+j5/rff5vAwWhkONwlbBs sHwuRcrt3yPCLyYvyFN+O0iOj93OPsYu4gst10ndZCWH2Ti+RgugowYT6Tf8SDrp WMgI99+t5LcrNwvGZ8NyfdcR8cf9vn2Vh7WJv3Xi6BKX0j9Kd3RKadgGwuPIpOxf aZE9UdiJo1wvTpEmtEVXCv6LcFqW+QhDZwKvo8Ulo7wSphDEmU0+AGFnuYDtNMQ= = Received: from nasanppmta01.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3xtv1htg3e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 01 May 2024 02:27:19 +0000 (GMT) Received: from nasanex01c.na.qualcomm.com (nasanex01c.na.qualcomm.com [10.45.79.139]) by NASANPPMTA01.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 4412RIKV007727 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 1 May 2024 02:27:18 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; Tue, 30 Apr 2024 19:27:16 -0700 From: Zhongqiu Han To: , , CC: , , Subject: [PATCH] gpiolib: cdev: Fix use after free in lineinfo_changed_notify Date: Wed, 1 May 2024 10:26:12 +0800 Message-ID: <20240501022612.1787143-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: nasanex01b.na.qualcomm.com (10.46.141.250) 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: 1cbCZhYTMPGdyBrm88lZGUsnNNseqoMn X-Proofpoint-ORIG-GUID: 1cbCZhYTMPGdyBrm88lZGUsnNNseqoMn 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-01_02,2024-04-30_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxlogscore=980 adultscore=0 spamscore=0 clxscore=1011 suspectscore=0 impostorscore=0 phishscore=0 bulkscore=0 mlxscore=0 malwarescore=0 lowpriorityscore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2404010003 definitions=main-2405010016 The use-after-free issue occurs when userspace closes the GPIO chip device file (e.g., "/dev/gpiochip0") by invoking gpio_chrdev_release(), while one of its GPIO lines is simultaneously being released. In a stress test scenario, stress-ng tool starts multi stress-ng-dev threads to continuously open and close device file in the /dev, the use-after-free issue will occur with a low reproducibility. Here is the typical stack when issue happened: BUG: KASAN: slab-use-after-free in lineinfo_changed_notify+0x84/0x1bc Read of size 8 at addr ffffff803c06e840 by task stress-ng-dev/5437 Call trace: dump_backtrace show_stack dump_stack_lvl print_report kasan_report __asan_load8 lineinfo_changed_notify notifier_call_chain blocking_notifier_call_chain gpiod_free_commit gpiod_free gpio_free st54spi_gpio_dev_release __fput __fput_sync __arm64_sys_close invoke_syscall el0_svc_common do_el0_svc el0_svc el0t_64_sync_handler el0t_64_sync Allocated by task 5425: kasan_set_track kasan_save_alloc_info __kasan_kmalloc __kmalloc bitmap_zalloc gpio_chrdev_open chrdev_open do_dentry_open vfs_open path_openat do_filp_open do_sys_openat2 __arm64_sys_openat invoke_syscall el0_svc_common do_el0_svc el0_svc el0t_64_sync_handler el0t_64_sync Freed by task 5425: kasan_set_track kasan_save_free_info ____kasan_slab_free __kasan_slab_free slab_free_freelist_hook __kmem_cache_free kfree bitmap_free gpio_chrdev_release __fput __fput_sync __arm64_sys_close invoke_syscall el0_svc_common do_el0_svc el0_svc el0t_64_sync_handler el0t_64_sync The use-after-free issue occurs as follows: watched_lines is freed by bitmap_free(), but the lineinfo_changed_nb notifier chain cannot be successfully unregistered due to waiting write rwsem when closing the GPIO chip device file. 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. [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 To fix this issue, call the bitmap_free() function after successfully unregistering the notifier chain. This prevents lineinfo_changed_notify() from being called, thus avoiding the use-after-free race condition. Fixes: 51c1064e82e7 ("gpiolib: add new ioctl() for monitoring changes in line info") Signed-off-by: Zhongqiu Han --- 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