Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1719178 > unrolled thread
| Started by | Baoquan He <bhe@redhat.com> |
|---|---|
| First post | 2017-08-24 14:00 +0200 |
| Last post | 2017-08-24 15:10 +0200 |
| Articles | 7 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH] iommu/amd: Check if domain is NULL before dereference it Baoquan He <bhe@redhat.com> - 2017-08-24 14:00 +0200
Re: [PATCH] iommu/amd: Check if domain is NULL before dereference it Dan Carpenter <dan.carpenter@oracle.com> - 2017-08-24 14:20 +0200
Re: [PATCH] iommu/amd: Check if domain is NULL before dereference it Baoquan He <bhe@redhat.com> - 2017-08-24 14:30 +0200
Re: [PATCH] iommu/amd: Check if domain is NULL before dereference it Dan Carpenter <dan.carpenter@oracle.com> - 2017-08-24 14:40 +0200
Re: [PATCH] iommu/amd: Check if domain is NULL before dereference it Baoquan He <bhe@redhat.com> - 2017-08-24 14:50 +0200
Re: [PATCH] iommu/amd: Check if domain is NULL before dereference it Dan Carpenter <dan.carpenter@oracle.com> - 2017-08-24 15:00 +0200
Re: [PATCH] iommu/amd: Check if domain is NULL before dereference it Baoquan He <bhe@redhat.com> - 2017-08-24 15:10 +0200
| From | Baoquan He <bhe@redhat.com> |
|---|---|
| Date | 2017-08-24 14:00 +0200 |
| Subject | [PATCH] iommu/amd: Check if domain is NULL before dereference it |
| Message-ID | <uhYXL-63x-9@gated-at.bofh.it> |
In get_domain(), 'domain' could still be NULL before it's passed to dma_ops_domain() to dereference. For safety, check if 'domain' is NULL before passing to dma_ops_domain(). Reported-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Baoquan He <bhe@redhat.com> --- drivers/iommu/amd_iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 16f1e6af00b0..2e2d5e6a13b3 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -2262,7 +2262,7 @@ static struct protection_domain *get_domain(struct device *dev) domain = to_pdomain(io_domain); attach_device(dev, domain); } - if (!dma_ops_domain(domain)) + if (domain && !dma_ops_domain(domain)) return ERR_PTR(-EBUSY); return domain; -- 2.5.5
[toc] | [next] | [standalone]
| From | Dan Carpenter <dan.carpenter@oracle.com> |
|---|---|
| Date | 2017-08-24 14:20 +0200 |
| Message-ID | <uhZh7-6r5-13@gated-at.bofh.it> |
| In reply to | #1719178 |
On Thu, Aug 24, 2017 at 07:56:47PM +0800, Baoquan He wrote: > In get_domain(), 'domain' could still be NULL before it's passed to > dma_ops_domain() to dereference. For safety, check if 'domain' is > NULL before passing to dma_ops_domain(). > > Reported-by: Dan Carpenter <dan.carpenter@oracle.com> > Signed-off-by: Baoquan He <bhe@redhat.com> > --- > drivers/iommu/amd_iommu.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c > index 16f1e6af00b0..2e2d5e6a13b3 100644 > --- a/drivers/iommu/amd_iommu.c > +++ b/drivers/iommu/amd_iommu.c > @@ -2262,7 +2262,7 @@ static struct protection_domain *get_domain(struct device *dev) > domain = to_pdomain(io_domain); > attach_device(dev, domain); > } > - if (!dma_ops_domain(domain)) > + if (domain && !dma_ops_domain(domain)) > return ERR_PTR(-EBUSY); > > return domain; This still doesn't look right. None of the callers can handle a NULL domain. regards, dan carpenter
[toc] | [prev] | [next] | [standalone]
| From | Baoquan He <bhe@redhat.com> |
|---|---|
| Date | 2017-08-24 14:30 +0200 |
| Message-ID | <uhZqO-6v9-3@gated-at.bofh.it> |
| In reply to | #1719189 |
On 08/24/17 at 03:11pm, Dan Carpenter wrote: > On Thu, Aug 24, 2017 at 07:56:47PM +0800, Baoquan He wrote: > > In get_domain(), 'domain' could still be NULL before it's passed to > > dma_ops_domain() to dereference. For safety, check if 'domain' is > > NULL before passing to dma_ops_domain(). > > > > Reported-by: Dan Carpenter <dan.carpenter@oracle.com> > > Signed-off-by: Baoquan He <bhe@redhat.com> > > --- > > drivers/iommu/amd_iommu.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c > > index 16f1e6af00b0..2e2d5e6a13b3 100644 > > --- a/drivers/iommu/amd_iommu.c > > +++ b/drivers/iommu/amd_iommu.c > > @@ -2262,7 +2262,7 @@ static struct protection_domain *get_domain(struct device *dev) > > domain = to_pdomain(io_domain); > > attach_device(dev, domain); > > } > > - if (!dma_ops_domain(domain)) > > + if (domain && !dma_ops_domain(domain)) > > return ERR_PTR(-EBUSY); > > > > return domain; > > This still doesn't look right. None of the callers can handle a NULL > domain. Here the NULL domain is on purpose. In kdump kernel if iommu is pre-enabled, just stop attach the device to domain until the device driver init. So here in driver init when call get_domain(), if found get_dev_data(dev)->defer_attach is true, we just do the attachment of device to domain. Not sure if I got what you mean about 'callers'.
[toc] | [prev] | [next] | [standalone]
| From | Dan Carpenter <dan.carpenter@oracle.com> |
|---|---|
| Date | 2017-08-24 14:40 +0200 |
| Message-ID | <uhZAv-6z1-25@gated-at.bofh.it> |
| In reply to | #1719193 |
Take a look at this code for example. But all the places which call
get_domain() are the same:
drivers/iommu/amd_iommu.c
2648 page = virt_to_page(virt_addr);
2649 size = PAGE_ALIGN(size);
2650
2651 domain = get_domain(dev);
^^^^^^^^^^^^^^
imagined get_domain() returns NULL.
2652 if (IS_ERR(domain))
2653 goto free_mem;
2654
2655 dma_dom = to_dma_ops_domain(domain);
^^^^^^^^^^^^^^^^^^^^^^^^^
This will Oops.
2656
regards,
dan carpenter
[toc] | [prev] | [next] | [standalone]
| From | Baoquan He <bhe@redhat.com> |
|---|---|
| Date | 2017-08-24 14:50 +0200 |
| Message-ID | <uhZK9-6D7-1@gated-at.bofh.it> |
| In reply to | #1719201 |
On 08/24/17 at 03:32pm, Dan Carpenter wrote: > Take a look at this code for example. But all the places which call > get_domain() are the same: > > drivers/iommu/amd_iommu.c > 2648 page = virt_to_page(virt_addr); > 2649 size = PAGE_ALIGN(size); > 2650 > 2651 domain = get_domain(dev); > ^^^^^^^^^^^^^^ > imagined get_domain() returns NULL. > > 2652 if (IS_ERR(domain)) > 2653 goto free_mem; > 2654 > 2655 dma_dom = to_dma_ops_domain(domain); > ^^^^^^^^^^^^^^^^^^^^^^^^^ > This will Oops. I see, it's a problem. Thanks for telling! How about below change? But I am not very sure which errno should be picked, seems the latter one, EBUSY is better since it has passed the check_device() checking. diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 16f1e6af00b0..2d7d04472555 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -2262,6 +2262,9 @@ static struct protection_domain *get_domain(struct device *dev) domain = to_pdomain(io_domain); attach_device(dev, domain); } + if (domain == NULL) + return ERR_PTR(-EBUSY); + if (!dma_ops_domain(domain)) return ERR_PTR(-EBUSY); -- 2.5.5
[toc] | [prev] | [next] | [standalone]
| From | Dan Carpenter <dan.carpenter@oracle.com> |
|---|---|
| Date | 2017-08-24 15:00 +0200 |
| Message-ID | <uhZTQ-6H8-11@gated-at.bofh.it> |
| In reply to | #1719203 |
On Thu, Aug 24, 2017 at 08:47:33PM +0800, Baoquan He wrote: > On 08/24/17 at 03:32pm, Dan Carpenter wrote: > > Take a look at this code for example. But all the places which call > > get_domain() are the same: > > > > drivers/iommu/amd_iommu.c > > 2648 page = virt_to_page(virt_addr); > > 2649 size = PAGE_ALIGN(size); > > 2650 > > 2651 domain = get_domain(dev); > > ^^^^^^^^^^^^^^ > > imagined get_domain() returns NULL. > > > > 2652 if (IS_ERR(domain)) > > 2653 goto free_mem; > > 2654 > > 2655 dma_dom = to_dma_ops_domain(domain); > > ^^^^^^^^^^^^^^^^^^^^^^^^^ > > This will Oops. > > I see, it's a problem. Thanks for telling! > > How about below change? But I am not very sure which errno should be > picked, seems the latter one, EBUSY is better since it has passed the > check_device() checking. Looks good to me. You know better than I do which errno is best, so I'll leave that to you. regards, dan carpenter
[toc] | [prev] | [next] | [standalone]
| From | Baoquan He <bhe@redhat.com> |
|---|---|
| Date | 2017-08-24 15:10 +0200 |
| Message-ID | <ui03w-70q-15@gated-at.bofh.it> |
| In reply to | #1719208 |
On 08/24/17 at 03:53pm, Dan Carpenter wrote: > On Thu, Aug 24, 2017 at 08:47:33PM +0800, Baoquan He wrote: > > On 08/24/17 at 03:32pm, Dan Carpenter wrote: > > > Take a look at this code for example. But all the places which call > > > get_domain() are the same: > > > > > > drivers/iommu/amd_iommu.c > > > 2648 page = virt_to_page(virt_addr); > > > 2649 size = PAGE_ALIGN(size); > > > 2650 > > > 2651 domain = get_domain(dev); > > > ^^^^^^^^^^^^^^ > > > imagined get_domain() returns NULL. > > > > > > 2652 if (IS_ERR(domain)) > > > 2653 goto free_mem; > > > 2654 > > > 2655 dma_dom = to_dma_ops_domain(domain); > > > ^^^^^^^^^^^^^^^^^^^^^^^^^ > > > This will Oops. > > > > I see, it's a problem. Thanks for telling! > > > > How about below change? But I am not very sure which errno should be > > picked, seems the latter one, EBUSY is better since it has passed the > > check_device() checking. > > Looks good to me. You know better than I do which errno is best, so > I'll leave that to you. OK, thanks! Then let me post v2 with it.
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web