--- v7
+++ v5
@@ -4,18 +4,18 @@
Signed-off-by: Milosz Tanski <milosz@adfin.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
- fs/read_write.c | 172 ++++++++++++++++++++++++++++++--------
+ fs/read_write.c | 176 ++++++++++++++++++++++++++++++--------
include/linux/compat.h | 6 ++
include/linux/syscalls.h | 6 ++
include/uapi/asm-generic/unistd.h | 6 +-
mm/filemap.c | 5 +-
- 5 files changed, 156 insertions(+), 39 deletions(-)
+ 5 files changed, 158 insertions(+), 41 deletions(-)
diff --git a/fs/read_write.c b/fs/read_write.c
-index b53bb59..e91f46e 100644
+index 94b2d34..907735c 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
-@@ -924,6 +924,8 @@ ssize_t vfs_readv(struct file *file, const struct iovec __user *vec,
+@@ -866,6 +866,8 @@ ssize_t vfs_readv(struct file *file, const struct iovec __user *vec,
return -EBADF;
if (!(file->f_mode & FMODE_CAN_READ))
return -EINVAL;
@@ -24,7 +24,7 @@
return do_readv_writev(READ, file, vec, vlen, pos, flags);
}
-@@ -937,21 +939,23 @@ ssize_t vfs_writev(struct file *file, const struct iovec __user *vec,
+@@ -879,21 +881,23 @@ ssize_t vfs_writev(struct file *file, const struct iovec __user *vec,
return -EBADF;
if (!(file->f_mode & FMODE_CAN_WRITE))
return -EINVAL;
@@ -51,7 +51,7 @@
if (ret >= 0)
file_pos_write(f.file, pos);
fdput_pos(f);
-@@ -963,15 +967,15 @@ SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec,
+@@ -905,15 +909,15 @@ SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec,
return ret;
}
@@ -70,7 +70,7 @@
if (ret >= 0)
file_pos_write(f.file, pos);
fdput_pos(f);
-@@ -989,10 +993,9 @@ static inline loff_t pos_from_hilo(unsigned long high, unsigned long low)
+@@ -931,10 +935,9 @@ static inline loff_t pos_from_hilo(unsigned long high, unsigned long low)
return (((loff_t)high << HALF_LONG_BITS) << HALF_LONG_BITS) | low;
}
@@ -83,7 +83,7 @@
struct fd f;
ssize_t ret = -EBADF;
-@@ -1003,7 +1006,7 @@ SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
+@@ -945,7 +948,7 @@ SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
if (f.file) {
ret = -ESPIPE;
if (f.file->f_mode & FMODE_PREAD)
@@ -92,7 +92,7 @@
fdput(f);
}
-@@ -1013,10 +1016,9 @@ SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
+@@ -955,10 +958,9 @@ SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
return ret;
}
@@ -105,7 +105,7 @@
struct fd f;
ssize_t ret = -EBADF;
-@@ -1027,7 +1029,7 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
+@@ -969,7 +971,7 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
if (f.file) {
ret = -ESPIPE;
if (f.file->f_mode & FMODE_PWRITE)
@@ -114,7 +114,7 @@
fdput(f);
}
-@@ -1037,11 +1039,63 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
+@@ -979,11 +981,63 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
return ret;
}
@@ -179,7 +179,7 @@
{
compat_ssize_t tot_len;
struct iovec iovstack[UIO_FASTIOV];
-@@ -1075,7 +1129,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
+@@ -1017,7 +1071,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
if (iter_fn)
ret = do_iter_readv_writev(file, type, iov, nr_segs, tot_len,
@@ -188,7 +188,7 @@
else if (fnv)
ret = do_sync_readv_writev(file, iov, nr_segs, tot_len,
pos, fnv);
-@@ -1099,7 +1153,7 @@ out:
+@@ -1041,7 +1095,7 @@ out:
static size_t compat_readv(struct file *file,
const struct compat_iovec __user *vec,
@@ -197,19 +197,16 @@
{
ssize_t ret = -EBADF;
-@@ -1109,8 +1163,10 @@ static size_t compat_readv(struct file *file,
- ret = -EINVAL;
+@@ -1052,7 +1106,7 @@ static size_t compat_readv(struct file *file,
if (!(file->f_mode & FMODE_CAN_READ))
goto out;
-+ if (flags & ~0)
-+ goto out;
- ret = compat_do_readv_writev(READ, file, vec, vlen, pos);
+ ret = compat_do_readv_writev(READ, file, vec, vlen, pos, flags);
out:
if (ret > 0)
-@@ -1119,9 +1175,9 @@ out:
+@@ -1061,9 +1115,9 @@ out:
return ret;
}
@@ -222,7 +219,7 @@
{
struct fd f = fdget_pos(fd);
ssize_t ret;
-@@ -1130,16 +1186,24 @@ COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd,
+@@ -1072,28 +1126,34 @@ COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd,
if (!f.file)
return -EBADF;
pos = f.file->f_pos;
@@ -249,7 +246,11 @@
{
struct fd f;
ssize_t ret;
-@@ -1151,7 +1215,7 @@ static long __compat_sys_preadv64(unsigned long fd,
+
+- if (pos < 0)
+- return -EINVAL;
+ f = fdget(fd);
+ if (!f.file)
return -EBADF;
ret = -ESPIPE;
if (f.file->f_mode & FMODE_PREAD)
@@ -258,20 +259,26 @@
fdput(f);
return ret;
}
-@@ -1161,7 +1225,7 @@ COMPAT_SYSCALL_DEFINE4(preadv64, unsigned long, fd,
+@@ -1103,7 +1163,10 @@ COMPAT_SYSCALL_DEFINE4(preadv64, unsigned long, fd,
const struct compat_iovec __user *,vec,
unsigned long, vlen, loff_t, pos)
{
- return __compat_sys_preadv64(fd, vec, vlen, pos);
++ if (pos < 0)
++ return -EINVAL;
++
+ return __compat_sys_preadv64(fd, vec, vlen, pos, 0);
}
#endif
-@@ -1171,12 +1235,25 @@ COMPAT_SYSCALL_DEFINE5(preadv, compat_ulong_t, fd,
+@@ -1113,12 +1176,28 @@ COMPAT_SYSCALL_DEFINE5(preadv, compat_ulong_t, fd,
{
loff_t pos = ((loff_t)pos_high << 32) | pos_low;
- return __compat_sys_preadv64(fd, vec, vlen, pos);
++ if (pos < 0)
++ return -EINVAL;
++
+ return __compat_sys_preadv64(fd, vec, vlen, pos, 0);
+}
+
@@ -295,19 +302,16 @@
{
ssize_t ret = -EBADF;
-@@ -1186,8 +1263,10 @@ static size_t compat_writev(struct file *file,
- ret = -EINVAL;
+@@ -1129,7 +1208,7 @@ static size_t compat_writev(struct file *file,
if (!(file->f_mode & FMODE_CAN_WRITE))
goto out;
-+ if (flags & ~0)
-+ goto out;
- ret = compat_do_readv_writev(WRITE, file, vec, vlen, pos);
+ ret = compat_do_readv_writev(WRITE, file, vec, vlen, pos, flags);
out:
if (ret > 0)
-@@ -1196,9 +1275,9 @@ out:
+@@ -1138,9 +1217,9 @@ out:
return ret;
}
@@ -320,7 +324,7 @@
{
struct fd f = fdget_pos(fd);
ssize_t ret;
-@@ -1207,28 +1286,36 @@ COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd,
+@@ -1149,28 +1228,36 @@ COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd,
if (!f.file)
return -EBADF;
pos = f.file->f_pos;
@@ -360,7 +364,7 @@
fdput(f);
return ret;
}
-@@ -1238,7 +1325,7 @@ COMPAT_SYSCALL_DEFINE4(pwritev64, unsigned long, fd,
+@@ -1180,7 +1267,7 @@ COMPAT_SYSCALL_DEFINE4(pwritev64, unsigned long, fd,
const struct compat_iovec __user *,vec,
unsigned long, vlen, loff_t, pos)
{
@@ -369,13 +373,13 @@
}
#endif
-@@ -1248,8 +1335,21 @@ COMPAT_SYSCALL_DEFINE5(pwritev, compat_ulong_t, fd,
+@@ -1190,8 +1277,21 @@ COMPAT_SYSCALL_DEFINE5(pwritev, compat_ulong_t, fd,
{
loff_t pos = ((loff_t)pos_high << 32) | pos_low;
- return __compat_sys_pwritev64(fd, vec, vlen, pos);
+ return __compat_sys_pwritev64(fd, vec, vlen, pos, 0);
-+}
+ }
+
+COMPAT_SYSCALL_DEFINE6(pwritev2, compat_ulong_t, fd,
+ const struct compat_iovec __user *,vec,
@@ -387,13 +391,13 @@
+ return __compat_sys_writev(fd, vec, vlen, flags);
+
+ return __compat_sys_pwritev64(fd, vec, vlen, pos, flags);
- }
++}
+
#endif
static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
diff --git a/include/linux/compat.h b/include/linux/compat.h
-index ab25814..6e4be9e 100644
+index e649426..63a94e2 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -340,6 +340,12 @@ asmlinkage ssize_t compat_sys_preadv(compat_ulong_t fd,
@@ -410,10 +414,10 @@
#ifdef __ARCH_WANT_COMPAT_SYS_PREADV64
asmlinkage long compat_sys_preadv64(unsigned long fd,
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
-index 76d1e38..f25ed7b 100644
+index bda9b81..cedc22e 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
-@@ -575,8 +575,14 @@ asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf,
+@@ -571,8 +571,14 @@ asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf,
size_t count, loff_t pos);
asmlinkage long sys_preadv(unsigned long fd, const struct iovec __user *vec,
unsigned long vlen, unsigned long pos_l, unsigned long pos_h);
@@ -429,34 +433,34 @@
asmlinkage long sys_mkdir(const char __user *pathname, umode_t mode);
asmlinkage long sys_chdir(const char __user *filename);
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
-index e016bd9..4d2c4c5 100644
+index 22749c1..9406018 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -213,6 +213,10 @@ __SC_COMP(__NR_pwrite64, sys_pwrite64, compat_sys_pwrite64)
__SC_COMP(__NR_preadv, sys_preadv, compat_sys_preadv)
#define __NR_pwritev 70
__SC_COMP(__NR_pwritev, sys_pwritev, compat_sys_pwritev)
-+#define __NR_preadv2 282
++#define __NR_preadv2 281
+__SC_COMP(__NR_preadv2, sys_preadv2, compat_sys_preadv2)
-+#define __NR_pwritev2 283
++#define __NR_pwritev2 282
+__SC_COMP(__NR_pwritev2, sys_pwritev2, compat_sys_pwritev2)
/* fs/sendfile.c */
#define __NR3264_sendfile 71
-@@ -711,7 +715,7 @@ __SYSCALL(__NR_bpf, sys_bpf)
- __SC_COMP(__NR_execveat, sys_execveat, compat_sys_execveat)
+@@ -709,7 +713,7 @@ __SYSCALL(__NR_memfd_create, sys_memfd_create)
+ __SYSCALL(__NR_bpf, sys_bpf)
#undef __NR_syscalls
--#define __NR_syscalls 282
-+#define __NR_syscalls 284
+-#define __NR_syscalls 281
++#define __NR_syscalls 283
/*
* All syscalls below here should go away really,
diff --git a/mm/filemap.c b/mm/filemap.c
-index ad72420..7865f64 100644
+index 14b4642..530c263 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
-@@ -1453,6 +1453,7 @@ static void shrink_readahead_size_eio(struct file *filp,
+@@ -1457,6 +1457,7 @@ static void shrink_readahead_size_eio(struct file *filp,
* @ppos: current file position
* @iter: data destination
* @written: already copied
@@ -464,7 +468,7 @@
*
* This is a generic file read routine, and uses the
* mapping->a_ops->readpage() function for the actual low-level stuff.
-@@ -1461,7 +1462,7 @@ static void shrink_readahead_size_eio(struct file *filp,
+@@ -1465,7 +1466,7 @@ static void shrink_readahead_size_eio(struct file *filp,
* of the logic when it comes to error handling etc.
*/
static ssize_t do_generic_file_read(struct file *filp, loff_t *ppos,
@@ -473,7 +477,7 @@
{
struct address_space *mapping = filp->f_mapping;
struct inode *inode = mapping->host;
-@@ -1732,7 +1733,7 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
+@@ -1735,7 +1736,7 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
}
}