All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: James Bottomley <James.Bottomley@HansenPartnership.com>
Cc: Helge Deller <deller@gmx.de>,
	linux-kernel@vger.kernel.org, Arnd Bergmann <arnd@arndb.de>,
	linux-arch@vger.kernel.org,
	"James E.J. Bottomley" <jejb@parisc-linux.org>,
	linux-parisc@vger.kernel.org
Subject: Re: [PATCH repost 12/16] parisc/uaccess: fix sparse errors
Date: Wed, 31 Dec 2014 20:38:24 +0200	[thread overview]
Message-ID: <20141231183824.GA32430@redhat.com> (raw)
In-Reply-To: <1420046240.2085.3.camel@HansenPartnership.com>

On Wed, Dec 31, 2014 at 09:17:20AM -0800, James Bottomley wrote:
> On Sat, 2014-12-27 at 18:14 +0200, Michael S. Tsirkin wrote:
> > On Thu, Dec 25, 2014 at 11:37:45PM +0100, Helge Deller wrote:
> > > Hi Michael,
> > > 
> > > On 12/25/2014 10:29 AM, Michael S. Tsirkin wrote:
> > > >virtio wants to read bitwise types from userspace using get_user.  At the
> > > 
> > > I don't know the virtio code much yet, but does it makes sense to read bitwise types?
> > > Will virtio then get possible troubles because of endianess correct as well?
> > 
> > There's no conversion: we are reading from __virtio16 __user *
> > pointer into __virtio16 v value.
> > 
> > > Do you have a code example, or the sparse error message ?
> > > 
> > > Helge
> > 
> > Sure. the code is upstream now.
> > The warning is below.
> > 
> > sparse warnings: (new ones prefixed by >>)
> > 
> > >> drivers/vhost/vringh.c:554:18: sparse: cast to restricted __virtio16
> > 
> > vim +554 drivers/vhost/vringh.c
> > 
> >    538                                                           __virtio16 *p, u16 val))
> >    539  {
> >    540          if (!vrh->event_indices) {
> >    541                  /* Old-school; update flags. */
> >    542                  if (putu16(vrh, &vrh->vring.used->flags,
> >    543                             VRING_USED_F_NO_NOTIFY)) {
> >    544                          vringh_bad("Setting used flags %p",
> >    545                                     &vrh->vring.used->flags);
> >    546                  }
> >    547          }
> >    548  }
> >    549
> >    550  /* Userspace access helpers: in this case, addresses are really userspace. */
> >    551  static inline int getu16_user(const struct vringh *vrh, u16 *val, const __virtio16 *p)
> >    552  {
> >    553          __virtio16 v = 0;
> >  > 554          int rc = get_user(v, (__force __virtio16 __user *)p);
> >    555          *val = vringh16_to_cpu(vrh, v);
> >    556          return rc;
> >    557  }
> >    558
> >    559  static inline int putu16_user(const struct vringh *vrh, __virtio16 *p, u16 val)
> >    560  {
> >    561          __virtio16 v = cpu_to_vringh16(vrh, val);
> >    562          return put_user(v, (__force __virtio16 __user *)p);
> 
> OK, parisc developers still being dense, but this does look like an
> abuse of the bitwise type.

To give you another example:

	__le16 __user *p;
	__le16 foo;
	int rc = get_user(v, p);

really should be fine, ATM this gives a warning.


>  bitwise is supposed to be consumed by endian
> specific accessors.

Surely, assignment is OK too? get_user is exactly that.

vringh16_to_cpu is an endian specific accessor.
Look up it's definition please. The reason for that __force is
because we are adding __user.
It's a decision Rusty made to reduce code duplication:
we have some code that handles both kernel and userspace pointers.

>  get/put_user have no endian tags because they
> really can't do this ... the potential for width mismatch between the
> user and kernel address spaces could cause havoc if people get this
> wrong, so the warning looks correct to me.


I'm sorry I don't understand.

Why is

	access_ok
	__get_user

safer than

	get_user

?

It does not trigger the warning, because
__get_user does not have the cast to long internally.

Also, on some architectures get_user does not cast to long
internally so there's no warning.

> If we take your proposed patch we lose the type checking on all
> accessors because of the __force.


Did you try?  In my testing, this is not at all true.

For example with my patch:


             u16 v = 0;
             int rc = get_user(v, (__force __virtio16 __user *)p);

correctly triggers a warning.



>  Why not, instead, alter your code to
> tell the kernel you know what you're doing:
> 
>         __u16 v = 0;
>         int rc = get_user(v, (__force __u16 __user *)p);
>         *val = vringh16_to_cpu(vrh, (__force __virtio16)v);
>         return rc;
> 
> That way the accessors still warn if anyone else tries this

Hmm I don't understand, sorry. Tries what?
Can you please show me an invalid use of get_user that
produces a warning currently but won't with my patch?

> but your
> warning is gone and the code basically says you knew the u16 was really
> an endianness specific virtio quantity?
> 
> James
> 


(__force __virtio16 __user *)
tells get_user exactly that pointer is to type __virtio16.
It does not get any more explicit.

What you are proposing is really discarding type
information by a bunch of __force calls.

I am very reluctant to do this.
In fact, because of the static checking I added,
conversion to virtio 1.0 went so smoothly:
most drivers worked right away after the conversion.
I'm very sure without static checking, or with
__force thrown around liberally, I would have



vringh specifically has one __force cast anyway because
it's mixing userspace and kernel pointers.

But, I also have an out of tree patch that use structures
like this:

	struct foo {
		__virtio16 bar;
	};


Now with my patches I can do:

       __virtio16 v = 0;
	struct foo __user *p;
       int rc = get_user(v, &p->bar);


-- 
MST

  reply	other threads:[~2014-12-31 18:38 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-25  9:28 [PATCH repost 00/16] uaccess: fix sparse warning on get_user for bitwise types Michael S. Tsirkin
2014-12-25  9:28 ` [PATCH repost 01/16] x86/uaccess: fix sparse errors Michael S. Tsirkin
2014-12-25  9:28 ` [PATCH repost 02/16] alpha/uaccess: " Michael S. Tsirkin
2014-12-25  9:28 ` [PATCH repost 03/16] arm64/uaccess: " Michael S. Tsirkin
2014-12-25  9:28   ` Michael S. Tsirkin
2015-01-23 15:33   ` Catalin Marinas
2015-01-23 15:33     ` Catalin Marinas
2015-01-23 15:42     ` Will Deacon
2015-01-23 15:42       ` Will Deacon
2015-01-23 16:35       ` Catalin Marinas
2015-01-23 16:35         ` Catalin Marinas
2014-12-25  9:28 ` [PATCH repost 04/16] avr32/uaccess: " Michael S. Tsirkin
2014-12-25  9:28 ` [PATCH repost 05/16] blackfin/uaccess: " Michael S. Tsirkin
2014-12-25  9:28 ` [PATCH repost 06/16] cris/uaccess: " Michael S. Tsirkin
2014-12-25  9:28 ` [PATCH repost 07/16] ia64/uaccess: " Michael S. Tsirkin
2014-12-25  9:28   ` Michael S. Tsirkin
2014-12-25  9:28 ` [PATCH repost 08/16] m32r/uaccess: " Michael S. Tsirkin
2014-12-25  9:29 ` [PATCH repost 09/16] metag/uaccess: " Michael S. Tsirkin
2015-01-02 15:41   ` James Hogan
2015-01-02 15:41     ` James Hogan
2015-01-04 10:52     ` Michael S. Tsirkin
2015-01-05  9:44       ` James Hogan
2015-01-05  9:44         ` James Hogan
2015-01-05 13:00         ` Michael S. Tsirkin
2015-01-05 14:47           ` James Hogan
2015-01-06 10:00             ` Michael S. Tsirkin
2014-12-25  9:29 ` [PATCH repost 10/16] microblaze/uaccess: " Michael S. Tsirkin
2014-12-25  9:29 ` [PATCH repost 11/16] openrisc/uaccess: " Michael S. Tsirkin
2014-12-25  9:29   ` Michael S. Tsirkin
2014-12-25  9:29 ` [PATCH repost 12/16] parisc/uaccess: " Michael S. Tsirkin
2014-12-25 22:37   ` Helge Deller
2014-12-27 16:14     ` Michael S. Tsirkin
2014-12-31 17:17       ` James Bottomley
2014-12-31 18:38         ` Michael S. Tsirkin [this message]
2014-12-31 20:23           ` James Bottomley
2014-12-25  9:29 ` [PATCH repost 13/16] sh/uaccess: " Michael S. Tsirkin
2014-12-25  9:29   ` Michael S. Tsirkin
2014-12-25  9:29 ` [PATCH repost 14/16] sparc/uaccess: " Michael S. Tsirkin
2014-12-25  9:29   ` Michael S. Tsirkin
2014-12-25  9:30 ` [PATCH repost 15/16] " Michael S. Tsirkin
2014-12-25  9:30   ` Michael S. Tsirkin
2014-12-25 23:39   ` David Miller
2014-12-25 23:39     ` David Miller
2014-12-28 10:21     ` Michael S. Tsirkin
2014-12-28 10:21       ` Michael S. Tsirkin
2014-12-25  9:30 ` [PATCH repost 16/16] m68k/uaccess: " Michael S. Tsirkin

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=20141231183824.GA32430@redhat.com \
    --to=mst@redhat.com \
    --cc=James.Bottomley@HansenPartnership.com \
    --cc=arnd@arndb.de \
    --cc=deller@gmx.de \
    --cc=jejb@parisc-linux.org \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-parisc@vger.kernel.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.