From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-oa1-f71.google.com (mail-oa1-f71.google.com [209.85.160.71]) (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 A97EC2F851 for ; Mon, 4 May 2026 01:22:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.71 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777857752; cv=none; b=E/QN1Ysj1qijYS0YYEMjZI3FFAx4M8LbZ03l+VxlYpbSNx55c7Czbj4Nnobx7xenOl2fsSzIjtX3lAXD1l3lFsrHbCF1u8R9IEx+ssdHvksIDDVfdWpTkrpCEF0erSyhMqHo08lu1VWqweRLM121qVgpcGBl9id19Al92DfoFHc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777857752; c=relaxed/simple; bh=FHVK5u+7rL43OTGxx8PEAdHEL++E+Og5OxYu5RfmmEM=; h=MIME-Version:Date:In-Reply-To:Message-ID:Subject:From:To: Content-Type; b=SdXojja5KsL2m4KoFCz9H6h1Z99aL7u06bJpmCGVWKTbikhyo5w1p9AbesL0NYoEuatLFicuO/lwkhuZs1ZzYQUeYi8b9ytUxLeguYo+/7ZaG8iO8ici+S8ZLkwX6uVH9KNdhRHnruZGWQXUqEyXSxwgqoZRMHWQzCkqD9aYva0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=syzkaller.appspotmail.com; spf=pass smtp.mailfrom=M3KW2WVRGUFZ5GODRSRYTGD7.apphosting.bounces.google.com; arc=none smtp.client-ip=209.85.160.71 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=syzkaller.appspotmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=M3KW2WVRGUFZ5GODRSRYTGD7.apphosting.bounces.google.com Received: by mail-oa1-f71.google.com with SMTP id 586e51a60fabf-4344aa5652fso5932731fac.2 for ; Sun, 03 May 2026 18:22:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777857749; x=1778462549; h=to:from:subject:message-id:in-reply-to:date:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=3UEiJtEqDzudHNHTpC3kYjX8JdwlmGTU9pFM2wShGuM=; b=gBSQQm6kvxLEwnbBBCcAFzXtyX3O5gkReei69ZosHFXQlYzJ99ZbE1yupCEYXiU6KE gElZmWBT53dO88uyqzRJZrj/DYM6sJcsAdLZyVPMUQVx60OilJT5Aq9G39kRJJcKFm8e wOFwUDrxYrWNNWejCNKWSaRpqJto9pfIJxqNlmbHISShF5Sc7ZnK9rcQkSNUYCOYDu4f cZ68PW3qbEsoWm9W3mplZ9tckCCZkuQfHA62N5zcCFfh5kuHN/0uYGWXP1Ij82LxB3pD DzaZBoxsz0qavVzYSc3xNV5JRg/RevybvPCK0DIYPc7TnHli9ARbs5A+sZY4Fhad+P8Y CKIg== X-Gm-Message-State: AOJu0Ywxs3E+Pu8ni+kqvSgNqegwLb77WTCCKhlVfmrQOCupk1xrWpPW vkUPOwbg7Sa8g1q8y7NdIcULx7+xumR6TiGZ9DDEC9xcANwZ73ZHNXAUuweqQtMDIdMjbtsGH3J z9oCTkyxFBYkq3PBx5o8W2hzr9ajxIqOJApFYtP1++gMgoIFx9JizQLkPN0A= Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Received: by 2002:a4a:e908:0:b0:696:282e:69b5 with SMTP id 006d021491bc7-69697df686amr3579430eaf.43.1777857749689; Sun, 03 May 2026 18:22:29 -0700 (PDT) Date: Sun, 03 May 2026 18:22:29 -0700 In-Reply-To: <69f3f165.170a0220.5f1b.0010.GAE@google.com> X-Google-Appengine-App-Id: s~syzkaller X-Google-Appengine-App-Id-Alias: syzkaller Message-ID: <69f7f4d5.050a0220.312cd3.003f.GAE@google.com> Subject: Forwarded: [PATCH v2] PCI/proc: check user access return values in proc_bus_pci_{read,write}() From: syzbot To: linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com Content-Type: text/plain; charset="UTF-8" For archival purposes, forwarding an incoming command email to linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com. *** Subject: [PATCH v2] PCI/proc: check user access return values in proc_bus_pci_{read,write}() Author: kartikey406@gmail.com #syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master proc_bus_pci_write() ignores the return value of __get_user(). On a faulting user pointer the extable fixup zeros the destination, and the function writes those zeros to PCI configuration space. syzbot triggers this with writev()-ing a NULL iov_base to /proc/bus/pci/00/03.0 (the virtio-blk controller in the syzkaller VM): zero is written to the Command register, clearing Bus Master Enable, and the disk stops responding. In-flight journal writes never complete and jbd2 hangs in wait_on_buffer() indefinitely: INFO: task jbd2/sda1-8 blocked in I/O wait for more than 143 seconds. __wait_on_buffer fs/buffer.c:123 jbd2_journal_commit_transaction+0x388a/0x6870 fs/jbd2/commit.c:837 kjournald2 fs/jbd2/journal.c:201 proc_bus_pci_read() has the symmetric problem with __put_user(): a faulting user pointer silently drops config-space data and returns success. Switch both functions to get_user()/put_user(), which combine the access_ok() check with the load/store and return -EFAULT on failure. The up-front access_ok() can be removed accordingly. On error, jump to a common label that releases the runtime-PM reference and returns -EFAULT. Reported-by: syzbot+c7604c9fdd7580cca4e0@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=c7604c9fdd7580cca4e0 Signed-off-by: Deepanshu Kartikey --- Changes in v2: - Use get_user()/put_user() and drop access_ok() (Krzysztof) - Rename label to err: per kernel convention (Krzysztof) - Simplify error path to release runtime-PM and return -EFAULT (Krzysztof) - Apply the same fix to proc_bus_pci_read() (Krzysztof) --- drivers/pci/proc.c | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index ce36e35681e8..8e624d829840 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -53,15 +53,13 @@ static ssize_t proc_bus_pci_read(struct file *file, char __user *buf, nbytes = size - pos; cnt = nbytes; - if (!access_ok(buf, cnt)) - return -EINVAL; - pci_config_pm_runtime_get(dev); if ((pos & 1) && cnt) { unsigned char val; pci_user_read_config_byte(dev, pos, &val); - __put_user(val, buf); + if (put_user(val, buf)) + goto err; buf++; pos++; cnt--; @@ -70,7 +68,8 @@ static ssize_t proc_bus_pci_read(struct file *file, char __user *buf, if ((pos & 3) && cnt > 2) { unsigned short val; pci_user_read_config_word(dev, pos, &val); - __put_user(cpu_to_le16(val), (__le16 __user *) buf); + if (put_user(cpu_to_le16(val), (__le16 __user *) buf)) + goto err; buf += 2; pos += 2; cnt -= 2; @@ -79,7 +78,8 @@ static ssize_t proc_bus_pci_read(struct file *file, char __user *buf, while (cnt >= 4) { unsigned int val; pci_user_read_config_dword(dev, pos, &val); - __put_user(cpu_to_le32(val), (__le32 __user *) buf); + if (put_user(cpu_to_le32(val), (__le32 __user *) buf)) + goto err; buf += 4; pos += 4; cnt -= 4; @@ -89,7 +89,8 @@ static ssize_t proc_bus_pci_read(struct file *file, char __user *buf, if (cnt >= 2) { unsigned short val; pci_user_read_config_word(dev, pos, &val); - __put_user(cpu_to_le16(val), (__le16 __user *) buf); + if (put_user(cpu_to_le16(val), (__le16 __user *) buf)) + goto err; buf += 2; pos += 2; cnt -= 2; @@ -98,7 +99,8 @@ static ssize_t proc_bus_pci_read(struct file *file, char __user *buf, if (cnt) { unsigned char val; pci_user_read_config_byte(dev, pos, &val); - __put_user(val, buf); + if (put_user(val, buf)) + goto err; pos++; } @@ -106,6 +108,10 @@ static ssize_t proc_bus_pci_read(struct file *file, char __user *buf, *ppos = pos; return nbytes; + +err: + pci_config_pm_runtime_put(dev); + return -EFAULT; } static ssize_t proc_bus_pci_write(struct file *file, const char __user *buf, @@ -129,14 +135,12 @@ static ssize_t proc_bus_pci_write(struct file *file, const char __user *buf, nbytes = size - pos; cnt = nbytes; - if (!access_ok(buf, cnt)) - return -EINVAL; - pci_config_pm_runtime_get(dev); if ((pos & 1) && cnt) { unsigned char val; - __get_user(val, buf); + if (get_user(val, buf)) + goto err; pci_user_write_config_byte(dev, pos, val); buf++; pos++; @@ -145,7 +149,8 @@ static ssize_t proc_bus_pci_write(struct file *file, const char __user *buf, if ((pos & 3) && cnt > 2) { __le16 val; - __get_user(val, (__le16 __user *) buf); + if (get_user(val, (__le16 __user *) buf)) + goto err; pci_user_write_config_word(dev, pos, le16_to_cpu(val)); buf += 2; pos += 2; @@ -154,7 +159,8 @@ static ssize_t proc_bus_pci_write(struct file *file, const char __user *buf, while (cnt >= 4) { __le32 val; - __get_user(val, (__le32 __user *) buf); + if (get_user(val, (__le32 __user *) buf)) + goto err; pci_user_write_config_dword(dev, pos, le32_to_cpu(val)); buf += 4; pos += 4; @@ -163,7 +169,8 @@ static ssize_t proc_bus_pci_write(struct file *file, const char __user *buf, if (cnt >= 2) { __le16 val; - __get_user(val, (__le16 __user *) buf); + if (get_user(val, (__le16 __user *) buf)) + goto err; pci_user_write_config_word(dev, pos, le16_to_cpu(val)); buf += 2; pos += 2; @@ -172,7 +179,8 @@ static ssize_t proc_bus_pci_write(struct file *file, const char __user *buf, if (cnt) { unsigned char val; - __get_user(val, buf); + if (get_user(val, buf)) + goto err; pci_user_write_config_byte(dev, pos, val); pos++; } @@ -182,6 +190,10 @@ static ssize_t proc_bus_pci_write(struct file *file, const char __user *buf, *ppos = pos; i_size_write(ino, dev->cfg_size); return nbytes; + +err: + pci_config_pm_runtime_put(dev); + return -EFAULT; } #ifdef HAVE_PCI_MMAP -- 2.43.0