All of lore.kernel.org
 help / color / mirror / Atom feed
From: Souptick Joarder <jrdr.linux@gmail.com>
To: "Marek Marczykowski-Górecki" <marmarek@invisiblethingslab.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Matthew Wilcox <willy@infradead.org>,
	Michal Hocko <mhocko@suse.com>,
	Boris Ostrovsky <boris.ostrovsky@oracle.com>,
	Juergen Gross <jgross@suse.com>,
	Russell King - ARM Linux <linux@armlinux.org.uk>,
	robin.murphy@arm.com, xen-devel@lists.xenproject.org,
	linux-kernel@vger.kernel.org, Linux-MM <linux-mm@kvack.org>
Subject: Re: [Xen-devel] [PATCH v4 8/9] xen/gntdev.c: Convert to use vm_map_pages()
Date: Mon, 29 Jul 2019 14:02:54 +0530	[thread overview]
Message-ID: <CAFqt6zY+07JBxAVfMqb+X78mXwFOj2VBh0nbR2tGnQOP9RrNkQ@mail.gmail.com> (raw)
In-Reply-To: <CAFqt6zaMDnpB-RuapQAyYAub1t7oSdHH_pTD=f5k-s327ZvqMA@mail.gmail.com>

On Mon, Jul 29, 2019 at 1:35 PM Souptick Joarder <jrdr.linux@gmail.com> wrote:
>
> On Sun, Jul 28, 2019 at 11:36 PM Marek Marczykowski-Górecki
> <marmarek@invisiblethingslab.com> wrote:
> >
> > On Fri, Feb 15, 2019 at 08:18:31AM +0530, Souptick Joarder wrote:
> > > Convert to use vm_map_pages() to map range of kernel
> > > memory to user vma.
> > >
> > > map->count is passed to vm_map_pages() and internal API
> > > verify map->count against count ( count = vma_pages(vma))
> > > for page array boundary overrun condition.
> >
> > This commit breaks gntdev driver. If vma->vm_pgoff > 0, vm_map_pages
> > will:
> >  - use map->pages starting at vma->vm_pgoff instead of 0
>
> The actual code ignores vma->vm_pgoff > 0 scenario and mapped
> the entire map->pages[i]. Why the entire map->pages[i] needs to be mapped
> if vma->vm_pgoff > 0 (in original code) ?
>
> are you referring to set vma->vm_pgoff = 0 irrespective of value passed
> from user space ? If yes, using vm_map_pages_zero() is an alternate
> option.
>
>
> >  - verify map->count against vma_pages()+vma->vm_pgoff instead of just
> >    vma_pages().
>
> In original code ->
>
> diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
> index 559d4b7f807d..469dfbd6cf90 100644
> --- a/drivers/xen/gntdev.c
> +++ b/drivers/xen/gntdev.c
> @@ -1084,7 +1084,7 @@ static int gntdev_mmap(struct file *flip, struct
> vm_area_struct *vma)
> int index = vma->vm_pgoff;
> int count = vma_pages(vma);
>
> Count is user passed value.
>
> struct gntdev_grant_map *map;
> - int i, err = -EINVAL;
> + int err = -EINVAL;
> if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED))
> return -EINVAL;
> @@ -1145,12 +1145,9 @@ static int gntdev_mmap(struct file *flip,
> struct vm_area_struct *vma)
> goto out_put_map;
> if (!use_ptemod) {
> - for (i = 0; i < count; i++) {
> - err = vm_insert_page(vma, vma->vm_start + i*PAGE_SIZE,
> - map->pages[i]);
>
> and when count > i , we end up with trying to map memory outside
> boundary of map->pages[i], which was not correct.

typo.
s/count > i / count > map->count
>
> - if (err)
> - goto out_put_map;
> - }
> + err = vm_map_pages(vma, map->pages, map->count);
> + if (err)
> + goto out_put_map;
>
> With this commit, inside __vm_map_pages(), we have addressed this scenario.
>
> +static int __vm_map_pages(struct vm_area_struct *vma, struct page **pages,
> + unsigned long num, unsigned long offset)
> +{
> + unsigned long count = vma_pages(vma);
> + unsigned long uaddr = vma->vm_start;
> + int ret, i;
> +
> + /* Fail if the user requested offset is beyond the end of the object */
> + if (offset > num)
> + return -ENXIO;
> +
> + /* Fail if the user requested size exceeds available object size */
> + if (count > num - offset)
> + return -ENXIO;
>
> By checking count > num -offset. (considering vma->vm_pgoff != 0 as well).
> So we will never cross the boundary of map->pages[i].
>
>
> >
> > In practice, this breaks using a single gntdev FD for mapping multiple
> > grants.
>
> How ?
>
> >
> > It looks like vm_map_pages() is not a good fit for this code and IMO it
> > should be reverted.
>
> Did you hit any issue around this code in real time ?
>
>
> >
> > > Signed-off-by: Souptick Joarder <jrdr.linux@gmail.com>
> > > Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
> > > ---
> > >  drivers/xen/gntdev.c | 11 ++++-------
> > >  1 file changed, 4 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
> > > index 5efc5ee..5d64262 100644
> > > --- a/drivers/xen/gntdev.c
> > > +++ b/drivers/xen/gntdev.c
> > > @@ -1084,7 +1084,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
> > >       int index = vma->vm_pgoff;
> > >       int count = vma_pages(vma);
> > >       struct gntdev_grant_map *map;
> > > -     int i, err = -EINVAL;
> > > +     int err = -EINVAL;
> > >
> > >       if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED))
> > >               return -EINVAL;
> > > @@ -1145,12 +1145,9 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
> > >               goto out_put_map;
> > >
> > >       if (!use_ptemod) {
> > > -             for (i = 0; i < count; i++) {
> > > -                     err = vm_insert_page(vma, vma->vm_start + i*PAGE_SIZE,
> > > -                             map->pages[i]);
> > > -                     if (err)
> > > -                             goto out_put_map;
> > > -             }
> > > +             err = vm_map_pages(vma, map->pages, map->count);
> > > +             if (err)
> > > +                     goto out_put_map;
> > >       } else {
> > >  #ifdef CONFIG_X86
> > >               /*
> >
> > --
> > Best Regards,
> > Marek Marczykowski-Górecki
> > Invisible Things Lab
> > A: Because it messes up the order in which people normally read text.
> > Q: Why is top-posting such a bad thing?

WARNING: multiple messages have this Message-ID (diff)
From: Souptick Joarder <jrdr.linux@gmail.com>
To: "Marek Marczykowski-Górecki" <marmarek@invisiblethingslab.com>
Cc: Juergen Gross <jgross@suse.com>, Michal Hocko <mhocko@suse.com>,
	Russell King - ARM Linux <linux@armlinux.org.uk>,
	Matthew Wilcox <willy@infradead.org>,
	linux-kernel@vger.kernel.org, Linux-MM <linux-mm@kvack.org>,
	xen-devel@lists.xenproject.org,
	Andrew Morton <akpm@linux-foundation.org>,
	robin.murphy@arm.com,
	Boris Ostrovsky <boris.ostrovsky@oracle.com>
Subject: Re: [Xen-devel] [PATCH v4 8/9] xen/gntdev.c: Convert to use vm_map_pages()
Date: Mon, 29 Jul 2019 14:02:54 +0530	[thread overview]
Message-ID: <CAFqt6zY+07JBxAVfMqb+X78mXwFOj2VBh0nbR2tGnQOP9RrNkQ@mail.gmail.com> (raw)
In-Reply-To: <CAFqt6zaMDnpB-RuapQAyYAub1t7oSdHH_pTD=f5k-s327ZvqMA@mail.gmail.com>

On Mon, Jul 29, 2019 at 1:35 PM Souptick Joarder <jrdr.linux@gmail.com> wrote:
>
> On Sun, Jul 28, 2019 at 11:36 PM Marek Marczykowski-Górecki
> <marmarek@invisiblethingslab.com> wrote:
> >
> > On Fri, Feb 15, 2019 at 08:18:31AM +0530, Souptick Joarder wrote:
> > > Convert to use vm_map_pages() to map range of kernel
> > > memory to user vma.
> > >
> > > map->count is passed to vm_map_pages() and internal API
> > > verify map->count against count ( count = vma_pages(vma))
> > > for page array boundary overrun condition.
> >
> > This commit breaks gntdev driver. If vma->vm_pgoff > 0, vm_map_pages
> > will:
> >  - use map->pages starting at vma->vm_pgoff instead of 0
>
> The actual code ignores vma->vm_pgoff > 0 scenario and mapped
> the entire map->pages[i]. Why the entire map->pages[i] needs to be mapped
> if vma->vm_pgoff > 0 (in original code) ?
>
> are you referring to set vma->vm_pgoff = 0 irrespective of value passed
> from user space ? If yes, using vm_map_pages_zero() is an alternate
> option.
>
>
> >  - verify map->count against vma_pages()+vma->vm_pgoff instead of just
> >    vma_pages().
>
> In original code ->
>
> diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
> index 559d4b7f807d..469dfbd6cf90 100644
> --- a/drivers/xen/gntdev.c
> +++ b/drivers/xen/gntdev.c
> @@ -1084,7 +1084,7 @@ static int gntdev_mmap(struct file *flip, struct
> vm_area_struct *vma)
> int index = vma->vm_pgoff;
> int count = vma_pages(vma);
>
> Count is user passed value.
>
> struct gntdev_grant_map *map;
> - int i, err = -EINVAL;
> + int err = -EINVAL;
> if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED))
> return -EINVAL;
> @@ -1145,12 +1145,9 @@ static int gntdev_mmap(struct file *flip,
> struct vm_area_struct *vma)
> goto out_put_map;
> if (!use_ptemod) {
> - for (i = 0; i < count; i++) {
> - err = vm_insert_page(vma, vma->vm_start + i*PAGE_SIZE,
> - map->pages[i]);
>
> and when count > i , we end up with trying to map memory outside
> boundary of map->pages[i], which was not correct.

typo.
s/count > i / count > map->count
>
> - if (err)
> - goto out_put_map;
> - }
> + err = vm_map_pages(vma, map->pages, map->count);
> + if (err)
> + goto out_put_map;
>
> With this commit, inside __vm_map_pages(), we have addressed this scenario.
>
> +static int __vm_map_pages(struct vm_area_struct *vma, struct page **pages,
> + unsigned long num, unsigned long offset)
> +{
> + unsigned long count = vma_pages(vma);
> + unsigned long uaddr = vma->vm_start;
> + int ret, i;
> +
> + /* Fail if the user requested offset is beyond the end of the object */
> + if (offset > num)
> + return -ENXIO;
> +
> + /* Fail if the user requested size exceeds available object size */
> + if (count > num - offset)
> + return -ENXIO;
>
> By checking count > num -offset. (considering vma->vm_pgoff != 0 as well).
> So we will never cross the boundary of map->pages[i].
>
>
> >
> > In practice, this breaks using a single gntdev FD for mapping multiple
> > grants.
>
> How ?
>
> >
> > It looks like vm_map_pages() is not a good fit for this code and IMO it
> > should be reverted.
>
> Did you hit any issue around this code in real time ?
>
>
> >
> > > Signed-off-by: Souptick Joarder <jrdr.linux@gmail.com>
> > > Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
> > > ---
> > >  drivers/xen/gntdev.c | 11 ++++-------
> > >  1 file changed, 4 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
> > > index 5efc5ee..5d64262 100644
> > > --- a/drivers/xen/gntdev.c
> > > +++ b/drivers/xen/gntdev.c
> > > @@ -1084,7 +1084,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
> > >       int index = vma->vm_pgoff;
> > >       int count = vma_pages(vma);
> > >       struct gntdev_grant_map *map;
> > > -     int i, err = -EINVAL;
> > > +     int err = -EINVAL;
> > >
> > >       if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED))
> > >               return -EINVAL;
> > > @@ -1145,12 +1145,9 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
> > >               goto out_put_map;
> > >
> > >       if (!use_ptemod) {
> > > -             for (i = 0; i < count; i++) {
> > > -                     err = vm_insert_page(vma, vma->vm_start + i*PAGE_SIZE,
> > > -                             map->pages[i]);
> > > -                     if (err)
> > > -                             goto out_put_map;
> > > -             }
> > > +             err = vm_map_pages(vma, map->pages, map->count);
> > > +             if (err)
> > > +                     goto out_put_map;
> > >       } else {
> > >  #ifdef CONFIG_X86
> > >               /*
> >
> > --
> > Best Regards,
> > Marek Marczykowski-Górecki
> > Invisible Things Lab
> > A: Because it messes up the order in which people normally read text.
> > Q: Why is top-posting such a bad thing?

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  reply	other threads:[~2019-07-29  8:33 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-15  2:48 [PATCH v4 8/9] xen/gntdev.c: Convert to use vm_map_pages() Souptick Joarder
2019-07-28 18:06 ` [Xen-devel] " Marek Marczykowski-Górecki
2019-07-28 18:06   ` Marek Marczykowski-Górecki
2019-07-29  8:05   ` Souptick Joarder
2019-07-29  8:05     ` Souptick Joarder
2019-07-29  8:05     ` Souptick Joarder
2019-07-29  8:32     ` Souptick Joarder [this message]
2019-07-29  8:32       ` Souptick Joarder
2019-07-29  8:32       ` Souptick Joarder
2019-07-29 13:36       ` Marek Marczykowski-Górecki
2019-07-29 13:36         ` Marek Marczykowski-Górecki
2019-07-30  6:03         ` Souptick Joarder
2019-07-30  6:03           ` Souptick Joarder
2019-07-30  6:03           ` Souptick Joarder
2019-07-30 14:05           ` Boris Ostrovsky
2019-07-30 14:05             ` Boris Ostrovsky
2019-07-30 14:22             ` Marek Marczykowski-Górecki
2019-07-30 14:22               ` Marek Marczykowski-Górecki
2019-07-30 14:52               ` Souptick Joarder
2019-07-30 14:52                 ` Souptick Joarder
2019-07-30 14:52                 ` Souptick Joarder
2019-07-30 15:01                 ` Marek Marczykowski-Górecki
2019-07-30 15:01                   ` Marek Marczykowski-Górecki

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=CAFqt6zY+07JBxAVfMqb+X78mXwFOj2VBh0nbR2tGnQOP9RrNkQ@mail.gmail.com \
    --to=jrdr.linux@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=boris.ostrovsky@oracle.com \
    --cc=jgross@suse.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux@armlinux.org.uk \
    --cc=marmarek@invisiblethingslab.com \
    --cc=mhocko@suse.com \
    --cc=robin.murphy@arm.com \
    --cc=willy@infradead.org \
    --cc=xen-devel@lists.xenproject.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.