From: Heiko Carstens <heiko.carstens@xxxxxxxxxx> Subject: fs/compat: fix parameter handling for compat readv/writev syscalls We got a report that the pwritev syscall does not work correctly in compat mode on s390. It turned out that with 72ec35163f9f "switch compat readv/writev variants to COMPAT_SYSCALL_DEFINE" we lost the zero extension of a couple of syscall parameters because the some parameter types haven't been converted from unsigned long to compat_ulong_t. This is needed for architectures where the ABI requires that the caller of a function performed zero and/or sign extension to 64 bit of all parameters. Signed-off-by: Heiko Carstens <heiko.carstens@xxxxxxxxxx> Cc: Al Viro <viro@xxxxxxxxxxxxxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxxxxx> Cc: "H. Peter Anvin" <hpa@xxxxxxxxx> Cc: Hendrik Brueckner <brueckner@xxxxxxxxxxxxxxxxxx> Cc: Martin Schwidefsky <schwidefsky@xxxxxxxxxx> Cc: <stable@xxxxxxxxxxxxxxx> [v3.10+] Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- fs/read_write.c | 16 ++++++++-------- include/linux/compat.h | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff -puN fs/read_write.c~fs-compat-fix-parameter-handling-for-compat-readv-writev-syscalls fs/read_write.c --- a/fs/read_write.c~fs-compat-fix-parameter-handling-for-compat-readv-writev-syscalls +++ a/fs/read_write.c @@ -964,9 +964,9 @@ out: return ret; } -COMPAT_SYSCALL_DEFINE3(readv, unsigned long, fd, +COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd, const struct compat_iovec __user *,vec, - unsigned long, vlen) + compat_ulong_t, vlen) { struct fd f = fdget(fd); ssize_t ret; @@ -1001,9 +1001,9 @@ COMPAT_SYSCALL_DEFINE4(preadv64, unsigne return ret; } -COMPAT_SYSCALL_DEFINE5(preadv, unsigned long, fd, +COMPAT_SYSCALL_DEFINE5(preadv, compat_ulong_t, fd, const struct compat_iovec __user *,vec, - unsigned long, vlen, u32, pos_low, u32, pos_high) + compat_ulong_t, vlen, u32, pos_low, u32, pos_high) { loff_t pos = ((loff_t)pos_high << 32) | pos_low; return compat_sys_preadv64(fd, vec, vlen, pos); @@ -1031,9 +1031,9 @@ out: return ret; } -COMPAT_SYSCALL_DEFINE3(writev, unsigned long, fd, +COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd, const struct compat_iovec __user *, vec, - unsigned long, vlen) + compat_ulong_t, vlen) { struct fd f = fdget(fd); ssize_t ret; @@ -1068,9 +1068,9 @@ COMPAT_SYSCALL_DEFINE4(pwritev64, unsign return ret; } -COMPAT_SYSCALL_DEFINE5(pwritev, unsigned long, fd, +COMPAT_SYSCALL_DEFINE5(pwritev, compat_ulong_t, fd, const struct compat_iovec __user *,vec, - unsigned long, vlen, u32, pos_low, u32, pos_high) + compat_ulong_t, vlen, u32, pos_low, u32, pos_high) { loff_t pos = ((loff_t)pos_high << 32) | pos_low; return compat_sys_pwritev64(fd, vec, vlen, pos); diff -puN include/linux/compat.h~fs-compat-fix-parameter-handling-for-compat-readv-writev-syscalls include/linux/compat.h --- a/include/linux/compat.h~fs-compat-fix-parameter-handling-for-compat-readv-writev-syscalls +++ a/include/linux/compat.h @@ -327,16 +327,16 @@ asmlinkage long compat_sys_keyctl(u32 op u32 arg2, u32 arg3, u32 arg4, u32 arg5); asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u32); -asmlinkage ssize_t compat_sys_readv(unsigned long fd, - const struct compat_iovec __user *vec, unsigned long vlen); -asmlinkage ssize_t compat_sys_writev(unsigned long fd, - const struct compat_iovec __user *vec, unsigned long vlen); -asmlinkage ssize_t compat_sys_preadv(unsigned long fd, +asmlinkage ssize_t compat_sys_readv(compat_ulong_t fd, + const struct compat_iovec __user *vec, compat_ulong_t vlen); +asmlinkage ssize_t compat_sys_writev(compat_ulong_t fd, + const struct compat_iovec __user *vec, compat_ulong_t vlen); +asmlinkage ssize_t compat_sys_preadv(compat_ulong_t fd, const struct compat_iovec __user *vec, - unsigned long vlen, u32 pos_low, u32 pos_high); -asmlinkage ssize_t compat_sys_pwritev(unsigned long fd, + compat_ulong_t vlen, u32 pos_low, u32 pos_high); +asmlinkage ssize_t compat_sys_pwritev(compat_ulong_t fd, const struct compat_iovec __user *vec, - unsigned long vlen, u32 pos_low, u32 pos_high); + compat_ulong_t vlen, u32 pos_low, u32 pos_high); asmlinkage long comat_sys_lseek(unsigned int, compat_off_t, unsigned int); asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr_t __user *argv, _ -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html