From: Jacob Pan <jacob.jun.pan@linux.intel.com>
To: Alex Williamson <alex.williamson@redhat.com>
Cc: "Tian, Kevin" <kevin.tian@intel.com>,
Raj Ashok <ashok.raj@intel.com>, Jonathan Corbet <corbet@lwn.net>,
Jean-Philippe Brucker <jean-philippe@linaro.com>,
LKML <linux-kernel@vger.kernel.org>,
Christoph Hellwig <hch@infradead.org>,
iommu@lists.linux-foundation.org,
David Woodhouse <dwmw2@infradead.org>
Subject: Re: [PATCH v2 3/3] iommu/vt-d: Sanity check uapi argsz filled by users
Date: Thu, 11 Jun 2020 16:58:35 -0700 [thread overview]
Message-ID: <20200611165835.4de03911@jacob-builder> (raw)
In-Reply-To: <20200611145518.0c2817d6@x1.home>
On Thu, 11 Jun 2020 14:55:18 -0600
Alex Williamson <alex.williamson@redhat.com> wrote:
> On Thu, 11 Jun 2020 13:02:24 -0700
> Jacob Pan <jacob.jun.pan@linux.intel.com> wrote:
>
> > On Thu, 11 Jun 2020 11:08:16 -0600
> > Alex Williamson <alex.williamson@redhat.com> wrote:
> >
> > > On Wed, 10 Jun 2020 21:12:15 -0700
> > > Jacob Pan <jacob.jun.pan@linux.intel.com> wrote:
> > >
> > > > IOMMU UAPI data has an argsz field which is filled by user. As
> > > > the data structures expands, argsz may change. As the UAPI data
> > > > are shared among different architectures, extensions of UAPI
> > > > data could be a result of one architecture which has no impact
> > > > on another. Therefore, these argsz santity checks are performed
> > > > in the model specific IOMMU drivers. This patch adds sanity
> > > > checks in the VT-d to ensure argsz passed by userspace matches
> > > > feature flags and other contents.
> > > >
> > > > Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
> > > > ---
> > > > drivers/iommu/intel-iommu.c | 16 ++++++++++++++++
> > > > drivers/iommu/intel-svm.c | 12 ++++++++++++
> > > > 2 files changed, 28 insertions(+)
> > > >
> > > > diff --git a/drivers/iommu/intel-iommu.c
> > > > b/drivers/iommu/intel-iommu.c index 27ebf4b9faef..c98b5109684b
> > > > 100644 --- a/drivers/iommu/intel-iommu.c
> > > > +++ b/drivers/iommu/intel-iommu.c
> > > > @@ -5365,6 +5365,7 @@ intel_iommu_sva_invalidate(struct
> > > > iommu_domain *domain, struct device *dev, struct
> > > > device_domain_info *info; struct intel_iommu *iommu;
> > > > unsigned long flags;
> > > > + unsigned long minsz;
> > > > int cache_type;
> > > > u8 bus, devfn;
> > > > u16 did, sid;
> > > > @@ -5385,6 +5386,21 @@ intel_iommu_sva_invalidate(struct
> > > > iommu_domain *domain, struct device *dev, if
> > > > (!(dmar_domain->flags & DOMAIN_FLAG_NESTING_MODE)) return
> > > > -EINVAL;
> > > > + minsz = offsetofend(struct iommu_cache_invalidate_info,
> > > > padding);
> > >
> > > Would it still be better to look for the end of the last field
> > > that's actually used to avoid the code churn and oversights
> > > if/when the padding field does get used and renamed?
> > >
> > My thought was that if the padding gets partially re-purposed, the
> > remaining padding would still be valid for minsz check. The
> > extension rule ensures that there is no size change other the
> > variable size union at the end. So use padding would avoid the
> > churn, or i am totally wrong?
>
> No, it's trying to predict the future either way. I figured checking
> minsz against the fields we actually consume allows complete use of
> the padding fields and provides a little leniency to the user. We'd
> need to be careful though that if those fields are later used by this
> driver, the code would still need to accept the smaller size. If the
> union was named rather than anonymous we could just use offsetof() to
> avoid directly referencing the padding fields.
>
I will change it to named union.
Thanks,
> > > Per my comment on patch 1/, this also seems like where the device
> > > specific IOMMU driver should also have the responsibility of
> > > receiving a __user pointer to do the copy_from_user() here. vfio
> > > can't know which flags require which fields to make a UAPI with
> > > acceptable compatibility guarantees otherwise.
> > >
> > Right, VFIO cannot do compatibility guarantees, it is just seem to
> > be that VFIO has enough information to copy_from_user sanely &
> > safely and handle over to IOMMU. Please help define the
> > roles/responsibilities in my other email. Then I will follow the
> > guideline.
>
> We can keep that part of the discussion in the other thread. Thanks,
>
> Alex
>
> > > > + if (inv_info->argsz < minsz)
> > > > + return -EINVAL;
> > > > +
> > > > + /* Sanity check user filled invalidation dat sizes */
> > > > + if (inv_info->granularity == IOMMU_INV_GRANU_ADDR &&
> > > > + inv_info->argsz != offsetofend(struct
> > > > iommu_cache_invalidate_info,
> > > > + addr_info))
> > > > + return -EINVAL;
> > > > +
> > > > + if (inv_info->granularity == IOMMU_INV_GRANU_PASID &&
> > > > + inv_info->argsz != offsetofend(struct
> > > > iommu_cache_invalidate_info,
> > > > + pasid_info))
> > > > + return -EINVAL;
> > > > +
> > > > spin_lock_irqsave(&device_domain_lock, flags);
> > > > spin_lock(&iommu->lock);
> > > > info = get_domain_info(dev);
> > > > diff --git a/drivers/iommu/intel-svm.c
> > > > b/drivers/iommu/intel-svm.c index 35b43fe819ed..64dc2c66dfff
> > > > 100644 --- a/drivers/iommu/intel-svm.c
> > > > +++ b/drivers/iommu/intel-svm.c
> > > > @@ -235,15 +235,27 @@ int intel_svm_bind_gpasid(struct
> > > > iommu_domain *domain, struct device *dev, struct dmar_domain
> > > > *dmar_domain; struct intel_svm_dev *sdev;
> > > > struct intel_svm *svm;
> > > > + unsigned long minsz;
> > > > int ret = 0;
> > > >
> > > > if (WARN_ON(!iommu) || !data)
> > > > return -EINVAL;
> > > >
> > > > + /*
> > > > + * We mandate that no size change in IOMMU UAPI data
> > > > before the
> > > > + * variable size union at the end.
> > > > + */
> > > > + minsz = offsetofend(struct iommu_gpasid_bind_data,
> > > > padding);
> > >
> > > Same. Thanks,
> > >
> > > Alex
> > >
> > > > + if (data->argsz < minsz)
> > > > + return -EINVAL;
> > > > +
> > > > if (data->version != IOMMU_GPASID_BIND_VERSION_1 ||
> > > > data->format != IOMMU_PASID_FORMAT_INTEL_VTD)
> > > > return -EINVAL;
> > > >
> > > > + if (data->argsz != offsetofend(struct
> > > > iommu_gpasid_bind_data, vtd))
> > > > + return -EINVAL;
> > > > +
> > > > if (!dev_is_pci(dev))
> > > > return -ENOTSUPP;
> > > >
> > >
> >
> > [Jacob Pan]
> >
>
[Jacob Pan]
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu
WARNING: multiple messages have this Message-ID (diff)
From: Jacob Pan <jacob.jun.pan@linux.intel.com>
To: Alex Williamson <alex.williamson@redhat.com>
Cc: iommu@lists.linux-foundation.org,
LKML <linux-kernel@vger.kernel.org>,
"Lu Baolu" <baolu.lu@linux.intel.com>,
Joerg Roedel <joro@8bytes.org>,
David Woodhouse <dwmw2@infradead.org>,
Yi Liu <yi.l.liu@intel.com>, "Tian, Kevin" <kevin.tian@intel.com>,
Raj Ashok <ashok.raj@intel.com>,
"Christoph Hellwig" <hch@infradead.org>,
Jean-Philippe Brucker <jean-philippe@linaro.com>,
Eric Auger <eric.auger@redhat.com>,
Jonathan Corbet <corbet@lwn.net>,
jacob.jun.pan@linux.intel.com
Subject: Re: [PATCH v2 3/3] iommu/vt-d: Sanity check uapi argsz filled by users
Date: Thu, 11 Jun 2020 16:58:35 -0700 [thread overview]
Message-ID: <20200611165835.4de03911@jacob-builder> (raw)
In-Reply-To: <20200611145518.0c2817d6@x1.home>
On Thu, 11 Jun 2020 14:55:18 -0600
Alex Williamson <alex.williamson@redhat.com> wrote:
> On Thu, 11 Jun 2020 13:02:24 -0700
> Jacob Pan <jacob.jun.pan@linux.intel.com> wrote:
>
> > On Thu, 11 Jun 2020 11:08:16 -0600
> > Alex Williamson <alex.williamson@redhat.com> wrote:
> >
> > > On Wed, 10 Jun 2020 21:12:15 -0700
> > > Jacob Pan <jacob.jun.pan@linux.intel.com> wrote:
> > >
> > > > IOMMU UAPI data has an argsz field which is filled by user. As
> > > > the data structures expands, argsz may change. As the UAPI data
> > > > are shared among different architectures, extensions of UAPI
> > > > data could be a result of one architecture which has no impact
> > > > on another. Therefore, these argsz santity checks are performed
> > > > in the model specific IOMMU drivers. This patch adds sanity
> > > > checks in the VT-d to ensure argsz passed by userspace matches
> > > > feature flags and other contents.
> > > >
> > > > Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
> > > > ---
> > > > drivers/iommu/intel-iommu.c | 16 ++++++++++++++++
> > > > drivers/iommu/intel-svm.c | 12 ++++++++++++
> > > > 2 files changed, 28 insertions(+)
> > > >
> > > > diff --git a/drivers/iommu/intel-iommu.c
> > > > b/drivers/iommu/intel-iommu.c index 27ebf4b9faef..c98b5109684b
> > > > 100644 --- a/drivers/iommu/intel-iommu.c
> > > > +++ b/drivers/iommu/intel-iommu.c
> > > > @@ -5365,6 +5365,7 @@ intel_iommu_sva_invalidate(struct
> > > > iommu_domain *domain, struct device *dev, struct
> > > > device_domain_info *info; struct intel_iommu *iommu;
> > > > unsigned long flags;
> > > > + unsigned long minsz;
> > > > int cache_type;
> > > > u8 bus, devfn;
> > > > u16 did, sid;
> > > > @@ -5385,6 +5386,21 @@ intel_iommu_sva_invalidate(struct
> > > > iommu_domain *domain, struct device *dev, if
> > > > (!(dmar_domain->flags & DOMAIN_FLAG_NESTING_MODE)) return
> > > > -EINVAL;
> > > > + minsz = offsetofend(struct iommu_cache_invalidate_info,
> > > > padding);
> > >
> > > Would it still be better to look for the end of the last field
> > > that's actually used to avoid the code churn and oversights
> > > if/when the padding field does get used and renamed?
> > >
> > My thought was that if the padding gets partially re-purposed, the
> > remaining padding would still be valid for minsz check. The
> > extension rule ensures that there is no size change other the
> > variable size union at the end. So use padding would avoid the
> > churn, or i am totally wrong?
>
> No, it's trying to predict the future either way. I figured checking
> minsz against the fields we actually consume allows complete use of
> the padding fields and provides a little leniency to the user. We'd
> need to be careful though that if those fields are later used by this
> driver, the code would still need to accept the smaller size. If the
> union was named rather than anonymous we could just use offsetof() to
> avoid directly referencing the padding fields.
>
I will change it to named union.
Thanks,
> > > Per my comment on patch 1/, this also seems like where the device
> > > specific IOMMU driver should also have the responsibility of
> > > receiving a __user pointer to do the copy_from_user() here. vfio
> > > can't know which flags require which fields to make a UAPI with
> > > acceptable compatibility guarantees otherwise.
> > >
> > Right, VFIO cannot do compatibility guarantees, it is just seem to
> > be that VFIO has enough information to copy_from_user sanely &
> > safely and handle over to IOMMU. Please help define the
> > roles/responsibilities in my other email. Then I will follow the
> > guideline.
>
> We can keep that part of the discussion in the other thread. Thanks,
>
> Alex
>
> > > > + if (inv_info->argsz < minsz)
> > > > + return -EINVAL;
> > > > +
> > > > + /* Sanity check user filled invalidation dat sizes */
> > > > + if (inv_info->granularity == IOMMU_INV_GRANU_ADDR &&
> > > > + inv_info->argsz != offsetofend(struct
> > > > iommu_cache_invalidate_info,
> > > > + addr_info))
> > > > + return -EINVAL;
> > > > +
> > > > + if (inv_info->granularity == IOMMU_INV_GRANU_PASID &&
> > > > + inv_info->argsz != offsetofend(struct
> > > > iommu_cache_invalidate_info,
> > > > + pasid_info))
> > > > + return -EINVAL;
> > > > +
> > > > spin_lock_irqsave(&device_domain_lock, flags);
> > > > spin_lock(&iommu->lock);
> > > > info = get_domain_info(dev);
> > > > diff --git a/drivers/iommu/intel-svm.c
> > > > b/drivers/iommu/intel-svm.c index 35b43fe819ed..64dc2c66dfff
> > > > 100644 --- a/drivers/iommu/intel-svm.c
> > > > +++ b/drivers/iommu/intel-svm.c
> > > > @@ -235,15 +235,27 @@ int intel_svm_bind_gpasid(struct
> > > > iommu_domain *domain, struct device *dev, struct dmar_domain
> > > > *dmar_domain; struct intel_svm_dev *sdev;
> > > > struct intel_svm *svm;
> > > > + unsigned long minsz;
> > > > int ret = 0;
> > > >
> > > > if (WARN_ON(!iommu) || !data)
> > > > return -EINVAL;
> > > >
> > > > + /*
> > > > + * We mandate that no size change in IOMMU UAPI data
> > > > before the
> > > > + * variable size union at the end.
> > > > + */
> > > > + minsz = offsetofend(struct iommu_gpasid_bind_data,
> > > > padding);
> > >
> > > Same. Thanks,
> > >
> > > Alex
> > >
> > > > + if (data->argsz < minsz)
> > > > + return -EINVAL;
> > > > +
> > > > if (data->version != IOMMU_GPASID_BIND_VERSION_1 ||
> > > > data->format != IOMMU_PASID_FORMAT_INTEL_VTD)
> > > > return -EINVAL;
> > > >
> > > > + if (data->argsz != offsetofend(struct
> > > > iommu_gpasid_bind_data, vtd))
> > > > + return -EINVAL;
> > > > +
> > > > if (!dev_is_pci(dev))
> > > > return -ENOTSUPP;
> > > >
> > >
> >
> > [Jacob Pan]
> >
>
[Jacob Pan]
next prev parent reply other threads:[~2020-06-11 23:52 UTC|newest]
Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-11 4:12 [PATCH v2 0/3] IOMMU user API enhancement Jacob Pan
2020-06-11 4:12 ` Jacob Pan
2020-06-11 4:12 ` [PATCH v2 1/3] docs: IOMMU user API Jacob Pan
2020-06-11 4:12 ` Jacob Pan
2020-06-11 6:33 ` Lu Baolu
2020-06-11 6:33 ` Lu Baolu
2020-06-12 22:05 ` Jacob Pan
2020-06-12 22:05 ` Jacob Pan
2020-06-11 9:30 ` Jonathan Cameron
2020-06-11 9:30 ` Jonathan Cameron
2020-06-12 22:53 ` Jacob Pan
2020-06-12 22:53 ` Jacob Pan
2020-06-11 13:55 ` Jonathan Corbet
2020-06-11 13:55 ` Jonathan Corbet
2020-06-11 16:38 ` Jacob Pan
2020-06-11 16:38 ` Jacob Pan
2020-06-11 15:47 ` Alex Williamson
2020-06-11 15:47 ` Alex Williamson
2020-06-11 19:52 ` Jacob Pan
2020-06-11 19:52 ` Jacob Pan
2020-06-11 20:40 ` Alex Williamson
2020-06-11 20:40 ` Alex Williamson
2020-06-12 0:27 ` Jacob Pan
2020-06-12 0:27 ` Jacob Pan
2020-06-12 7:38 ` Tian, Kevin
2020-06-12 7:38 ` Tian, Kevin
2020-06-12 13:09 ` Jacob Pan
2020-06-12 13:09 ` Jacob Pan
2020-06-16 15:22 ` Jacob Pan
2020-06-16 15:22 ` Jacob Pan
2020-06-17 6:20 ` Liu, Yi L
2020-06-17 6:20 ` Liu, Yi L
2020-06-17 8:28 ` Tian, Kevin
2020-06-17 8:28 ` Tian, Kevin
2020-06-18 21:48 ` Alex Williamson
2020-06-18 21:48 ` Alex Williamson
2020-06-19 2:15 ` Liu, Yi L
2020-06-19 2:15 ` Liu, Yi L
2020-06-19 2:54 ` Alex Williamson
2020-06-19 2:54 ` Alex Williamson
2020-06-19 3:30 ` Liu, Yi L
2020-06-19 3:30 ` Liu, Yi L
2020-06-19 16:37 ` Alex Williamson
2020-06-19 16:37 ` Alex Williamson
2020-06-21 5:46 ` Liu, Yi L
2020-06-21 5:46 ` Liu, Yi L
2020-06-11 4:12 ` [PATCH v2 2/3] iommu/uapi: Add argsz for user filled data Jacob Pan
2020-06-11 4:12 ` Jacob Pan
2020-06-11 16:49 ` Alex Williamson
2020-06-11 16:49 ` Alex Williamson
2020-06-12 0:02 ` Jacob Pan
2020-06-12 0:02 ` Jacob Pan
2020-06-11 4:12 ` [PATCH v2 3/3] iommu/vt-d: Sanity check uapi argsz filled by users Jacob Pan
2020-06-11 4:12 ` Jacob Pan
2020-06-11 17:08 ` Alex Williamson
2020-06-11 17:08 ` Alex Williamson
2020-06-11 20:02 ` Jacob Pan
2020-06-11 20:02 ` Jacob Pan
2020-06-11 20:55 ` Alex Williamson
2020-06-11 20:55 ` Alex Williamson
2020-06-11 23:58 ` Jacob Pan [this message]
2020-06-11 23:58 ` Jacob Pan
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=20200611165835.4de03911@jacob-builder \
--to=jacob.jun.pan@linux.intel.com \
--cc=alex.williamson@redhat.com \
--cc=ashok.raj@intel.com \
--cc=corbet@lwn.net \
--cc=dwmw2@infradead.org \
--cc=hch@infradead.org \
--cc=iommu@lists.linux-foundation.org \
--cc=jean-philippe@linaro.com \
--cc=kevin.tian@intel.com \
--cc=linux-kernel@vger.kernel.org \
/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.