lkml.org 
[lkml]   [2020]   [Apr]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.6 107/129] iommu/virtio: Fix freeing of incomplete domains
    Date
    From: Jean-Philippe Brucker <jean-philippe@linaro.org>

    [ Upstream commit 7062af3ed2ba451029e3733d9f677c68f5ea9e77 ]

    Calling viommu_domain_free() on a domain that hasn't been finalised (not
    attached to any device, for example) can currently cause an Oops,
    because we attempt to call ida_free() on ID 0, which may either be
    unallocated or used by another domain.

    Only initialise the vdomain->viommu pointer, which denotes a finalised
    domain, at the end of a successful viommu_domain_finalise().

    Fixes: edcd69ab9a32 ("iommu: Add virtio-iommu driver")
    Reported-by: Eric Auger <eric.auger@redhat.com>
    Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
    Reviewed-by: Robin Murphy <robin.murphy@arm.com>
    Link: https://lore.kernel.org/r/20200326093558.2641019-3-jean-philippe@linaro.org
    Signed-off-by: Joerg Roedel <jroedel@suse.de>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/iommu/virtio-iommu.c | 16 +++++++++-------
    1 file changed, 9 insertions(+), 7 deletions(-)

    diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
    index cce329d71fbad..5eed75cd121f1 100644
    --- a/drivers/iommu/virtio-iommu.c
    +++ b/drivers/iommu/virtio-iommu.c
    @@ -613,18 +613,20 @@ static int viommu_domain_finalise(struct viommu_dev *viommu,
    int ret;
    struct viommu_domain *vdomain = to_viommu_domain(domain);

    - vdomain->viommu = viommu;
    - vdomain->map_flags = viommu->map_flags;
    + ret = ida_alloc_range(&viommu->domain_ids, viommu->first_domain,
    + viommu->last_domain, GFP_KERNEL);
    + if (ret < 0)
    + return ret;
    +
    + vdomain->id = (unsigned int)ret;

    domain->pgsize_bitmap = viommu->pgsize_bitmap;
    domain->geometry = viommu->geometry;

    - ret = ida_alloc_range(&viommu->domain_ids, viommu->first_domain,
    - viommu->last_domain, GFP_KERNEL);
    - if (ret >= 0)
    - vdomain->id = (unsigned int)ret;
    + vdomain->map_flags = viommu->map_flags;
    + vdomain->viommu = viommu;

    - return ret > 0 ? 0 : ret;
    + return 0;
    }

    static void viommu_domain_free(struct iommu_domain *domain)
    --
    2.20.1
    \
     
     \ /
      Last update: 2020-04-15 14:58    [W:2.839 / U:0.084 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site