From: Alex Williamson <alex.williamson@redhat.com>
To: Vlad Tsyrklevich <vlad@tsyrklevich.net>
Cc: kvm@vger.kernel.org
Subject: Re: [PATCH v2] vfio/pci: Fix integer overflows, bitmask check
Date: Wed, 12 Oct 2016 09:39:59 -0600 [thread overview]
Message-ID: <20161012093959.0f7ba9dc@t450s.home> (raw)
In-Reply-To: <CAH0z3hPfQdvPV5vogbQdx_EoRQGtGKuw-q2h7AeYdFq1V=e1kQ@mail.gmail.com>
On Wed, 12 Oct 2016 17:06:15 +0200
Vlad Tsyrklevich <vlad@tsyrklevich.net> wrote:
> On Wed, Oct 12, 2016 at 4:51 PM, Alex Williamson
> <alex.williamson@redhat.com> wrote:
> > On Wed, 12 Oct 2016 09:53:49 +0200
> > Vlad Tsyrklevich <vlad@tsyrklevich.net> wrote:
> >
> >> The VFIO_DEVICE_SET_IRQS ioctl did not sufficiently sanitize
> >> user-supplied integers, potentially allowing arbitrary memory writes.
> >> This patch adds appropriate integer checks, and also verifies that only
> >> a single element in the VFIO_IRQ_SET_DATA_TYPE_MASK bitmask is set.
> >> VFIO_IRQ_SET_ACTION_TYPE_MASK is already correctly checked later in
> >> vfio_pci_set_irqs_ioctl().
> >>
> >> Signed-off-by: Vlad Tsyrklevich <vlad@tsyrklevich.net>
> >> ---
> >> drivers/vfio/pci/vfio_pci.c | 26 +++++++++++++++++---------
> >> drivers/vfio/pci/vfio_pci_intrs.c | 2 +-
> >> 2 files changed, 18 insertions(+), 10 deletions(-)
> >>
> >> diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
> >> index d624a52..44de13c 100644
> >> --- a/drivers/vfio/pci/vfio_pci.c
> >> +++ b/drivers/vfio/pci/vfio_pci.c
> >> @@ -829,6 +829,7 @@ static long vfio_pci_ioctl(void *device_data,
> >>
> >> } else if (cmd == VFIO_DEVICE_SET_IRQS) {
> >> struct vfio_irq_set hdr;
> >> + size_t size;
> >> u8 *data = NULL;
> >> int ret = 0;
> >>
> >> @@ -838,20 +839,27 @@ static long vfio_pci_ioctl(void *device_data,
> >> return -EFAULT;
> >>
> >> if (hdr.argsz < minsz || hdr.index >= VFIO_PCI_NUM_IRQS ||
> >> + hdr.count >= (U32_MAX - hdr.start) ||
> >> hdr.flags & ~(VFIO_IRQ_SET_DATA_TYPE_MASK |
> >> VFIO_IRQ_SET_ACTION_TYPE_MASK))
> >> return -EINVAL;
> >>
> >> - if (!(hdr.flags & VFIO_IRQ_SET_DATA_NONE)) {
> >> - size_t size;
> >> - int max = vfio_pci_get_irq_count(vdev, hdr.index);
> >> + switch (hdr.flags & VFIO_IRQ_SET_DATA_TYPE_MASK) {
> >> + case VFIO_IRQ_SET_DATA_NONE:
> >> + size = 0;
> >> + break;
> >> + case VFIO_IRQ_SET_DATA_BOOL:
> >> + size = sizeof(uint8_t);
> >> + break;
> >> + case VFIO_IRQ_SET_DATA_EVENTFD:
> >> + size = sizeof(int32_t);
> >> + break;
> >> + default:
> >> + return -EINVAL;
> >> + }
> >>
> >> - if (hdr.flags & VFIO_IRQ_SET_DATA_BOOL)
> >> - size = sizeof(uint8_t);
> >> - else if (hdr.flags & VFIO_IRQ_SET_DATA_EVENTFD)
> >> - size = sizeof(int32_t);
> >> - else
> >> - return -EINVAL;
> >> + if (size) {
> >> + int max = vfio_pci_get_irq_count(vdev, hdr.index);
> >
> >
> > Why not pull this out too so we can fully validate start/count for the
> > DATA_NONE case?
>
> I'm not familiar with the vfio subsystem so I wasn't sure if the check
> against vfio_pci_get_irq_count() was also valid for the DATA_NONE
> case. It turns out that the ioctls also all check start/count as well
> so it's not strictly necessary, but I'm happy to also break out that
> case here.
It feels like pulling vfio_pci_get_irq_count() up allows us to more
strictly validate the range, not just sanitize it for overflow. Maybe
that leads to some redundancy later, but we can fix that with future
patches if it seems necessary.
> >>
> >> if (hdr.argsz - minsz < hdr.count * size ||
> >> hdr.start >= max || hdr.start +
> >> hdr.count > max) diff --git a/drivers/vfio/pci/vfio_pci_intrs.c
> >> b/drivers/vfio/pci/vfio_pci_intrs.c index c2e6089..1c46045 100644
> >> --- a/drivers/vfio/pci/vfio_pci_intrs.c
> >> +++ b/drivers/vfio/pci/vfio_pci_intrs.c
> >> @@ -256,7 +256,7 @@ static int vfio_msi_enable(struct
> >> vfio_pci_device *vdev, int nvec, bool msix) if (!is_irq_none(vdev))
> >> return -EINVAL;
> >>
> >> - vdev->ctx = kzalloc(nvec * sizeof(struct vfio_pci_irq_ctx),
> >> GFP_KERNEL);
> >> + vdev->ctx = kcalloc(nvec, sizeof(struct vfio_pci_irq_ctx),
> >> GFP_KERNEL); if (!vdev->ctx)
> >> return -ENOMEM;
> >
> > Unrelated change?
>
> I put it in this patch because kcalloc checks against integer overflow
> and part of the cause of the issue I identified last time was caused
> by the fact that nvec * sizeof(struct vfio_pci_irq_ctx) could be made
> to overflow. That integer overflow is no longer possible with the
> other changes I've made in this patch, but I figured it would be a
> good protection from other integer issues as well. Should have called
> that out more clearly.
Ah, I see. Yes, please note this in the commit log. Thanks,
Alex
next prev parent reply other threads:[~2016-10-12 15:40 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-11 11:02 [PATCH] vfio/pci: Fix integer overflow/heap memory disclosure Vlad Tsyrklevich
2016-10-11 16:10 ` Alex Williamson
2016-10-11 20:04 ` Vlad Tsyrklevich
2016-10-11 22:39 ` Alex Williamson
2016-10-12 7:53 ` [PATCH v2] vfio/pci: Fix integer overflows, bitmask check Vlad Tsyrklevich
2016-10-12 14:51 ` Alex Williamson
2016-10-12 15:06 ` Vlad Tsyrklevich
2016-10-12 15:39 ` Alex Williamson [this message]
2016-10-12 16:51 ` [PATCH v3] " Vlad Tsyrklevich
2016-10-26 21:19 ` Alex Williamson
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=20161012093959.0f7ba9dc@t450s.home \
--to=alex.williamson@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=vlad@tsyrklevich.net \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox