linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Dmitry Kalinkin <dmitry.kalinkin@gmail.com>
To: Dan Carpenter <dan.carpenter@oracle.com>
Cc: linux-kernel@vger.kernel.org, devel@driverdev.osuosl.org,
	Martyn Welch <martyn.welch@ge.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Manohar Vanga <manohar.vanga@gmail.com>,
	Igor Alekseev <igor.alekseev@itep.ru>
Subject: Re: [PATCH 6/6] staging: vme_user: provide DMA functionality
Date: Fri, 22 May 2015 01:12:19 +0300	[thread overview]
Message-ID: <DCA609ED-9931-4020-8948-AE92D02C6820@gmail.com> (raw)
In-Reply-To: <20150519091846.GB4150@mwanda>

On Tue, May 19, 2015 at 12:18 PM, Dan Carpenter <dan.carpenter@oracle.com> wrote:
> On Mon, May 18, 2015 at 09:56:33PM +0300, Dmitry Kalinkin wrote:
>> 
>> +     for_each_sg(sgt->sgl, sg, sg_count, i) {
>> +             struct vme_dma_attr *pci_attr, *vme_attr, *dest, *src;
>> +             dma_addr_t hw_address = sg_dma_address(sg);
>> +             unsigned int hw_len = sg_dma_len(sg);
>> +
>> +             vme_attr = vme_dma_vme_attribute(dma_op->vme_addr + pos,
>                                                 ^^^^^^^^^^^^^^^^^^^^^^
> 
> ->vme_addr comes from the user and we don't seem to have done any
> validation that it's correct.  This addition can overflow.  How is this
> safe?  (This is not a rhetorical question, I am a newbie in this).
> 
This expression calculates address on the VME bus, where we already have
full access. There shouldn't have security implications. Such transfer will
most likely wrap or cause DMA transfer error (gives EIO).

We could add an additional check:

diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c
index d8aa03b..cb0fc63 100644
--- a/drivers/staging/vme/devices/vme_user.c
+++ b/drivers/staging/vme/devices/vme_user.c
@@ -515,6 +515,11 @@ static ssize_t vme_user_dma_ioctl(unsigned int minor,
        if (dma_op->count == 0)
                return 0;
 
+       ret = vme_check_window(dma_op->aspace, dma_op->vme_addr,
+                              dma_op->count);
+       if (ret)
+               return ret;
+
        nr_pages = (offset + dma_op->count + PAGE_SIZE - 1) >> PAGE_SHIFT;
        dir = dma_op->write ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
 
diff --git a/drivers/vme/vme.c b/drivers/vme/vme.c
index 6bab2c4..50cabc3 100644
--- a/drivers/vme/vme.c
+++ b/drivers/vme/vme.c
@@ -177,7 +177,7 @@ size_t vme_get_size(struct vme_resource *resource)
 }
 EXPORT_SYMBOL(vme_get_size);
 
-static int vme_check_window(u32 aspace, unsigned long long vme_base,
+int vme_check_window(u32 aspace, unsigned long long vme_base,
        unsigned long long size)
 {
        int retval = 0;
@@ -199,10 +199,8 @@ static int vme_check_window(u32 aspace, unsigned long long vme_base,
                        retval = -EFAULT;
                break;
        case VME_A64:
-               /*
-                * Any value held in an unsigned long long can be used as the
-                * base
-                */
+               if (vme_base > VME_A64_MAX - size)
+                       retval = -EFAULT;
                break;
        case VME_CRCSR:
                if (((vme_base + size) > VME_CRCSR_MAX) ||
@@ -223,6 +221,7 @@ static int vme_check_window(u32 aspace, unsigned long long vme_base,
 
        return retval;
 }
+EXPORT_SYMBOL(vme_check_window);
 
 /*
  * Request a slave image with specific attributes, return some unique
diff --git a/include/linux/vme.h b/include/linux/vme.h
index 79242e9..cfff272 100644
--- a/include/linux/vme.h
+++ b/include/linux/vme.h
@@ -120,6 +120,8 @@ void vme_free_consistent(struct vme_resource *, size_t,  void *,
        dma_addr_t);
 
 size_t vme_get_size(struct vme_resource *);
+int vme_check_window(u32 aspace, unsigned long long vme_base,
+                     unsigned long long size);
 
 struct vme_resource *vme_slave_request(struct vme_dev *, u32, u32);
 int vme_slave_set(struct vme_resource *, int, unsigned long long,

>> +     nr_pages = (offset + dma_op->count + PAGE_SIZE - 1) >> PAGE_SHIFT;
>> +     dir = dma_op->write ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
>> +
>> +     pages = kmalloc_array(nr_pages, sizeof(pages[0]), GFP_KERNEL);
> 
> This lets the user try allocate huge ammounts of RAM.  Is there no
> reasonable max size we can use?
> 
We could limit operation size by 64 MiB and do an partial read for any bigger request.

> This file is all indented poorly, but these patches adds a bunch of new
> ones so they make a bad situation worse.
> 
>        got_pages = get_user_pages_fast(dma_op->buf_vaddr, nr_pages,
>                                        !dma_op->write, pages);
> 
> You sometimes might have to use spaces to make things align correctly.
> 
>        got_pages = some_fake_name(dma_op->buf_vaddr, nr_pages,
>                                   !dma_op->write, pages);
> 
> [tab][tab][tab][tab][space][space][space][space]!dma_op->write, pages);
Will fix this.


Thank you.

Cheers,
Dmitry


  reply	other threads:[~2015-05-21 22:12 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-18 18:56 [PATCH 0/6] vme: DMA improvements Dmitry Kalinkin
2015-05-18 18:56 ` [PATCH 1/6] Documentation: mention vme_master_mmap() in VME API Dmitry Kalinkin
2015-05-18 18:56 ` [PATCH 2/6] vme: tsi148: fix DMA lists longer that one item Dmitry Kalinkin
2015-05-18 18:56 ` [PATCH 3/6] vme: tsi148: fix first DMA item mapping Dmitry Kalinkin
2015-05-18 18:56 ` [PATCH 4/6] vme: stop DMA transfer on interruption Dmitry Kalinkin
2015-05-18 18:56 ` [PATCH 5/6] staging: vme_user: refactor llseek to switch(){} Dmitry Kalinkin
2015-05-18 18:56 ` [PATCH 6/6] staging: vme_user: provide DMA functionality Dmitry Kalinkin
2015-05-19  9:18   ` Dan Carpenter
2015-05-21 22:12     ` Dmitry Kalinkin [this message]
2015-05-22  7:59       ` Dan Carpenter

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=DCA609ED-9931-4020-8948-AE92D02C6820@gmail.com \
    --to=dmitry.kalinkin@gmail.com \
    --cc=dan.carpenter@oracle.com \
    --cc=devel@driverdev.osuosl.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=igor.alekseev@itep.ru \
    --cc=linux-kernel@vger.kernel.org \
    --cc=manohar.vanga@gmail.com \
    --cc=martyn.welch@ge.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).