Message ID | dd330453ed31099b5b3b76db02fe79d55aa9bce3.1582899080.git.robin.murphy@arm.com (mailing list archive) |
---|---|
State | Mainlined |
Commit | 08090744f2dbba6b10d38fb17443c81f66798ca0 |
Headers | show |
Series | iommu/io-pgtable-arm: Fix IOVA validation for 32-bit | expand |
On Fri, Feb 28, 2020 at 02:18:55PM +0000, Robin Murphy wrote: > Since we ony support the TTB1 quirk for AArch64 contexts, and > consequently only for 64-bit builds, the sign-extension aspect of the > "are all bits above IAS consistent?" check should implicitly only apply > to 64-bit IOVAs. Change the type of the cast to ensure that 32-bit longs > don't inadvertently get sign-extended, and thus considered invalid, if > they happen to be above 2GB in the TTB0 region. > > Reported-by: Stephan Gerhold <stephan@gerhold.net> > Signed-off-by: Robin Murphy <robin.murphy@arm.com> > > --- > > Logically there may also have been a UBSAN "shift greater than size of > type" warning too, but arch/arm doesn't support UBSAN_SANITIZE_ALL, > and that's now my only easy "spin up a 32-bit VM" option to hand :) > > drivers/iommu/io-pgtable-arm.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) Acked-by: Will Deacon <will@kernel.org> Joerg -- pleae can you take this as a fix for 5.6? Thanks, Will > diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c > index 983b08477e64..04fbd4bf0ff9 100644 > --- a/drivers/iommu/io-pgtable-arm.c > +++ b/drivers/iommu/io-pgtable-arm.c > @@ -468,7 +468,7 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova, > arm_lpae_iopte *ptep = data->pgd; > int ret, lvl = data->start_level; > arm_lpae_iopte prot; > - long iaext = (long)iova >> cfg->ias; > + long iaext = (s64)iova >> cfg->ias; > > /* If no access, then nothing to do */ > if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE))) > @@ -645,7 +645,7 @@ static size_t arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova, > struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops); > struct io_pgtable_cfg *cfg = &data->iop.cfg; > arm_lpae_iopte *ptep = data->pgd; > - long iaext = (long)iova >> cfg->ias; > + long iaext = (s64)iova >> cfg->ias; > > if (WARN_ON(!size || (size & cfg->pgsize_bitmap) != size)) > return 0; > -- > 2.23.0.dirty >
On Mon, Mar 02, 2020 at 11:53:01AM +0000, Will Deacon wrote: > On Fri, Feb 28, 2020 at 02:18:55PM +0000, Robin Murphy wrote: > > Since we ony support the TTB1 quirk for AArch64 contexts, and > > consequently only for 64-bit builds, the sign-extension aspect of the > > "are all bits above IAS consistent?" check should implicitly only apply > > to 64-bit IOVAs. Change the type of the cast to ensure that 32-bit longs > > don't inadvertently get sign-extended, and thus considered invalid, if > > they happen to be above 2GB in the TTB0 region. > > > > Reported-by: Stephan Gerhold <stephan@gerhold.net> > > Signed-off-by: Robin Murphy <robin.murphy@arm.com> > > > > --- > > > > Logically there may also have been a UBSAN "shift greater than size of > > type" warning too, but arch/arm doesn't support UBSAN_SANITIZE_ALL, > > and that's now my only easy "spin up a 32-bit VM" option to hand :) > > > > drivers/iommu/io-pgtable-arm.c | 4 ++-- > > 1 file changed, 2 insertions(+), 2 deletions(-) > > Acked-by: Will Deacon <will@kernel.org> > > Joerg -- pleae can you take this as a fix for 5.6? Done, do you also have a fixes-tag for me? Regards, Joerg
On Mon, Mar 02, 2020 at 05:11:23PM +0100, Joerg Roedel wrote: > On Mon, Mar 02, 2020 at 11:53:01AM +0000, Will Deacon wrote: > > On Fri, Feb 28, 2020 at 02:18:55PM +0000, Robin Murphy wrote: > > > Since we ony support the TTB1 quirk for AArch64 contexts, and > > > consequently only for 64-bit builds, the sign-extension aspect of the > > > "are all bits above IAS consistent?" check should implicitly only apply > > > to 64-bit IOVAs. Change the type of the cast to ensure that 32-bit longs > > > don't inadvertently get sign-extended, and thus considered invalid, if > > > they happen to be above 2GB in the TTB0 region. > > > > > > Reported-by: Stephan Gerhold <stephan@gerhold.net> > > > Signed-off-by: Robin Murphy <robin.murphy@arm.com> > > > > > > --- > > > > > > Logically there may also have been a UBSAN "shift greater than size of > > > type" warning too, but arch/arm doesn't support UBSAN_SANITIZE_ALL, > > > and that's now my only easy "spin up a 32-bit VM" option to hand :) > > > > > > drivers/iommu/io-pgtable-arm.c | 4 ++-- > > > 1 file changed, 2 insertions(+), 2 deletions(-) > > > > Acked-by: Will Deacon <will@kernel.org> > > > > Joerg -- pleae can you take this as a fix for 5.6? > > Done, do you also have a fixes-tag for me? Fixes: db6903010aa5 ("iommu/io-pgtable-arm: Prepare for TTBR1 usage") Although it doesn't need to go to -stable, since this was only introduced during the recent merge window. Will
Hi Robin, On Fri, Feb 28, 2020 at 02:18:55PM +0000, Robin Murphy wrote: > Since we ony support the TTB1 quirk for AArch64 contexts, and > consequently only for 64-bit builds, the sign-extension aspect of the > "are all bits above IAS consistent?" check should implicitly only apply > to 64-bit IOVAs. Change the type of the cast to ensure that 32-bit longs > don't inadvertently get sign-extended, and thus considered invalid, if > they happen to be above 2GB in the TTB0 region. > > Reported-by: Stephan Gerhold <stephan@gerhold.net> > Signed-off-by: Robin Murphy <robin.murphy@arm.com> > Thanks for the patch! Just wanted to report that this patch does indeed fix the problem I had with qcom-venus on ARM32. It's probably too late now, but FWIW: Tested-by: Stephan Gerhold <stephan@gerhold.net> > --- > > Logically there may also have been a UBSAN "shift greater than size of > type" warning too, but arch/arm doesn't support UBSAN_SANITIZE_ALL, > and that's now my only easy "spin up a 32-bit VM" option to hand :) > > drivers/iommu/io-pgtable-arm.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c > index 983b08477e64..04fbd4bf0ff9 100644 > --- a/drivers/iommu/io-pgtable-arm.c > +++ b/drivers/iommu/io-pgtable-arm.c > @@ -468,7 +468,7 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova, > arm_lpae_iopte *ptep = data->pgd; > int ret, lvl = data->start_level; > arm_lpae_iopte prot; > - long iaext = (long)iova >> cfg->ias; > + long iaext = (s64)iova >> cfg->ias; > > /* If no access, then nothing to do */ > if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE))) > @@ -645,7 +645,7 @@ static size_t arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova, > struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops); > struct io_pgtable_cfg *cfg = &data->iop.cfg; > arm_lpae_iopte *ptep = data->pgd; > - long iaext = (long)iova >> cfg->ias; > + long iaext = (s64)iova >> cfg->ias; > > if (WARN_ON(!size || (size & cfg->pgsize_bitmap) != size)) > return 0; > -- > 2.23.0.dirty >
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 983b08477e64..04fbd4bf0ff9 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -468,7 +468,7 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova, arm_lpae_iopte *ptep = data->pgd; int ret, lvl = data->start_level; arm_lpae_iopte prot; - long iaext = (long)iova >> cfg->ias; + long iaext = (s64)iova >> cfg->ias; /* If no access, then nothing to do */ if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE))) @@ -645,7 +645,7 @@ static size_t arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova, struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops); struct io_pgtable_cfg *cfg = &data->iop.cfg; arm_lpae_iopte *ptep = data->pgd; - long iaext = (long)iova >> cfg->ias; + long iaext = (s64)iova >> cfg->ias; if (WARN_ON(!size || (size & cfg->pgsize_bitmap) != size)) return 0;
Since we ony support the TTB1 quirk for AArch64 contexts, and consequently only for 64-bit builds, the sign-extension aspect of the "are all bits above IAS consistent?" check should implicitly only apply to 64-bit IOVAs. Change the type of the cast to ensure that 32-bit longs don't inadvertently get sign-extended, and thus considered invalid, if they happen to be above 2GB in the TTB0 region. Reported-by: Stephan Gerhold <stephan@gerhold.net> Signed-off-by: Robin Murphy <robin.murphy@arm.com> --- Logically there may also have been a UBSAN "shift greater than size of type" warning too, but arch/arm doesn't support UBSAN_SANITIZE_ALL, and that's now my only easy "spin up a 32-bit VM" option to hand :) drivers/iommu/io-pgtable-arm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)