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
