On Fri, Jul 7, 2017 at 5:46 AM, Michael Ellerman <m...@ellerman.id.au> wrote: > Al Viro <v...@zeniv.linux.org.uk> writes: > >> >> Switch flock copyin/copyout primitives to copy_{from,to}_user() >> (2017-06-26 23:52:44 -0400) > > This commit seems to have broken networking on a bunch of my PPC > machines (64-bit kernel, 32-bit userspace).
Bah. I think that commit is entirely broken, due to having the arguments to the "copy_flock_fields()" in the wrong order. The copy_flock_fields() macro has the arguments in order <from, to>, but all the users seem to do it the other way around. I think it would have been more obvious if the put_compat_flock*() source argument had been "const". > Patch coming. I'm not seeing a patch, so I did my own. But it's _entirely_ untested. Does the attached fix things for you? Linus
fs/fcntl.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/fs/fcntl.c b/fs/fcntl.c index b6bd89628025..eeb19e22fd08 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -527,43 +527,43 @@ SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, (to).l_len = (from).l_len; \ (to).l_pid = (from).l_pid; -static int get_compat_flock(struct flock *kfl, struct compat_flock __user *ufl) +static int get_compat_flock(struct flock *kfl, const struct compat_flock __user *ufl) { struct compat_flock fl; if (copy_from_user(&fl, ufl, sizeof(struct compat_flock))) return -EFAULT; - copy_flock_fields(*kfl, fl); + copy_flock_fields(fl, *kfl); return 0; } -static int get_compat_flock64(struct flock *kfl, struct compat_flock64 __user *ufl) +static int get_compat_flock64(struct flock *kfl, const struct compat_flock64 __user *ufl) { struct compat_flock64 fl; if (copy_from_user(&fl, ufl, sizeof(struct compat_flock64))) return -EFAULT; - copy_flock_fields(*kfl, fl); + copy_flock_fields(fl, *kfl); return 0; } -static int put_compat_flock(struct flock *kfl, struct compat_flock __user *ufl) +static int put_compat_flock(const struct flock *kfl, struct compat_flock __user *ufl) { struct compat_flock fl; memset(&fl, 0, sizeof(struct compat_flock)); - copy_flock_fields(fl, *kfl); + copy_flock_fields(*kfl, fl); if (copy_to_user(ufl, &fl, sizeof(struct compat_flock))) return -EFAULT; return 0; } -static int put_compat_flock64(struct flock *kfl, struct compat_flock64 __user *ufl) +static int put_compat_flock64(const struct flock *kfl, struct compat_flock64 __user *ufl) { struct compat_flock64 fl; memset(&fl, 0, sizeof(struct compat_flock64)); - copy_flock_fields(fl, *kfl); + copy_flock_fields(*kfl, fl); if (copy_to_user(ufl, &fl, sizeof(struct compat_flock64))) return -EFAULT; return 0;