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.

Thanks,
Sunil.


--- 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