All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bjorn Helgaas <helgaas@kernel.org>
To: Deepanshu Kartikey <kartikey406@gmail.com>
Cc: bhelgaas@google.com, kw@linux.com, linux-pci@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	syzbot+c7604c9fdd7580cca4e0@syzkaller.appspotmail.com
Subject: Re: [PATCH v2] PCI/proc: check user access return values in proc_bus_pci_{read,write}()
Date: Mon, 22 Jun 2026 12:19:26 -0500	[thread overview]
Message-ID: <20260622171926.GA684276@bhelgaas> (raw)
In-Reply-To: <CADhLXY6F5G-prnD=c+oKYPvOhXTukjs3_1TksEvjPU6u+u+6og@mail.gmail.com>

On Sun, Jun 21, 2026 at 01:52:17PM +0530, Deepanshu Kartikey wrote:
> On Mon, May 4, 2026 at 7:52 AM Deepanshu Kartikey <kartikey406@gmail.com> wrote:
> >
> > 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
> > Tested-by: syzbot+c7604c9fdd7580cca4e0@syzkaller.appspotmail.com
> > Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
> > ---
> > 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
> >
> 
> Gentle Reminder on this patch. Please let me know the status of this
> patch.

Thanks for the reminder.  We're halfway through the merge window for
v7.2, so we'll have to look at this for v7.3 after v7.2-rc1 is tagged.

      reply	other threads:[~2026-06-22 17:19 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-04  2:22 [PATCH v2] PCI/proc: check user access return values in proc_bus_pci_{read,write}() Deepanshu Kartikey
2026-05-04  2:44 ` sashiko-bot
2026-06-21  8:22 ` Deepanshu Kartikey
2026-06-22 17:19   ` Bjorn Helgaas [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260622171926.GA684276@bhelgaas \
    --to=helgaas@kernel.org \
    --cc=bhelgaas@google.com \
    --cc=kartikey406@gmail.com \
    --cc=kw@linux.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=syzbot+c7604c9fdd7580cca4e0@syzkaller.appspotmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.