Message ID | a4f2cd76b9dc1833ee6c1cf325cba57def22231c.1740014950.git.nicolinc@nvidia.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | iommu: Add MSI mapping support with nested SMMU (Part-1 core) | expand |
On Wed, Feb 19 2025 at 17:31, Nicolin Chen wrote: > Fix the MSI cookie UAF by removing the cookie pointer. The translated IOVA > address is already known during iommu_dma_prepare_msi() and cannot change. > Thus, it can simply be stored as an integer in the MSI descriptor. > > A following patch will fix the other UAF in iommu_get_domain_for_dev(), by > using the IOMMU group mutex. "A following patch" has no meaning once the current one is applied. Simply say: The other UAF in iommu_get_domain_for_dev() will be addressed seperately, by .... > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> > Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> With that fixed: Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Hi Nicolin, On Fri, Feb 21, 2025 at 10:28:20AM +0100, Thomas Gleixner wrote: > On Wed, Feb 19 2025 at 17:31, Nicolin Chen wrote: > > Fix the MSI cookie UAF by removing the cookie pointer. The translated IOVA > > address is already known during iommu_dma_prepare_msi() and cannot change. > > Thus, it can simply be stored as an integer in the MSI descriptor. > > > > A following patch will fix the other UAF in iommu_get_domain_for_dev(), by > > using the IOMMU group mutex. > > "A following patch" has no meaning once the current one is > applied. Simply say: > > The other UAF in iommu_get_domain_for_dev() will be addressed > seperately, by .... > > > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> > > Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> > > With that fixed: > > Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Can you please send a v3 with updated commit message and all the review/acked tags added? I will pick it up then. Thanks, Joerg
On Fri, Feb 21, 2025 at 12:10:46PM +0100, Joerg Roedel wrote: > Hi Nicolin, > > On Fri, Feb 21, 2025 at 10:28:20AM +0100, Thomas Gleixner wrote: > > On Wed, Feb 19 2025 at 17:31, Nicolin Chen wrote: > > > Fix the MSI cookie UAF by removing the cookie pointer. The translated IOVA > > > address is already known during iommu_dma_prepare_msi() and cannot change. > > > Thus, it can simply be stored as an integer in the MSI descriptor. > > > > > > A following patch will fix the other UAF in iommu_get_domain_for_dev(), by > > > using the IOMMU group mutex. > > > > "A following patch" has no meaning once the current one is > > applied. Simply say: > > > > The other UAF in iommu_get_domain_for_dev() will be addressed > > seperately, by .... > > > > > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> > > > Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> > > > > With that fixed: > > > > Reviewed-by: Thomas Gleixner <tglx@linutronix.de> > > Can you please send a v3 with updated commit message and all the > review/acked tags added? I will pick it up then. Can I send you a PR instead? I'd like it on a branch so we can work on the iommufd specific bits that where in v1. Jason
Hi Jason, On Fri, Feb 21, 2025 at 09:41:12AM -0400, Jason Gunthorpe wrote: > Can I send you a PR instead? I'd like it on a branch so we can work on > the iommufd specific bits that where in v1. Yes, that works as well. Thanks, Joerg
On Fri, Feb 21, 2025 at 10:28:20AM +0100, Thomas Gleixner wrote: > On Wed, Feb 19 2025 at 17:31, Nicolin Chen wrote: > > Fix the MSI cookie UAF by removing the cookie pointer. The translated IOVA > > address is already known during iommu_dma_prepare_msi() and cannot change. > > Thus, it can simply be stored as an integer in the MSI descriptor. > > > > A following patch will fix the other UAF in iommu_get_domain_for_dev(), by > > using the IOMMU group mutex. > > "A following patch" has no meaning once the current one is > applied. Simply say: > > The other UAF in iommu_get_domain_for_dev() will be addressed > seperately, by .... I used this paragraph: The other UAF related to iommu_get_domain_for_dev() will be addressed in patch "iommu: Make iommu_dma_prepare_msi() into a generic operation" by using the IOMMU group mutex. Thanks, Jason
diff --git a/include/linux/msi.h b/include/linux/msi.h index b10093c4d00e..fc4f3774c3af 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -166,6 +166,10 @@ struct msi_desc_data { * @dev: Pointer to the device which uses this descriptor * @msg: The last set MSI message cached for reuse * @affinity: Optional pointer to a cpu affinity mask for this descriptor + * @iommu_msi_iova: Optional shifted IOVA from the IOMMU to override the msi_addr. + * Only used if iommu_msi_shift != 0 + * @iommu_msi_shift: Indicates how many bits of the original address should be + * preserved when using iommu_msi_iova. * @sysfs_attr: Pointer to sysfs device attribute * * @write_msi_msg: Callback that may be called when the MSI message @@ -184,7 +188,8 @@ struct msi_desc { struct msi_msg msg; struct irq_affinity_desc *affinity; #ifdef CONFIG_IRQ_MSI_IOMMU - const void *iommu_cookie; + u64 iommu_msi_iova : 58; + u64 iommu_msi_shift : 6; #endif #ifdef CONFIG_SYSFS struct device_attribute *sysfs_attrs; @@ -285,28 +290,14 @@ struct msi_desc *msi_next_desc(struct device *dev, unsigned int domid, #define msi_desc_to_dev(desc) ((desc)->dev) -#ifdef CONFIG_IRQ_MSI_IOMMU -static inline const void *msi_desc_get_iommu_cookie(struct msi_desc *desc) -{ - return desc->iommu_cookie; -} - -static inline void msi_desc_set_iommu_cookie(struct msi_desc *desc, - const void *iommu_cookie) -{ - desc->iommu_cookie = iommu_cookie; -} -#else -static inline const void *msi_desc_get_iommu_cookie(struct msi_desc *desc) +static inline void msi_desc_set_iommu_msi_iova(struct msi_desc *desc, u64 msi_iova, + unsigned int msi_shift) { - return NULL; -} - -static inline void msi_desc_set_iommu_cookie(struct msi_desc *desc, - const void *iommu_cookie) -{ -} +#ifdef CONFIG_IRQ_MSI_IOMMU + desc->iommu_msi_iova = msi_iova >> msi_shift; + desc->iommu_msi_shift = msi_shift; #endif +} int msi_domain_insert_msi_desc(struct device *dev, unsigned int domid, struct msi_desc *init_desc); diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 2a9fa0c8cc00..0f0caf59023c 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -1815,7 +1815,7 @@ int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr) static DEFINE_MUTEX(msi_prepare_lock); /* see below */ if (!domain || !domain->iova_cookie) { - desc->iommu_cookie = NULL; + msi_desc_set_iommu_msi_iova(desc, 0, 0); return 0; } @@ -1827,11 +1827,12 @@ int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr) mutex_lock(&msi_prepare_lock); msi_page = iommu_dma_get_msi_page(dev, msi_addr, domain); mutex_unlock(&msi_prepare_lock); - - msi_desc_set_iommu_cookie(desc, msi_page); - if (!msi_page) return -ENOMEM; + + msi_desc_set_iommu_msi_iova( + desc, msi_page->iova, + ilog2(cookie_msi_granule(domain->iova_cookie))); return 0; } @@ -1842,18 +1843,15 @@ int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr) */ void iommu_dma_compose_msi_msg(struct msi_desc *desc, struct msi_msg *msg) { - struct device *dev = msi_desc_to_dev(desc); - const struct iommu_domain *domain = iommu_get_domain_for_dev(dev); - const struct iommu_dma_msi_page *msi_page; +#ifdef CONFIG_IRQ_MSI_IOMMU + if (desc->iommu_msi_shift) { + u64 msi_iova = desc->iommu_msi_iova << desc->iommu_msi_shift; - msi_page = msi_desc_get_iommu_cookie(desc); - - if (!domain || !domain->iova_cookie || WARN_ON(!msi_page)) - return; - - msg->address_hi = upper_32_bits(msi_page->iova); - msg->address_lo &= cookie_msi_granule(domain->iova_cookie) - 1; - msg->address_lo += lower_32_bits(msi_page->iova); + msg->address_hi = upper_32_bits(msi_iova); + msg->address_lo = lower_32_bits(msi_iova) | + (msg->address_lo & ((1 << desc->iommu_msi_shift) - 1)); + } +#endif } static int iommu_dma_init(void)