Hi Sunil,

On Sun, 2010-12-19 at 00:16 -0800, ccmail111 wrote:
> Hi Miklos/Greg,
> 
> IMHO, I see 3 diffs/patches for same issue below.
> I have posted initial patch, then Miklos had updated patch (which I was in 
> process of testing), then I see one below.

Yes, the patch was further simplified  before submitting to mainline.  I
also did some testing but further testing is very welcome on this
updated patch as well.

Thanks,
Miklos

> 
> --- On Fri, 12/17/10, [email protected] <[email protected]> wrote:
> 
> > From: [email protected] <[email protected]>
> > Subject: Patch "fuse: fix ioctl when server is 32bit" has been added to the 
> > 2.6.32-longterm tree
> > To: [email protected], [email protected], [email protected], [email protected]
> > Cc: [email protected], [email protected]
> > Date: Friday, December 17, 2010, 6:34 PM
> > 
> > This is a note to let you know that I've just added the
> > patch titled
> > 
> >     fuse: fix ioctl when server is 32bit
> > 
> > to the 2.6.32-longterm tree which can be found at:
> >     
> > http://www.kernel.org/git/?p=linux/kernel/git/longterm/longterm-queue-2.6.32.git;a=summary
> > 
> > The filename of the patch is:
> >  
> >    fuse-fix-ioctl-when-server-is-32bit.patch
> > and it can be found in the queue-2.6.32 subdirectory.
> > 
> > If you, or anyone else, feels it should not be added to the
> > 2.6.32 longterm tree,
> > please let <[email protected]>
> > know about it.
> > 
> > 
> > From d9d318d39dd5cb686660504a3565aac453709ccc Mon Sep 17
> > 00:00:00 2001
> > From: Miklos Szeredi <[email protected]>
> > Date: Tue, 30 Nov 2010 16:39:27 +0100
> > Subject: fuse: fix ioctl when server is 32bit
> > 
> > From: Miklos Szeredi <[email protected]>
> > 
> > commit d9d318d39dd5cb686660504a3565aac453709ccc upstream.
> > 
> > If a 32bit CUSE server is run on 64bit this results in EIO
> > being
> > returned to the caller.
> > 
> > The reason is that FUSE_IOCTL_RETRY reply was defined to
> > use 'struct
> > iovec', which is different on 32bit and 64bit archs.
> > 
> > Work around this by looking at the size of the reply to
> > determine
> > which struct was used.  This is only needed if
> > CONFIG_COMPAT is
> > defined.
> > 
> > A more permanent fix for the interface will be to use the
> > same struct
> > on both 32bit and 64bit.
> > 
> > Reported-by: "ccmail111" <[email protected]>
> > Signed-off-by: Miklos Szeredi <[email protected]>
> > CC: Tejun Heo <[email protected]>
> > Signed-off-by: Greg Kroah-Hartman <[email protected]>
> > 
> > ---
> >  fs/fuse/file.c |   50
> > ++++++++++++++++++++++++++++++++++++++++++++------
> >  1 file changed, 44 insertions(+), 6 deletions(-)
> > 
> > --- a/fs/fuse/file.c
> > +++ b/fs/fuse/file.c
> > @@ -13,6 +13,7 @@
> >  #include <linux/kernel.h>
> >  #include <linux/sched.h>
> >  #include <linux/module.h>
> > +#include <linux/compat.h>
> >  
> >  static const struct file_operations
> > fuse_direct_io_file_operations;
> >  
> > @@ -1634,6 +1635,44 @@ static int
> > fuse_verify_ioctl_iov(struct
> >  }
> >  
> >  /*
> > + * CUSE servers compiled on 32bit broke on 64bit kernels
> > because the
> > + * ABI was defined to be 'struct iovec' which is different
> > on 32bit
> > + * and 64bit.  Fortunately we can determine which
> > structure the server
> > + * used from the size of the reply.
> > + */
> > +static int fuse_copy_ioctl_iovec(struct iovec *dst, void
> > *src,
> > +           
> >      size_t transferred, unsigned
> > count,
> > +           
> >      bool is_compat)
> > +{
> > +#ifdef CONFIG_COMPAT
> > +    if (count * sizeof(struct compat_iovec)
> > == transferred) {
> > +        struct compat_iovec
> > *ciov = src;
> > +        unsigned i;
> > +
> > +        /*
> > +         * With
> > this interface a 32bit server cannot support
> > +         *
> > non-compat (i.e. ones coming from 64bit apps) ioctl
> > +         *
> > requests
> > +         */
> > +        if (!is_compat)
> > +           
> > return -EINVAL;
> > +
> > +        for (i = 0; i <
> > count; i++) {
> > +           
> > dst[i].iov_base = compat_ptr(ciov[i].iov_base);
> > +           
> > dst[i].iov_len = ciov[i].iov_len;
> > +        }
> > +        return 0;
> > +    }
> > +#endif
> > +
> > +    if (count * sizeof(struct iovec) !=
> > transferred)
> > +        return -EIO;
> > +
> > +    memcpy(dst, src, transferred);
> > +    return 0;
> > +}
> > +
> > +/*
> >   * For ioctls, there is no generic way to determine
> > how much memory
> >   * needs to be read and/or written. 
> > Furthermore, ioctls are allowed
> >   * to dereference the passed pointer, so the
> > parameter requires deep
> > @@ -1814,14 +1853,13 @@ long fuse_do_ioctl(struct file
> > *file, un
> >             
> > in_iovs + out_iovs > FUSE_IOCTL_MAX_IOV)
> >             
> > goto out;
> >  
> > -        err = -EIO;
> > -        if ((in_iovs +
> > out_iovs) * sizeof(struct iovec) != transferred)
> > -           
> > goto out;
> > -
> > -        /* okay, copy in
> > iovs and retry */
> >          vaddr =
> > kmap_atomic(pages[0], KM_USER0);
> > -       
> > memcpy(page_address(iov_page), vaddr, transferred);
> > +        err =
> > fuse_copy_ioctl_iovec(page_address(iov_page), vaddr,
> > +           
> >            
> > transferred, in_iovs + out_iovs,
> > +           
> >             (flags
> > & FUSE_IOCTL_COMPAT) != 0);
> >          kunmap_atomic(vaddr,
> > KM_USER0);
> > +        if (err)
> > +           
> > goto out;
> >  
> >          in_iov =
> > page_address(iov_page);
> >          out_iov = in_iov +
> > in_iovs;
> > 
> > 
> > Patches currently in longterm-queue-2.6.32 which might be
> > from [email protected]
> > are
> > 
> > 
> 
> 
>       



_______________________________________________
stable mailing list
[email protected]
http://linux.kernel.org/mailman/listinfo/stable

Reply via email to