]>
Commit | Line | Data |
---|---|---|
04fd09d4 SL |
1 | From 3e9ab5c01015b76d0c44ef0a2cb9821dff69746b Mon Sep 17 00:00:00 2001 |
2 | From: Aurelien Jarno <aurelien@aurel32.net> | |
3 | Date: Thu, 6 Dec 2018 20:05:34 +0100 | |
4 | Subject: vfs: fix preadv64v2 and pwritev64v2 compat syscalls with offset == -1 | |
5 | ||
6 | [ Upstream commit cc4b1242d7e3b42eed73881fc749944146493e4f ] | |
7 | ||
8 | The preadv2 and pwritev2 syscalls are supposed to emulate the readv and | |
9 | writev syscalls when offset == -1. Therefore the compat code should | |
10 | check for offset before calling do_compat_preadv64 and | |
11 | do_compat_pwritev64. This is the case for the preadv2 and pwritev2 | |
12 | syscalls, but handling of offset == -1 is missing in their 64-bit | |
13 | equivalent. | |
14 | ||
15 | This patch fixes that, calling do_compat_readv and do_compat_writev when | |
16 | offset == -1. This fixes the following glibc tests on x32: | |
17 | - misc/tst-preadvwritev2 | |
18 | - misc/tst-preadvwritev64v2 | |
19 | ||
20 | Cc: Alexander Viro <viro@zeniv.linux.org.uk> | |
21 | Cc: H.J. Lu <hjl.tools@gmail.com> | |
22 | Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> | |
23 | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> | |
24 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
25 | --- | |
26 | fs/read_write.c | 6 ++++++ | |
27 | 1 file changed, 6 insertions(+) | |
28 | ||
29 | diff --git a/fs/read_write.c b/fs/read_write.c | |
30 | index 57a00ef895b2..1c3eada2fe25 100644 | |
31 | --- a/fs/read_write.c | |
32 | +++ b/fs/read_write.c | |
33 | @@ -1235,6 +1235,9 @@ COMPAT_SYSCALL_DEFINE5(preadv64v2, unsigned long, fd, | |
34 | const struct compat_iovec __user *,vec, | |
35 | unsigned long, vlen, loff_t, pos, rwf_t, flags) | |
36 | { | |
37 | + if (pos == -1) | |
38 | + return do_compat_readv(fd, vec, vlen, flags); | |
39 | + | |
40 | return do_compat_preadv64(fd, vec, vlen, pos, flags); | |
41 | } | |
42 | #endif | |
43 | @@ -1341,6 +1344,9 @@ COMPAT_SYSCALL_DEFINE5(pwritev64v2, unsigned long, fd, | |
44 | const struct compat_iovec __user *,vec, | |
45 | unsigned long, vlen, loff_t, pos, rwf_t, flags) | |
46 | { | |
47 | + if (pos == -1) | |
48 | + return do_compat_writev(fd, vec, vlen, flags); | |
49 | + | |
50 | return do_compat_pwritev64(fd, vec, vlen, pos, flags); | |
51 | } | |
52 | #endif | |
53 | -- | |
54 | 2.19.1 | |
55 |