aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2014-03-05 04:43:51 -0500
committerHeiko Carstens <heiko.carstens@de.ibm.com>2014-03-06 09:35:09 -0500
commit378a10f3ae2e8a67ecc8f548c8e5ff25881bd88a (patch)
treee477b1924739af0585a3b2b6aa8b043a06f7eda0
parent291fdb0bcebd5e8db6af767c1fdc522167dad73d (diff)
fs/compat: optional preadv64/pwrite64 compat system calls
The preadv64/pwrite64 have been implemented for the x32 ABI, in order to allow passing 64 bit arguments from user space without splitting them into two 32 bit parameters, like it would be necessary for usual compat tasks. Howevert these two system calls are only being used for the x32 ABI, so add __ARCH_WANT_COMPAT defines for these two compat syscalls and make these two only visible for x86. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
-rw-r--r--arch/x86/include/asm/unistd.h2
-rw-r--r--fs/read_write.c36
-rw-r--r--include/linux/compat.h13
3 files changed, 43 insertions, 8 deletions
diff --git a/arch/x86/include/asm/unistd.h b/arch/x86/include/asm/unistd.h
index f4b5795d7e34..3f556c6a0157 100644
--- a/arch/x86/include/asm/unistd.h
+++ b/arch/x86/include/asm/unistd.h
@@ -24,6 +24,8 @@
24# include <asm/unistd_64_x32.h> 24# include <asm/unistd_64_x32.h>
25# define __ARCH_WANT_COMPAT_SYS_TIME 25# define __ARCH_WANT_COMPAT_SYS_TIME
26# define __ARCH_WANT_COMPAT_SYS_GETDENTS64 26# define __ARCH_WANT_COMPAT_SYS_GETDENTS64
27# define __ARCH_WANT_COMPAT_SYS_PREADV64
28# define __ARCH_WANT_COMPAT_SYS_PWRITEV64
27 29
28# endif 30# endif
29 31
diff --git a/fs/read_write.c b/fs/read_write.c
index edc5746a902a..72c09b4a01a4 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -982,9 +982,9 @@ COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd,
982 return ret; 982 return ret;
983} 983}
984 984
985COMPAT_SYSCALL_DEFINE4(preadv64, unsigned long, fd, 985static long __compat_sys_preadv64(unsigned long fd,
986 const struct compat_iovec __user *,vec, 986 const struct compat_iovec __user *vec,
987 unsigned long, vlen, loff_t, pos) 987 unsigned long vlen, loff_t pos)
988{ 988{
989 struct fd f; 989 struct fd f;
990 ssize_t ret; 990 ssize_t ret;
@@ -1001,12 +1001,22 @@ COMPAT_SYSCALL_DEFINE4(preadv64, unsigned long, fd,
1001 return ret; 1001 return ret;
1002} 1002}
1003 1003
1004#ifdef __ARCH_WANT_COMPAT_SYS_PREADV64
1005COMPAT_SYSCALL_DEFINE4(preadv64, unsigned long, fd,
1006 const struct compat_iovec __user *,vec,
1007 unsigned long, vlen, loff_t, pos)
1008{
1009 return __compat_sys_preadv64(fd, vec, vlen, pos);
1010}
1011#endif
1012
1004COMPAT_SYSCALL_DEFINE5(preadv, compat_ulong_t, fd, 1013COMPAT_SYSCALL_DEFINE5(preadv, compat_ulong_t, fd,
1005 const struct compat_iovec __user *,vec, 1014 const struct compat_iovec __user *,vec,
1006 compat_ulong_t, vlen, u32, pos_low, u32, pos_high) 1015 compat_ulong_t, vlen, u32, pos_low, u32, pos_high)
1007{ 1016{
1008 loff_t pos = ((loff_t)pos_high << 32) | pos_low; 1017 loff_t pos = ((loff_t)pos_high << 32) | pos_low;
1009 return compat_sys_preadv64(fd, vec, vlen, pos); 1018
1019 return __compat_sys_preadv64(fd, vec, vlen, pos);
1010} 1020}
1011 1021
1012static size_t compat_writev(struct file *file, 1022static size_t compat_writev(struct file *file,
@@ -1049,9 +1059,9 @@ COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd,
1049 return ret; 1059 return ret;
1050} 1060}
1051 1061
1052COMPAT_SYSCALL_DEFINE4(pwritev64, unsigned long, fd, 1062static long __compat_sys_pwritev64(unsigned long fd,
1053 const struct compat_iovec __user *,vec, 1063 const struct compat_iovec __user *vec,
1054 unsigned long, vlen, loff_t, pos) 1064 unsigned long vlen, loff_t pos)
1055{ 1065{
1056 struct fd f; 1066 struct fd f;
1057 ssize_t ret; 1067 ssize_t ret;
@@ -1068,12 +1078,22 @@ COMPAT_SYSCALL_DEFINE4(pwritev64, unsigned long, fd,
1068 return ret; 1078 return ret;
1069} 1079}
1070 1080
1081#ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64
1082COMPAT_SYSCALL_DEFINE4(pwritev64, unsigned long, fd,
1083 const struct compat_iovec __user *,vec,
1084 unsigned long, vlen, loff_t, pos)
1085{
1086 return __compat_sys_pwritev64(fd, vec, vlen, pos);
1087}
1088#endif
1089
1071COMPAT_SYSCALL_DEFINE5(pwritev, compat_ulong_t, fd, 1090COMPAT_SYSCALL_DEFINE5(pwritev, compat_ulong_t, fd,
1072 const struct compat_iovec __user *,vec, 1091 const struct compat_iovec __user *,vec,
1073 compat_ulong_t, vlen, u32, pos_low, u32, pos_high) 1092 compat_ulong_t, vlen, u32, pos_low, u32, pos_high)
1074{ 1093{
1075 loff_t pos = ((loff_t)pos_high << 32) | pos_low; 1094 loff_t pos = ((loff_t)pos_high << 32) | pos_low;
1076 return compat_sys_pwritev64(fd, vec, vlen, pos); 1095
1096 return __compat_sys_pwritev64(fd, vec, vlen, pos);
1077} 1097}
1078#endif 1098#endif
1079 1099
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 179b1da9e19f..1c457428ec0a 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -340,6 +340,19 @@ asmlinkage ssize_t compat_sys_preadv(compat_ulong_t fd,
340asmlinkage ssize_t compat_sys_pwritev(compat_ulong_t fd, 340asmlinkage ssize_t compat_sys_pwritev(compat_ulong_t fd,
341 const struct compat_iovec __user *vec, 341 const struct compat_iovec __user *vec,
342 compat_ulong_t vlen, u32 pos_low, u32 pos_high); 342 compat_ulong_t vlen, u32 pos_low, u32 pos_high);
343
344#ifdef __ARCH_WANT_COMPAT_SYS_PREADV64
345asmlinkage long compat_sys_preadv64(unsigned long fd,
346 const struct compat_iovec __user *vec,
347 unsigned long vlen, loff_t pos);
348#endif
349
350#ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64
351asmlinkage long compat_sys_pwritev64(unsigned long fd,
352 const struct compat_iovec __user *vec,
353 unsigned long vlen, loff_t pos);
354#endif
355
343asmlinkage long compat_sys_lseek(unsigned int, compat_off_t, unsigned int); 356asmlinkage long compat_sys_lseek(unsigned int, compat_off_t, unsigned int);
344 357
345asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr_t __user *argv, 358asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr_t __user *argv,