]>
Commit | Line | Data |
---|---|---|
11899940 GKH |
1 | From dfd948e32af2e7b28bcd7a490c0a30d4b8df2a36 Mon Sep 17 00:00:00 2001 |
2 | From: Heiko Carstens <heiko.carstens@de.ibm.com> | |
3 | Date: Wed, 29 Jan 2014 14:05:44 -0800 | |
4 | Subject: fs/compat: fix parameter handling for compat readv/writev syscalls | |
5 | ||
6 | From: Heiko Carstens <heiko.carstens@de.ibm.com> | |
7 | ||
8 | commit dfd948e32af2e7b28bcd7a490c0a30d4b8df2a36 upstream. | |
9 | ||
10 | We got a report that the pwritev syscall does not work correctly in | |
11 | compat mode on s390. | |
12 | ||
13 | It turned out that with commit 72ec35163f9f ("switch compat readv/writev | |
14 | variants to COMPAT_SYSCALL_DEFINE") we lost the zero extension of a | |
15 | couple of syscall parameters because the some parameter types haven't | |
16 | been converted from unsigned long to compat_ulong_t. | |
17 | ||
18 | This is needed for architectures where the ABI requires that the caller | |
19 | of a function performed zero and/or sign extension to 64 bit of all | |
20 | parameters. | |
21 | ||
22 | Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> | |
23 | Cc: Al Viro <viro@zeniv.linux.org.uk> | |
24 | Cc: Ingo Molnar <mingo@kernel.org> | |
25 | Cc: "H. Peter Anvin" <hpa@zytor.com> | |
26 | Cc: Hendrik Brueckner <brueckner@linux.vnet.ibm.com> | |
27 | Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> | |
28 | Signed-off-by: Andrew Morton <akpm@linux-foundation.org> | |
29 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | |
30 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
31 | ||
32 | --- | |
33 | fs/read_write.c | 16 ++++++++-------- | |
34 | include/linux/compat.h | 16 ++++++++-------- | |
35 | 2 files changed, 16 insertions(+), 16 deletions(-) | |
36 | ||
37 | --- a/fs/read_write.c | |
38 | +++ b/fs/read_write.c | |
39 | @@ -947,9 +947,9 @@ out: | |
40 | return ret; | |
41 | } | |
42 | ||
43 | -COMPAT_SYSCALL_DEFINE3(readv, unsigned long, fd, | |
44 | +COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd, | |
45 | const struct compat_iovec __user *,vec, | |
46 | - unsigned long, vlen) | |
47 | + compat_ulong_t, vlen) | |
48 | { | |
49 | struct fd f = fdget(fd); | |
50 | ssize_t ret; | |
51 | @@ -983,9 +983,9 @@ COMPAT_SYSCALL_DEFINE4(preadv64, unsigne | |
52 | return ret; | |
53 | } | |
54 | ||
55 | -COMPAT_SYSCALL_DEFINE5(preadv, unsigned long, fd, | |
56 | +COMPAT_SYSCALL_DEFINE5(preadv, compat_ulong_t, fd, | |
57 | const struct compat_iovec __user *,vec, | |
58 | - unsigned long, vlen, u32, pos_low, u32, pos_high) | |
59 | + compat_ulong_t, vlen, u32, pos_low, u32, pos_high) | |
60 | { | |
61 | loff_t pos = ((loff_t)pos_high << 32) | pos_low; | |
62 | return compat_sys_preadv64(fd, vec, vlen, pos); | |
63 | @@ -1013,9 +1013,9 @@ out: | |
64 | return ret; | |
65 | } | |
66 | ||
67 | -COMPAT_SYSCALL_DEFINE3(writev, unsigned long, fd, | |
68 | +COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd, | |
69 | const struct compat_iovec __user *, vec, | |
70 | - unsigned long, vlen) | |
71 | + compat_ulong_t, vlen) | |
72 | { | |
73 | struct fd f = fdget(fd); | |
74 | ssize_t ret; | |
75 | @@ -1049,9 +1049,9 @@ COMPAT_SYSCALL_DEFINE4(pwritev64, unsign | |
76 | return ret; | |
77 | } | |
78 | ||
79 | -COMPAT_SYSCALL_DEFINE5(pwritev, unsigned long, fd, | |
80 | +COMPAT_SYSCALL_DEFINE5(pwritev, compat_ulong_t, fd, | |
81 | const struct compat_iovec __user *,vec, | |
82 | - unsigned long, vlen, u32, pos_low, u32, pos_high) | |
83 | + compat_ulong_t, vlen, u32, pos_low, u32, pos_high) | |
84 | { | |
85 | loff_t pos = ((loff_t)pos_high << 32) | pos_low; | |
86 | return compat_sys_pwritev64(fd, vec, vlen, pos); | |
87 | --- a/include/linux/compat.h | |
88 | +++ b/include/linux/compat.h | |
89 | @@ -326,16 +326,16 @@ asmlinkage long compat_sys_keyctl(u32 op | |
90 | u32 arg2, u32 arg3, u32 arg4, u32 arg5); | |
91 | asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u32); | |
92 | ||
93 | -asmlinkage ssize_t compat_sys_readv(unsigned long fd, | |
94 | - const struct compat_iovec __user *vec, unsigned long vlen); | |
95 | -asmlinkage ssize_t compat_sys_writev(unsigned long fd, | |
96 | - const struct compat_iovec __user *vec, unsigned long vlen); | |
97 | -asmlinkage ssize_t compat_sys_preadv(unsigned long fd, | |
98 | +asmlinkage ssize_t compat_sys_readv(compat_ulong_t fd, | |
99 | + const struct compat_iovec __user *vec, compat_ulong_t vlen); | |
100 | +asmlinkage ssize_t compat_sys_writev(compat_ulong_t fd, | |
101 | + const struct compat_iovec __user *vec, compat_ulong_t vlen); | |
102 | +asmlinkage ssize_t compat_sys_preadv(compat_ulong_t fd, | |
103 | const struct compat_iovec __user *vec, | |
104 | - unsigned long vlen, u32 pos_low, u32 pos_high); | |
105 | -asmlinkage ssize_t compat_sys_pwritev(unsigned long fd, | |
106 | + compat_ulong_t vlen, u32 pos_low, u32 pos_high); | |
107 | +asmlinkage ssize_t compat_sys_pwritev(compat_ulong_t fd, | |
108 | const struct compat_iovec __user *vec, | |
109 | - unsigned long vlen, u32 pos_low, u32 pos_high); | |
110 | + compat_ulong_t vlen, u32 pos_low, u32 pos_high); | |
111 | asmlinkage long comat_sys_lseek(unsigned int, compat_off_t, unsigned int); | |
112 | ||
113 | asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr_t __user *argv, |