From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f178.google.com (mail-pl1-f178.google.com [209.85.214.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2D52A39098E for ; Tue, 3 Mar 2026 04:44:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.178 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772513082; cv=none; b=VPawPee763cA+sBRYMJmwx6+Xr8fYUch31ap0QQVRrTzqyXushAbHhVlJPslK3/Mg5isVAERLSPOIsgsoQUDSGpU3MAtDkwdqDpRZDM4ELNcBb9dQnKuHeg6zsD9Q04Lyb5VaPt5s1ytdsc+wffDtNOm7aZAzZu+6Jya+iqaZN8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772513082; c=relaxed/simple; bh=MNANG+0AT6IcgsqUUS5qz4o4QyCNwEbDrogfRjYmYcY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iFi67lDR2BimYIIyTTEXAnTSMRPG2hxJnChOl1/zVKpPcH+NK6uYxFu2GM6lojOYCajTEuc2fVEBTQRsU0uDqNhCa34w7+T4U3i/HcsS3HcaEXMQ9DCmFgtSdpq34jjGJSq8IOFqAjN2kp9U/KFOxSo7xO+pX5LQpoWb1ldkX4Y= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=dZxgrR4X; arc=none smtp.client-ip=209.85.214.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="dZxgrR4X" Received: by mail-pl1-f178.google.com with SMTP id d9443c01a7336-2ae5636ab04so15692145ad.3 for ; Mon, 02 Mar 2026 20:44:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772513080; x=1773117880; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=6LWqfPnYJzFeuZzCdQbWgAY+H5By2f/u+Z1YMUOO9a4=; b=dZxgrR4Xt+2z/aHe1jmDrVR8sg2ZcbQJZ2WvzZkwqetIM65t6ETvFsPwMPlPmcyj4P hJ7vsT2quA4ofDHCPeYEdvgHo+E7WRkhdVs9/dpnbfgj7Qqe0rXTXXMLhg2BsTQl1NBx G2uutPsbv2QAgoYkj0q/lQ4rZhkv42KPgOYqxqYXkcqP0ObYeJCd2tDbrOOChwfEPYgt r4SZhgWCiYOrmvuyLdQLB92GOfIR5LW7rqWpOr5MYikAZno/0DaP8IoiE2c4qJM8bfia RclSpRv8Vzlb3bBdJh/l+kALUfc70v7B204yNIM7jnOMABjELOCXMwd6KVLZZGdc6lzD ZgAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772513080; x=1773117880; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=6LWqfPnYJzFeuZzCdQbWgAY+H5By2f/u+Z1YMUOO9a4=; b=Efz2UJRXfa6L5hJ7Vsoum/RbQQ2Hwvclu6KSjp7f5q5/7ZrlC+L85gryi48AK4RdH3 YEC4vAuiRSAl7NB83Dg6IgDou+izUzV7nyfVuby/Aw1HdWF871SW8xPJr2/fqtaxI+M5 sV9RVFZNNqwQuImb+EQWzZkf5zrsnJy1VKRVbkoqznqkUXeIWuohLEjMnwWT9uxVI3hx +awAbMYWpSLUykNvEdDkZBkzEovgcc31LiO0COa9vGguxpQmAi+UzIFw0+IiCiT1Oz3b AhsCLCXK1YnBbncvfFaLXQQ0uoqOWnHtSi0RrUh0gQCi50tPxFSVoFYgVIOBqkCn6XLl Yc7w== X-Gm-Message-State: AOJu0YzfGP87y2S0HXy6zxZ6WJ7fPJprlJaevQ0bQNzcUhMMouVokdkx dcCrzynZ5PFO7/SS0rFf2hwISVACcJF41bAHKwcK2TY0QRgPRatvHUoRjJ/0iYCq X-Gm-Gg: ATEYQzzra5psM0wA2WZTCQ+Vl8Kn91Ed6qHEZTCbaByCarCA2ldrVN7YQkDDie+qFll 6UL3J0JEFByIIzgrogTA/nTOk9Unuv7cLORIk9FtV78O9DN+E+Cq6/xUNinw4oOA0HPd1aCdU7F bZSuJ0SZ5VBxIQrx9RLgGlTVuAk8TGT4ly9Xxw2ishXHHr3ugVCb6m2wItceeNDXPJcBhF5fnnK 9fIO2u/VnMxOW0MKx07rBp0YXg55eMdtTfznoeRwNwQDcytZaP4JmXIhYGlSLIlPBG7+LnixuBV SntUSpDObmF2Kxl5iK6M93B3aZPMpqZPcNl4U5k4Rvsa6Nb8u+Cg4bXutPzUHgp5GZ5SOfl1L8+ 8WT5w2HwtN1/umGFt9r1n6PDz/ivXpCtyA3HI9T7rHNb6iylw/SLKq8/HcaqQRRHfs7IH9PHPbk h70jctoxmWE/OkK9QFe+znlw== X-Received: by 2002:a17:902:ce06:b0:2ae:47c0:19ce with SMTP id d9443c01a7336-2ae47c01d10mr72462485ad.55.1772513080332; Mon, 02 Mar 2026 20:44:40 -0800 (PST) Received: from ubuntu.. ([89.222.116.197]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2ae4f945985sm74775645ad.71.2026.03.02.20.44.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Mar 2026 20:44:39 -0800 (PST) From: "jk.hong" To: xujiakai2025@iscas.ac.cn Cc: linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, kvm-riscv@lists.infradead.org, Ryan JK Hong Subject: Re: [PATCH v2] RISC-V: KVM: Fix use-after-free in kvm_riscv_aia_aplic_has_attr() Date: Tue, 3 Mar 2026 12:44:30 +0800 Message-ID: <20260303044432.699084-1-ryan.jk.hong@gmail.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20260302085312.1649738-1-xujiakai2025@iscas.ac.cn> References: <20260302085312.1649738-1-xujiakai2025@iscas.ac.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Ryan JK Hong > Fuzzer reports a KASAN use-after-free bug triggered by a race > between KVM_HAS_DEVICE_ATTR and KVM_SET_DEVICE_ATTR ioctls on the AIA > device. The root cause is that aia_has_attr() invokes > kvm_riscv_aia_aplic_has_attr() without holding dev->kvm->lock, while > a concurrent aia_set_attr() may call aia_init() under that lock. When > aia_init() fails after kvm_riscv_aia_aplic_init() has succeeded, it > calls kvm_riscv_aia_aplic_cleanup() in its fail_cleanup_imsics path, > which frees both aplic_state and aplic_state->irqs. The concurrent > has_attr path can then dereference the freed aplic->irqs in > aplic_read_pending(): > irqd = &aplic->irqs[irq]; /* UAF here */ > > KASAN report: > BUG: KASAN: slab-use-after-free in aplic_read_pending > arch/riscv/kvm/aia_aplic.c:119 [inline] > BUG: KASAN: slab-use-after-free in aplic_read_pending_word > arch/riscv/kvm/aia_aplic.c:351 [inline] > BUG: KASAN: slab-use-after-free in aplic_mmio_read_offset > arch/riscv/kvm/aia_aplic.c:406 > Read of size 8 at addr ff600000ba965d58 by task 9498 > Call Trace: > aplic_read_pending arch/riscv/kvm/aia_aplic.c:119 [inline] > aplic_read_pending_word arch/riscv/kvm/aia_aplic.c:351 [inline] > aplic_mmio_read_offset arch/riscv/kvm/aia_aplic.c:406 > kvm_riscv_aia_aplic_has_attr arch/riscv/kvm/aia_aplic.c:566 > aia_has_attr arch/riscv/kvm/aia_device.c:469 > allocated by task 9473: > kvm_riscv_aia_aplic_init arch/riscv/kvm/aia_aplic.c:583 > aia_init arch/riscv/kvm/aia_device.c:248 [inline] > aia_set_attr arch/riscv/kvm/aia_device.c:334 > freed by task 9473: > kvm_riscv_aia_aplic_cleanup arch/riscv/kvm/aia_aplic.c:644 > aia_init arch/riscv/kvm/aia_device.c:292 [inline] > aia_set_attr arch/riscv/kvm/aia_device.c:334 > > Fix this race by acquiring dev->kvm->lock in aia_has_attr() before > calling kvm_riscv_aia_aplic_has_attr(), consistent with the locking > pattern used in aia_get_attr() and aia_set_attr(). > > Fixes: 289a007b98b06d ("RISC-V: KVM: Expose APLIC registers as attributes of AIA irqchip") > Signed-off-by: Jiakai Xu > Signed-off-by: Jiakai Xu > --- > V2 -> V3: > - Fixed incorrect locking pattern in aia_has_attr(): avoid returning > while holding dev->kvm->lock by storing the return value in a local > variable, unlocking, and then returning. > V1 -> V2: > - Fixed the race by adding locking in aia_has_attr() instead of > introducing a new validation function, as suggested by Anup Patel. > --- > arch/riscv/kvm/aia_device.c | 9 ++++++--- > 1 file changed, 6 insertions(+), 3 deletions(-) > > diff --git a/arch/riscv/kvm/aia_device.c b/arch/riscv/kvm/aia_device.c > index b195a93add1ce..0722cbaed5ec9 100644 > --- a/arch/riscv/kvm/aia_device.c > +++ b/arch/riscv/kvm/aia_device.c > @@ -437,7 +437,7 @@ static int aia_get_attr(struct kvm_device *dev, struct kvm_device_attr *attr) > > static int aia_has_attr(struct kvm_device *dev, struct kvm_device_attr *attr) > { > - int nr_vcpus; > + int nr_vcpus, r = -ENXIO; > > switch (attr->group) { > case KVM_DEV_RISCV_AIA_GRP_CONFIG: > @@ -466,12 +466,15 @@ static int aia_has_attr(struct kvm_device *dev, struct kvm_device_attr *attr) > } > break; > case KVM_DEV_RISCV_AIA_GRP_APLIC: > - return kvm_riscv_aia_aplic_has_attr(dev->kvm, attr->attr); > + mutex_lock(&dev->kvm->lock); > + r = kvm_riscv_aia_aplic_has_attr(dev->kvm, attr->attr); > + mutex_unlock(&dev->kvm->lock); > + return r; > case KVM_DEV_RISCV_AIA_GRP_IMSIC: > return kvm_riscv_aia_imsic_has_attr(dev->kvm, attr->attr); > } > > - return -ENXIO; > + return r; > } > > struct kvm_device_ops kvm_riscv_aia_device_ops = { This case branch has the same problem. case KVM_DEV_RISCV_AIA_GRP_IMSIC: mutex_lock(&dev->kvm->lock); ret = kvm_riscv_aia_imsic_has_attr(dev->kvm, attr->attr); mutex_unlock(&dev->kvm->lock); return ret; }