diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2014-01-29 17:05:44 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-29 19:22:39 -0500 |
commit | dfd948e32af2e7b28bcd7a490c0a30d4b8df2a36 (patch) | |
tree | 41f14ee51b5d57387a425b241c67f7d33446076b /fs/read_write.c | |
parent | 4a404bea941ac3c62e11b88c9d16197334eee2f1 (diff) |
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 commit 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@de.ibm.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: <stable@vger.kernel.org> [v3.10+]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/read_write.c')
-rw-r--r-- | fs/read_write.c | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/fs/read_write.c b/fs/read_write.c index 1193ffd03565..edc5746a902a 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -964,9 +964,9 @@ out: | |||
964 | return ret; | 964 | return ret; |
965 | } | 965 | } |
966 | 966 | ||
967 | COMPAT_SYSCALL_DEFINE3(readv, unsigned long, fd, | 967 | COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd, |
968 | const struct compat_iovec __user *,vec, | 968 | const struct compat_iovec __user *,vec, |
969 | unsigned long, vlen) | 969 | compat_ulong_t, vlen) |
970 | { | 970 | { |
971 | struct fd f = fdget(fd); | 971 | struct fd f = fdget(fd); |
972 | ssize_t ret; | 972 | ssize_t ret; |
@@ -1001,9 +1001,9 @@ COMPAT_SYSCALL_DEFINE4(preadv64, unsigned long, fd, | |||
1001 | return ret; | 1001 | return ret; |
1002 | } | 1002 | } |
1003 | 1003 | ||
1004 | COMPAT_SYSCALL_DEFINE5(preadv, unsigned long, fd, | 1004 | COMPAT_SYSCALL_DEFINE5(preadv, compat_ulong_t, fd, |
1005 | const struct compat_iovec __user *,vec, | 1005 | const struct compat_iovec __user *,vec, |
1006 | unsigned long, vlen, u32, pos_low, u32, pos_high) | 1006 | compat_ulong_t, vlen, u32, pos_low, u32, pos_high) |
1007 | { | 1007 | { |
1008 | loff_t pos = ((loff_t)pos_high << 32) | pos_low; | 1008 | loff_t pos = ((loff_t)pos_high << 32) | pos_low; |
1009 | return compat_sys_preadv64(fd, vec, vlen, pos); | 1009 | return compat_sys_preadv64(fd, vec, vlen, pos); |
@@ -1031,9 +1031,9 @@ out: | |||
1031 | return ret; | 1031 | return ret; |
1032 | } | 1032 | } |
1033 | 1033 | ||
1034 | COMPAT_SYSCALL_DEFINE3(writev, unsigned long, fd, | 1034 | COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd, |
1035 | const struct compat_iovec __user *, vec, | 1035 | const struct compat_iovec __user *, vec, |
1036 | unsigned long, vlen) | 1036 | compat_ulong_t, vlen) |
1037 | { | 1037 | { |
1038 | struct fd f = fdget(fd); | 1038 | struct fd f = fdget(fd); |
1039 | ssize_t ret; | 1039 | ssize_t ret; |
@@ -1068,9 +1068,9 @@ COMPAT_SYSCALL_DEFINE4(pwritev64, unsigned long, fd, | |||
1068 | return ret; | 1068 | return ret; |
1069 | } | 1069 | } |
1070 | 1070 | ||
1071 | COMPAT_SYSCALL_DEFINE5(pwritev, unsigned long, fd, | 1071 | COMPAT_SYSCALL_DEFINE5(pwritev, compat_ulong_t, fd, |
1072 | const struct compat_iovec __user *,vec, | 1072 | const struct compat_iovec __user *,vec, |
1073 | unsigned long, vlen, u32, pos_low, u32, pos_high) | 1073 | compat_ulong_t, vlen, u32, pos_low, u32, pos_high) |
1074 | { | 1074 | { |
1075 | loff_t pos = ((loff_t)pos_high << 32) | pos_low; | 1075 | loff_t pos = ((loff_t)pos_high << 32) | pos_low; |
1076 | return compat_sys_pwritev64(fd, vec, vlen, pos); | 1076 | return compat_sys_pwritev64(fd, vec, vlen, pos); |