Merge branch 'work.iov_iter' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull compat iovec cleanups from Al Viro: "Christoph's series around import_iovec() and compat variant thereof" * 'work.iov_iter' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: security/keys: remove compat_keyctl_instantiate_key_iov mm: remove compat_process_vm_{readv,writev} fs: remove compat_sys_vmsplice fs: remove the compat readv/writev syscalls fs: remove various compat readv/writev helpers iov_iter: transparently handle compat iovecs in import_iovec iov_iter: refactor rw_copy_check_uvector and import_iovec iov_iter: move rw_copy_check_uvector() into lib/iov_iter.c compat.h: fix a spelling error in <linux/compat.h>
This commit is contained in:
commit
85ed13e78d
|
@ -301,9 +301,9 @@ __SYSCALL(__NR_flock, sys_flock)
|
|||
#define __NR_msync 144
|
||||
__SYSCALL(__NR_msync, sys_msync)
|
||||
#define __NR_readv 145
|
||||
__SYSCALL(__NR_readv, compat_sys_readv)
|
||||
__SYSCALL(__NR_readv, sys_readv)
|
||||
#define __NR_writev 146
|
||||
__SYSCALL(__NR_writev, compat_sys_writev)
|
||||
__SYSCALL(__NR_writev, sys_writev)
|
||||
#define __NR_getsid 147
|
||||
__SYSCALL(__NR_getsid, sys_getsid)
|
||||
#define __NR_fdatasync 148
|
||||
|
@ -697,7 +697,7 @@ __SYSCALL(__NR_sync_file_range2, compat_sys_aarch32_sync_file_range2)
|
|||
#define __NR_tee 342
|
||||
__SYSCALL(__NR_tee, sys_tee)
|
||||
#define __NR_vmsplice 343
|
||||
__SYSCALL(__NR_vmsplice, compat_sys_vmsplice)
|
||||
__SYSCALL(__NR_vmsplice, sys_vmsplice)
|
||||
#define __NR_move_pages 344
|
||||
__SYSCALL(__NR_move_pages, compat_sys_move_pages)
|
||||
#define __NR_getcpu 345
|
||||
|
@ -763,9 +763,9 @@ __SYSCALL(__NR_sendmmsg, compat_sys_sendmmsg)
|
|||
#define __NR_setns 375
|
||||
__SYSCALL(__NR_setns, sys_setns)
|
||||
#define __NR_process_vm_readv 376
|
||||
__SYSCALL(__NR_process_vm_readv, compat_sys_process_vm_readv)
|
||||
__SYSCALL(__NR_process_vm_readv, sys_process_vm_readv)
|
||||
#define __NR_process_vm_writev 377
|
||||
__SYSCALL(__NR_process_vm_writev, compat_sys_process_vm_writev)
|
||||
__SYSCALL(__NR_process_vm_writev, sys_process_vm_writev)
|
||||
#define __NR_kcmp 378
|
||||
__SYSCALL(__NR_kcmp, sys_kcmp)
|
||||
#define __NR_finit_module 379
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
15 n32 ioctl compat_sys_ioctl
|
||||
16 n32 pread64 sys_pread64
|
||||
17 n32 pwrite64 sys_pwrite64
|
||||
18 n32 readv compat_sys_readv
|
||||
19 n32 writev compat_sys_writev
|
||||
18 n32 readv sys_readv
|
||||
19 n32 writev sys_writev
|
||||
20 n32 access sys_access
|
||||
21 n32 pipe sysm_pipe
|
||||
22 n32 _newselect compat_sys_select
|
||||
|
@ -278,7 +278,7 @@
|
|||
267 n32 splice sys_splice
|
||||
268 n32 sync_file_range sys_sync_file_range
|
||||
269 n32 tee sys_tee
|
||||
270 n32 vmsplice compat_sys_vmsplice
|
||||
270 n32 vmsplice sys_vmsplice
|
||||
271 n32 move_pages compat_sys_move_pages
|
||||
272 n32 set_robust_list compat_sys_set_robust_list
|
||||
273 n32 get_robust_list compat_sys_get_robust_list
|
||||
|
@ -317,8 +317,8 @@
|
|||
306 n32 syncfs sys_syncfs
|
||||
307 n32 sendmmsg compat_sys_sendmmsg
|
||||
308 n32 setns sys_setns
|
||||
309 n32 process_vm_readv compat_sys_process_vm_readv
|
||||
310 n32 process_vm_writev compat_sys_process_vm_writev
|
||||
309 n32 process_vm_readv sys_process_vm_readv
|
||||
310 n32 process_vm_writev sys_process_vm_writev
|
||||
311 n32 kcmp sys_kcmp
|
||||
312 n32 finit_module sys_finit_module
|
||||
313 n32 sched_setattr sys_sched_setattr
|
||||
|
|
|
@ -156,8 +156,8 @@
|
|||
142 o32 _newselect sys_select compat_sys_select
|
||||
143 o32 flock sys_flock
|
||||
144 o32 msync sys_msync
|
||||
145 o32 readv sys_readv compat_sys_readv
|
||||
146 o32 writev sys_writev compat_sys_writev
|
||||
145 o32 readv sys_readv
|
||||
146 o32 writev sys_writev
|
||||
147 o32 cacheflush sys_cacheflush
|
||||
148 o32 cachectl sys_cachectl
|
||||
149 o32 sysmips __sys_sysmips
|
||||
|
@ -318,7 +318,7 @@
|
|||
304 o32 splice sys_splice
|
||||
305 o32 sync_file_range sys_sync_file_range sys32_sync_file_range
|
||||
306 o32 tee sys_tee
|
||||
307 o32 vmsplice sys_vmsplice compat_sys_vmsplice
|
||||
307 o32 vmsplice sys_vmsplice
|
||||
308 o32 move_pages sys_move_pages compat_sys_move_pages
|
||||
309 o32 set_robust_list sys_set_robust_list compat_sys_set_robust_list
|
||||
310 o32 get_robust_list sys_get_robust_list compat_sys_get_robust_list
|
||||
|
@ -356,8 +356,8 @@
|
|||
342 o32 syncfs sys_syncfs
|
||||
343 o32 sendmmsg sys_sendmmsg compat_sys_sendmmsg
|
||||
344 o32 setns sys_setns
|
||||
345 o32 process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv
|
||||
346 o32 process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev
|
||||
345 o32 process_vm_readv sys_process_vm_readv
|
||||
346 o32 process_vm_writev sys_process_vm_writev
|
||||
347 o32 kcmp sys_kcmp
|
||||
348 o32 finit_module sys_finit_module
|
||||
349 o32 sched_setattr sys_sched_setattr
|
||||
|
|
|
@ -159,8 +159,8 @@
|
|||
142 common _newselect sys_select compat_sys_select
|
||||
143 common flock sys_flock
|
||||
144 common msync sys_msync
|
||||
145 common readv sys_readv compat_sys_readv
|
||||
146 common writev sys_writev compat_sys_writev
|
||||
145 common readv sys_readv
|
||||
146 common writev sys_writev
|
||||
147 common getsid sys_getsid
|
||||
148 common fdatasync sys_fdatasync
|
||||
149 common _sysctl sys_ni_syscall
|
||||
|
@ -330,7 +330,7 @@
|
|||
292 32 sync_file_range parisc_sync_file_range
|
||||
292 64 sync_file_range sys_sync_file_range
|
||||
293 common tee sys_tee
|
||||
294 common vmsplice sys_vmsplice compat_sys_vmsplice
|
||||
294 common vmsplice sys_vmsplice
|
||||
295 common move_pages sys_move_pages compat_sys_move_pages
|
||||
296 common getcpu sys_getcpu
|
||||
297 common epoll_pwait sys_epoll_pwait compat_sys_epoll_pwait
|
||||
|
@ -372,8 +372,8 @@
|
|||
327 common syncfs sys_syncfs
|
||||
328 common setns sys_setns
|
||||
329 common sendmmsg sys_sendmmsg compat_sys_sendmmsg
|
||||
330 common process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv
|
||||
331 common process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev
|
||||
330 common process_vm_readv sys_process_vm_readv
|
||||
331 common process_vm_writev sys_process_vm_writev
|
||||
332 common kcmp sys_kcmp
|
||||
333 common finit_module sys_finit_module
|
||||
334 common sched_setattr sys_sched_setattr
|
||||
|
|
|
@ -193,8 +193,8 @@
|
|||
142 common _newselect sys_select compat_sys_select
|
||||
143 common flock sys_flock
|
||||
144 common msync sys_msync
|
||||
145 common readv sys_readv compat_sys_readv
|
||||
146 common writev sys_writev compat_sys_writev
|
||||
145 common readv sys_readv
|
||||
146 common writev sys_writev
|
||||
147 common getsid sys_getsid
|
||||
148 common fdatasync sys_fdatasync
|
||||
149 nospu _sysctl sys_ni_syscall
|
||||
|
@ -369,7 +369,7 @@
|
|||
282 common unshare sys_unshare
|
||||
283 common splice sys_splice
|
||||
284 common tee sys_tee
|
||||
285 common vmsplice sys_vmsplice compat_sys_vmsplice
|
||||
285 common vmsplice sys_vmsplice
|
||||
286 common openat sys_openat compat_sys_openat
|
||||
287 common mkdirat sys_mkdirat
|
||||
288 common mknodat sys_mknodat
|
||||
|
@ -449,8 +449,8 @@
|
|||
348 common syncfs sys_syncfs
|
||||
349 common sendmmsg sys_sendmmsg compat_sys_sendmmsg
|
||||
350 common setns sys_setns
|
||||
351 nospu process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv
|
||||
352 nospu process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev
|
||||
351 nospu process_vm_readv sys_process_vm_readv
|
||||
352 nospu process_vm_writev sys_process_vm_writev
|
||||
353 nospu finit_module sys_finit_module
|
||||
354 nospu kcmp sys_kcmp
|
||||
355 common sched_setattr sys_sched_setattr
|
||||
|
|
|
@ -134,8 +134,8 @@
|
|||
142 64 select sys_select -
|
||||
143 common flock sys_flock sys_flock
|
||||
144 common msync sys_msync sys_msync
|
||||
145 common readv sys_readv compat_sys_readv
|
||||
146 common writev sys_writev compat_sys_writev
|
||||
145 common readv sys_readv sys_readv
|
||||
146 common writev sys_writev sys_writev
|
||||
147 common getsid sys_getsid sys_getsid
|
||||
148 common fdatasync sys_fdatasync sys_fdatasync
|
||||
149 common _sysctl - -
|
||||
|
@ -316,7 +316,7 @@
|
|||
306 common splice sys_splice sys_splice
|
||||
307 common sync_file_range sys_sync_file_range compat_sys_s390_sync_file_range
|
||||
308 common tee sys_tee sys_tee
|
||||
309 common vmsplice sys_vmsplice compat_sys_vmsplice
|
||||
309 common vmsplice sys_vmsplice sys_vmsplice
|
||||
310 common move_pages sys_move_pages compat_sys_move_pages
|
||||
311 common getcpu sys_getcpu sys_getcpu
|
||||
312 common epoll_pwait sys_epoll_pwait compat_sys_epoll_pwait
|
||||
|
@ -347,8 +347,8 @@
|
|||
337 common clock_adjtime sys_clock_adjtime sys_clock_adjtime32
|
||||
338 common syncfs sys_syncfs sys_syncfs
|
||||
339 common setns sys_setns sys_setns
|
||||
340 common process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv
|
||||
341 common process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev
|
||||
340 common process_vm_readv sys_process_vm_readv sys_process_vm_readv
|
||||
341 common process_vm_writev sys_process_vm_writev sys_process_vm_writev
|
||||
342 common s390_runtime_instr sys_s390_runtime_instr sys_s390_runtime_instr
|
||||
343 common kcmp sys_kcmp sys_kcmp
|
||||
344 common finit_module sys_finit_module sys_finit_module
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
23 64 setuid sys_setuid
|
||||
24 32 getuid sys_getuid16
|
||||
24 64 getuid sys_getuid
|
||||
25 common vmsplice sys_vmsplice compat_sys_vmsplice
|
||||
25 common vmsplice sys_vmsplice
|
||||
26 common ptrace sys_ptrace compat_sys_ptrace
|
||||
27 common alarm sys_alarm
|
||||
28 common sigaltstack sys_sigaltstack compat_sys_sigaltstack
|
||||
|
@ -149,8 +149,8 @@
|
|||
117 common getrusage sys_getrusage compat_sys_getrusage
|
||||
118 common getsockopt sys_getsockopt sys_getsockopt
|
||||
119 common getcwd sys_getcwd
|
||||
120 common readv sys_readv compat_sys_readv
|
||||
121 common writev sys_writev compat_sys_writev
|
||||
120 common readv sys_readv
|
||||
121 common writev sys_writev
|
||||
122 common settimeofday sys_settimeofday compat_sys_settimeofday
|
||||
123 32 fchown sys_fchown16
|
||||
123 64 fchown sys_fchown
|
||||
|
@ -406,8 +406,8 @@
|
|||
335 common syncfs sys_syncfs
|
||||
336 common sendmmsg sys_sendmmsg compat_sys_sendmmsg
|
||||
337 common setns sys_setns
|
||||
338 common process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv
|
||||
339 common process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev
|
||||
338 common process_vm_readv sys_process_vm_readv
|
||||
339 common process_vm_writev sys_process_vm_writev
|
||||
340 32 kern_features sys_ni_syscall sys_kern_features
|
||||
340 64 kern_features sys_kern_features
|
||||
341 common kcmp sys_kcmp
|
||||
|
|
|
@ -12,8 +12,13 @@
|
|||
* Reuse the 64-bit entry points for the x32 versions that occupy different
|
||||
* slots in the syscall table.
|
||||
*/
|
||||
#define __x32_sys_readv __x64_sys_readv
|
||||
#define __x32_sys_writev __x64_sys_writev
|
||||
#define __x32_sys_getsockopt __x64_sys_getsockopt
|
||||
#define __x32_sys_setsockopt __x64_sys_setsockopt
|
||||
#define __x32_sys_vmsplice __x64_sys_vmsplice
|
||||
#define __x32_sys_process_vm_readv __x64_sys_process_vm_readv
|
||||
#define __x32_sys_process_vm_writev __x64_sys_process_vm_writev
|
||||
|
||||
#define __SYSCALL_64(nr, sym)
|
||||
|
||||
|
|
|
@ -156,8 +156,8 @@
|
|||
142 i386 _newselect sys_select compat_sys_select
|
||||
143 i386 flock sys_flock
|
||||
144 i386 msync sys_msync
|
||||
145 i386 readv sys_readv compat_sys_readv
|
||||
146 i386 writev sys_writev compat_sys_writev
|
||||
145 i386 readv sys_readv
|
||||
146 i386 writev sys_writev
|
||||
147 i386 getsid sys_getsid
|
||||
148 i386 fdatasync sys_fdatasync
|
||||
149 i386 _sysctl sys_ni_syscall
|
||||
|
@ -327,7 +327,7 @@
|
|||
313 i386 splice sys_splice
|
||||
314 i386 sync_file_range sys_ia32_sync_file_range
|
||||
315 i386 tee sys_tee
|
||||
316 i386 vmsplice sys_vmsplice compat_sys_vmsplice
|
||||
316 i386 vmsplice sys_vmsplice
|
||||
317 i386 move_pages sys_move_pages compat_sys_move_pages
|
||||
318 i386 getcpu sys_getcpu
|
||||
319 i386 epoll_pwait sys_epoll_pwait
|
||||
|
@ -358,8 +358,8 @@
|
|||
344 i386 syncfs sys_syncfs
|
||||
345 i386 sendmmsg sys_sendmmsg compat_sys_sendmmsg
|
||||
346 i386 setns sys_setns
|
||||
347 i386 process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv
|
||||
348 i386 process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev
|
||||
347 i386 process_vm_readv sys_process_vm_readv
|
||||
348 i386 process_vm_writev sys_process_vm_writev
|
||||
349 i386 kcmp sys_kcmp
|
||||
350 i386 finit_module sys_finit_module
|
||||
351 i386 sched_setattr sys_sched_setattr
|
||||
|
|
|
@ -371,8 +371,8 @@
|
|||
512 x32 rt_sigaction compat_sys_rt_sigaction
|
||||
513 x32 rt_sigreturn compat_sys_x32_rt_sigreturn
|
||||
514 x32 ioctl compat_sys_ioctl
|
||||
515 x32 readv compat_sys_readv
|
||||
516 x32 writev compat_sys_writev
|
||||
515 x32 readv sys_readv
|
||||
516 x32 writev sys_writev
|
||||
517 x32 recvfrom compat_sys_recvfrom
|
||||
518 x32 sendmsg compat_sys_sendmsg
|
||||
519 x32 recvmsg compat_sys_recvmsg
|
||||
|
@ -388,15 +388,15 @@
|
|||
529 x32 waitid compat_sys_waitid
|
||||
530 x32 set_robust_list compat_sys_set_robust_list
|
||||
531 x32 get_robust_list compat_sys_get_robust_list
|
||||
532 x32 vmsplice compat_sys_vmsplice
|
||||
532 x32 vmsplice sys_vmsplice
|
||||
533 x32 move_pages compat_sys_move_pages
|
||||
534 x32 preadv compat_sys_preadv64
|
||||
535 x32 pwritev compat_sys_pwritev64
|
||||
536 x32 rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo
|
||||
537 x32 recvmmsg compat_sys_recvmmsg_time64
|
||||
538 x32 sendmmsg compat_sys_sendmmsg
|
||||
539 x32 process_vm_readv compat_sys_process_vm_readv
|
||||
540 x32 process_vm_writev compat_sys_process_vm_writev
|
||||
539 x32 process_vm_readv sys_process_vm_readv
|
||||
540 x32 process_vm_writev sys_process_vm_writev
|
||||
541 x32 setsockopt sys_setsockopt
|
||||
542 x32 getsockopt sys_getsockopt
|
||||
543 x32 io_setup compat_sys_io_setup
|
||||
|
|
|
@ -333,16 +333,8 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
|
|||
struct iov_iter i;
|
||||
struct iovec *iov = NULL;
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
if (in_compat_syscall())
|
||||
ret = compat_import_iovec(rq_data_dir(rq),
|
||||
hdr->dxferp, hdr->iovec_count,
|
||||
0, &iov, &i);
|
||||
else
|
||||
#endif
|
||||
ret = import_iovec(rq_data_dir(rq),
|
||||
hdr->dxferp, hdr->iovec_count,
|
||||
0, &iov, &i);
|
||||
ret = import_iovec(rq_data_dir(rq), hdr->dxferp,
|
||||
hdr->iovec_count, 0, &iov, &i);
|
||||
if (ret < 0)
|
||||
goto out_free_cdb;
|
||||
|
||||
|
|
|
@ -1820,14 +1820,7 @@ sg_start_req(Sg_request *srp, unsigned char *cmd)
|
|||
struct iovec *iov = NULL;
|
||||
struct iov_iter i;
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
if (in_compat_syscall())
|
||||
res = compat_import_iovec(rw, hp->dxferp, iov_count,
|
||||
0, &iov, &i);
|
||||
else
|
||||
#endif
|
||||
res = import_iovec(rw, hp->dxferp, iov_count,
|
||||
0, &iov, &i);
|
||||
res = import_iovec(rw, hp->dxferp, iov_count, 0, &iov, &i);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
|
|
8
fs/aio.c
8
fs/aio.c
|
@ -1489,12 +1489,8 @@ static ssize_t aio_setup_rw(int rw, const struct iocb *iocb,
|
|||
*iovec = NULL;
|
||||
return ret;
|
||||
}
|
||||
#ifdef CONFIG_COMPAT
|
||||
if (compat)
|
||||
return compat_import_iovec(rw, buf, len, UIO_FASTIOV, iovec,
|
||||
iter);
|
||||
#endif
|
||||
return import_iovec(rw, buf, len, UIO_FASTIOV, iovec, iter);
|
||||
|
||||
return __import_iovec(rw, buf, len, UIO_FASTIOV, iovec, iter, compat);
|
||||
}
|
||||
|
||||
static inline void aio_rw_done(struct kiocb *req, ssize_t ret)
|
||||
|
|
|
@ -2852,13 +2852,8 @@ static ssize_t __io_import_iovec(int rw, struct io_kiocb *req,
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
if (req->ctx->compat)
|
||||
return compat_import_iovec(rw, buf, sqe_len, UIO_FASTIOV,
|
||||
iovec, iter);
|
||||
#endif
|
||||
|
||||
return import_iovec(rw, buf, sqe_len, UIO_FASTIOV, iovec, iter);
|
||||
return __import_iovec(rw, buf, sqe_len, UIO_FASTIOV, iovec, iter,
|
||||
req->ctx->compat);
|
||||
}
|
||||
|
||||
static ssize_t io_import_iovec(int rw, struct io_kiocb *req,
|
||||
|
@ -4200,8 +4195,9 @@ static int __io_recvmsg_copy_hdr(struct io_kiocb *req,
|
|||
sr->len);
|
||||
iomsg->iov = NULL;
|
||||
} else {
|
||||
ret = import_iovec(READ, uiov, iov_len, UIO_FASTIOV,
|
||||
&iomsg->iov, &iomsg->msg.msg_iter);
|
||||
ret = __import_iovec(READ, uiov, iov_len, UIO_FASTIOV,
|
||||
&iomsg->iov, &iomsg->msg.msg_iter,
|
||||
false);
|
||||
if (ret > 0)
|
||||
ret = 0;
|
||||
}
|
||||
|
@ -4241,9 +4237,9 @@ static int __io_compat_recvmsg_copy_hdr(struct io_kiocb *req,
|
|||
sr->len = iomsg->iov[0].iov_len;
|
||||
iomsg->iov = NULL;
|
||||
} else {
|
||||
ret = compat_import_iovec(READ, uiov, len, UIO_FASTIOV,
|
||||
&iomsg->iov,
|
||||
&iomsg->msg.msg_iter);
|
||||
ret = __import_iovec(READ, (struct iovec __user *)uiov, len,
|
||||
UIO_FASTIOV, &iomsg->iov,
|
||||
&iomsg->msg.msg_iter, true);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
|
362
fs/read_write.c
362
fs/read_write.c
|
@ -760,185 +760,6 @@ static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* rw_copy_check_uvector() - Copy an array of &struct iovec from userspace
|
||||
* into the kernel and check that it is valid.
|
||||
*
|
||||
* @type: One of %CHECK_IOVEC_ONLY, %READ, or %WRITE.
|
||||
* @uvector: Pointer to the userspace array.
|
||||
* @nr_segs: Number of elements in userspace array.
|
||||
* @fast_segs: Number of elements in @fast_pointer.
|
||||
* @fast_pointer: Pointer to (usually small on-stack) kernel array.
|
||||
* @ret_pointer: (output parameter) Pointer to a variable that will point to
|
||||
* either @fast_pointer, a newly allocated kernel array, or NULL,
|
||||
* depending on which array was used.
|
||||
*
|
||||
* This function copies an array of &struct iovec of @nr_segs from
|
||||
* userspace into the kernel and checks that each element is valid (e.g.
|
||||
* it does not point to a kernel address or cause overflow by being too
|
||||
* large, etc.).
|
||||
*
|
||||
* As an optimization, the caller may provide a pointer to a small
|
||||
* on-stack array in @fast_pointer, typically %UIO_FASTIOV elements long
|
||||
* (the size of this array, or 0 if unused, should be given in @fast_segs).
|
||||
*
|
||||
* @ret_pointer will always point to the array that was used, so the
|
||||
* caller must take care not to call kfree() on it e.g. in case the
|
||||
* @fast_pointer array was used and it was allocated on the stack.
|
||||
*
|
||||
* Return: The total number of bytes covered by the iovec array on success
|
||||
* or a negative error code on error.
|
||||
*/
|
||||
ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
|
||||
unsigned long nr_segs, unsigned long fast_segs,
|
||||
struct iovec *fast_pointer,
|
||||
struct iovec **ret_pointer)
|
||||
{
|
||||
unsigned long seg;
|
||||
ssize_t ret;
|
||||
struct iovec *iov = fast_pointer;
|
||||
|
||||
/*
|
||||
* SuS says "The readv() function *may* fail if the iovcnt argument
|
||||
* was less than or equal to 0, or greater than {IOV_MAX}. Linux has
|
||||
* traditionally returned zero for zero segments, so...
|
||||
*/
|
||||
if (nr_segs == 0) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* First get the "struct iovec" from user memory and
|
||||
* verify all the pointers
|
||||
*/
|
||||
if (nr_segs > UIO_MAXIOV) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (nr_segs > fast_segs) {
|
||||
iov = kmalloc_array(nr_segs, sizeof(struct iovec), GFP_KERNEL);
|
||||
if (iov == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (copy_from_user(iov, uvector, nr_segs*sizeof(*uvector))) {
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* According to the Single Unix Specification we should return EINVAL
|
||||
* if an element length is < 0 when cast to ssize_t or if the
|
||||
* total length would overflow the ssize_t return value of the
|
||||
* system call.
|
||||
*
|
||||
* Linux caps all read/write calls to MAX_RW_COUNT, and avoids the
|
||||
* overflow case.
|
||||
*/
|
||||
ret = 0;
|
||||
for (seg = 0; seg < nr_segs; seg++) {
|
||||
void __user *buf = iov[seg].iov_base;
|
||||
ssize_t len = (ssize_t)iov[seg].iov_len;
|
||||
|
||||
/* see if we we're about to use an invalid len or if
|
||||
* it's about to overflow ssize_t */
|
||||
if (len < 0) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (type >= 0
|
||||
&& unlikely(!access_ok(buf, len))) {
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
if (len > MAX_RW_COUNT - ret) {
|
||||
len = MAX_RW_COUNT - ret;
|
||||
iov[seg].iov_len = len;
|
||||
}
|
||||
ret += len;
|
||||
}
|
||||
out:
|
||||
*ret_pointer = iov;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
ssize_t compat_rw_copy_check_uvector(int type,
|
||||
const struct compat_iovec __user *uvector, unsigned long nr_segs,
|
||||
unsigned long fast_segs, struct iovec *fast_pointer,
|
||||
struct iovec **ret_pointer)
|
||||
{
|
||||
compat_ssize_t tot_len;
|
||||
struct iovec *iov = *ret_pointer = fast_pointer;
|
||||
ssize_t ret = 0;
|
||||
int seg;
|
||||
|
||||
/*
|
||||
* SuS says "The readv() function *may* fail if the iovcnt argument
|
||||
* was less than or equal to 0, or greater than {IOV_MAX}. Linux has
|
||||
* traditionally returned zero for zero segments, so...
|
||||
*/
|
||||
if (nr_segs == 0)
|
||||
goto out;
|
||||
|
||||
ret = -EINVAL;
|
||||
if (nr_segs > UIO_MAXIOV)
|
||||
goto out;
|
||||
if (nr_segs > fast_segs) {
|
||||
ret = -ENOMEM;
|
||||
iov = kmalloc_array(nr_segs, sizeof(struct iovec), GFP_KERNEL);
|
||||
if (iov == NULL)
|
||||
goto out;
|
||||
}
|
||||
*ret_pointer = iov;
|
||||
|
||||
ret = -EFAULT;
|
||||
if (!access_ok(uvector, nr_segs*sizeof(*uvector)))
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Single unix specification:
|
||||
* We should -EINVAL if an element length is not >= 0 and fitting an
|
||||
* ssize_t.
|
||||
*
|
||||
* In Linux, the total length is limited to MAX_RW_COUNT, there is
|
||||
* no overflow possibility.
|
||||
*/
|
||||
tot_len = 0;
|
||||
ret = -EINVAL;
|
||||
for (seg = 0; seg < nr_segs; seg++) {
|
||||
compat_uptr_t buf;
|
||||
compat_ssize_t len;
|
||||
|
||||
if (__get_user(len, &uvector->iov_len) ||
|
||||
__get_user(buf, &uvector->iov_base)) {
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
if (len < 0) /* size_t not fitting in compat_ssize_t .. */
|
||||
goto out;
|
||||
if (type >= 0 &&
|
||||
!access_ok(compat_ptr(buf), len)) {
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
if (len > MAX_RW_COUNT - tot_len)
|
||||
len = MAX_RW_COUNT - tot_len;
|
||||
tot_len += len;
|
||||
iov->iov_base = compat_ptr(buf);
|
||||
iov->iov_len = (compat_size_t) len;
|
||||
uvector++;
|
||||
iov++;
|
||||
}
|
||||
ret = tot_len;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static ssize_t do_iter_read(struct file *file, struct iov_iter *iter,
|
||||
loff_t *pos, rwf_t flags)
|
||||
{
|
||||
|
@ -1255,224 +1076,93 @@ SYSCALL_DEFINE6(pwritev2, unsigned long, fd, const struct iovec __user *, vec,
|
|||
return do_pwritev(fd, vec, vlen, pos, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Various compat syscalls. Note that they all pretend to take a native
|
||||
* iovec - import_iovec will properly treat those as compat_iovecs based on
|
||||
* in_compat_syscall().
|
||||
*/
|
||||
#ifdef CONFIG_COMPAT
|
||||
static size_t compat_readv(struct file *file,
|
||||
const struct compat_iovec __user *vec,
|
||||
unsigned long vlen, loff_t *pos, rwf_t flags)
|
||||
{
|
||||
struct iovec iovstack[UIO_FASTIOV];
|
||||
struct iovec *iov = iovstack;
|
||||
struct iov_iter iter;
|
||||
ssize_t ret;
|
||||
|
||||
ret = compat_import_iovec(READ, vec, vlen, UIO_FASTIOV, &iov, &iter);
|
||||
if (ret >= 0) {
|
||||
ret = do_iter_read(file, &iter, pos, flags);
|
||||
kfree(iov);
|
||||
}
|
||||
if (ret > 0)
|
||||
add_rchar(current, ret);
|
||||
inc_syscr(current);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static size_t do_compat_readv(compat_ulong_t fd,
|
||||
const struct compat_iovec __user *vec,
|
||||
compat_ulong_t vlen, rwf_t flags)
|
||||
{
|
||||
struct fd f = fdget_pos(fd);
|
||||
ssize_t ret;
|
||||
loff_t pos;
|
||||
|
||||
if (!f.file)
|
||||
return -EBADF;
|
||||
pos = f.file->f_pos;
|
||||
ret = compat_readv(f.file, vec, vlen, &pos, flags);
|
||||
if (ret >= 0)
|
||||
f.file->f_pos = pos;
|
||||
fdput_pos(f);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd,
|
||||
const struct compat_iovec __user *,vec,
|
||||
compat_ulong_t, vlen)
|
||||
{
|
||||
return do_compat_readv(fd, vec, vlen, 0);
|
||||
}
|
||||
|
||||
static long do_compat_preadv64(unsigned long fd,
|
||||
const struct compat_iovec __user *vec,
|
||||
unsigned long vlen, loff_t pos, rwf_t flags)
|
||||
{
|
||||
struct fd f;
|
||||
ssize_t ret;
|
||||
|
||||
if (pos < 0)
|
||||
return -EINVAL;
|
||||
f = fdget(fd);
|
||||
if (!f.file)
|
||||
return -EBADF;
|
||||
ret = -ESPIPE;
|
||||
if (f.file->f_mode & FMODE_PREAD)
|
||||
ret = compat_readv(f.file, vec, vlen, &pos, flags);
|
||||
fdput(f);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef __ARCH_WANT_COMPAT_SYS_PREADV64
|
||||
COMPAT_SYSCALL_DEFINE4(preadv64, unsigned long, fd,
|
||||
const struct compat_iovec __user *,vec,
|
||||
const struct iovec __user *, vec,
|
||||
unsigned long, vlen, loff_t, pos)
|
||||
{
|
||||
return do_compat_preadv64(fd, vec, vlen, pos, 0);
|
||||
return do_preadv(fd, vec, vlen, pos, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
COMPAT_SYSCALL_DEFINE5(preadv, compat_ulong_t, fd,
|
||||
const struct compat_iovec __user *,vec,
|
||||
const struct iovec __user *, vec,
|
||||
compat_ulong_t, vlen, u32, pos_low, u32, pos_high)
|
||||
{
|
||||
loff_t pos = ((loff_t)pos_high << 32) | pos_low;
|
||||
|
||||
return do_compat_preadv64(fd, vec, vlen, pos, 0);
|
||||
return do_preadv(fd, vec, vlen, pos, 0);
|
||||
}
|
||||
|
||||
#ifdef __ARCH_WANT_COMPAT_SYS_PREADV64V2
|
||||
COMPAT_SYSCALL_DEFINE5(preadv64v2, unsigned long, fd,
|
||||
const struct compat_iovec __user *,vec,
|
||||
const struct iovec __user *, vec,
|
||||
unsigned long, vlen, loff_t, pos, rwf_t, flags)
|
||||
{
|
||||
if (pos == -1)
|
||||
return do_compat_readv(fd, vec, vlen, flags);
|
||||
|
||||
return do_compat_preadv64(fd, vec, vlen, pos, flags);
|
||||
return do_readv(fd, vec, vlen, flags);
|
||||
return do_preadv(fd, vec, vlen, pos, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
COMPAT_SYSCALL_DEFINE6(preadv2, compat_ulong_t, fd,
|
||||
const struct compat_iovec __user *,vec,
|
||||
const struct iovec __user *, vec,
|
||||
compat_ulong_t, vlen, u32, pos_low, u32, pos_high,
|
||||
rwf_t, flags)
|
||||
{
|
||||
loff_t pos = ((loff_t)pos_high << 32) | pos_low;
|
||||
|
||||
if (pos == -1)
|
||||
return do_compat_readv(fd, vec, vlen, flags);
|
||||
|
||||
return do_compat_preadv64(fd, vec, vlen, pos, flags);
|
||||
}
|
||||
|
||||
static size_t compat_writev(struct file *file,
|
||||
const struct compat_iovec __user *vec,
|
||||
unsigned long vlen, loff_t *pos, rwf_t flags)
|
||||
{
|
||||
struct iovec iovstack[UIO_FASTIOV];
|
||||
struct iovec *iov = iovstack;
|
||||
struct iov_iter iter;
|
||||
ssize_t ret;
|
||||
|
||||
ret = compat_import_iovec(WRITE, vec, vlen, UIO_FASTIOV, &iov, &iter);
|
||||
if (ret >= 0) {
|
||||
file_start_write(file);
|
||||
ret = do_iter_write(file, &iter, pos, flags);
|
||||
file_end_write(file);
|
||||
kfree(iov);
|
||||
}
|
||||
if (ret > 0)
|
||||
add_wchar(current, ret);
|
||||
inc_syscw(current);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static size_t do_compat_writev(compat_ulong_t fd,
|
||||
const struct compat_iovec __user* vec,
|
||||
compat_ulong_t vlen, rwf_t flags)
|
||||
{
|
||||
struct fd f = fdget_pos(fd);
|
||||
ssize_t ret;
|
||||
loff_t pos;
|
||||
|
||||
if (!f.file)
|
||||
return -EBADF;
|
||||
pos = f.file->f_pos;
|
||||
ret = compat_writev(f.file, vec, vlen, &pos, flags);
|
||||
if (ret >= 0)
|
||||
f.file->f_pos = pos;
|
||||
fdput_pos(f);
|
||||
return ret;
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd,
|
||||
const struct compat_iovec __user *, vec,
|
||||
compat_ulong_t, vlen)
|
||||
{
|
||||
return do_compat_writev(fd, vec, vlen, 0);
|
||||
}
|
||||
|
||||
static long do_compat_pwritev64(unsigned long fd,
|
||||
const struct compat_iovec __user *vec,
|
||||
unsigned long vlen, loff_t pos, rwf_t flags)
|
||||
{
|
||||
struct fd f;
|
||||
ssize_t ret;
|
||||
|
||||
if (pos < 0)
|
||||
return -EINVAL;
|
||||
f = fdget(fd);
|
||||
if (!f.file)
|
||||
return -EBADF;
|
||||
ret = -ESPIPE;
|
||||
if (f.file->f_mode & FMODE_PWRITE)
|
||||
ret = compat_writev(f.file, vec, vlen, &pos, flags);
|
||||
fdput(f);
|
||||
return ret;
|
||||
return do_readv(fd, vec, vlen, flags);
|
||||
return do_preadv(fd, vec, vlen, pos, flags);
|
||||
}
|
||||
|
||||
#ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64
|
||||
COMPAT_SYSCALL_DEFINE4(pwritev64, unsigned long, fd,
|
||||
const struct compat_iovec __user *,vec,
|
||||
const struct iovec __user *, vec,
|
||||
unsigned long, vlen, loff_t, pos)
|
||||
{
|
||||
return do_compat_pwritev64(fd, vec, vlen, pos, 0);
|
||||
return do_pwritev(fd, vec, vlen, pos, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
COMPAT_SYSCALL_DEFINE5(pwritev, compat_ulong_t, fd,
|
||||
const struct compat_iovec __user *,vec,
|
||||
const struct iovec __user *,vec,
|
||||
compat_ulong_t, vlen, u32, pos_low, u32, pos_high)
|
||||
{
|
||||
loff_t pos = ((loff_t)pos_high << 32) | pos_low;
|
||||
|
||||
return do_compat_pwritev64(fd, vec, vlen, pos, 0);
|
||||
return do_pwritev(fd, vec, vlen, pos, 0);
|
||||
}
|
||||
|
||||
#ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64V2
|
||||
COMPAT_SYSCALL_DEFINE5(pwritev64v2, unsigned long, fd,
|
||||
const struct compat_iovec __user *,vec,
|
||||
const struct iovec __user *, vec,
|
||||
unsigned long, vlen, loff_t, pos, rwf_t, flags)
|
||||
{
|
||||
if (pos == -1)
|
||||
return do_compat_writev(fd, vec, vlen, flags);
|
||||
|
||||
return do_compat_pwritev64(fd, vec, vlen, pos, flags);
|
||||
return do_writev(fd, vec, vlen, flags);
|
||||
return do_pwritev(fd, vec, vlen, pos, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
COMPAT_SYSCALL_DEFINE6(pwritev2, compat_ulong_t, fd,
|
||||
const struct compat_iovec __user *,vec,
|
||||
const struct iovec __user *,vec,
|
||||
compat_ulong_t, vlen, u32, pos_low, u32, pos_high, rwf_t, flags)
|
||||
{
|
||||
loff_t pos = ((loff_t)pos_high << 32) | pos_low;
|
||||
|
||||
if (pos == -1)
|
||||
return do_compat_writev(fd, vec, vlen, flags);
|
||||
|
||||
return do_compat_pwritev64(fd, vec, vlen, pos, flags);
|
||||
return do_writev(fd, vec, vlen, flags);
|
||||
return do_pwritev(fd, vec, vlen, pos, flags);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* CONFIG_COMPAT */
|
||||
|
||||
static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
|
||||
size_t count, loff_t max)
|
||||
|
|
61
fs/splice.c
61
fs/splice.c
|
@ -33,7 +33,6 @@
|
|||
#include <linux/security.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/socket.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/sched/signal.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
@ -1352,20 +1351,6 @@ static int vmsplice_type(struct fd f, int *type)
|
|||
* Currently we punt and implement it as a normal copy, see pipe_to_user().
|
||||
*
|
||||
*/
|
||||
static long do_vmsplice(struct file *f, struct iov_iter *iter, unsigned int flags)
|
||||
{
|
||||
if (unlikely(flags & ~SPLICE_F_ALL))
|
||||
return -EINVAL;
|
||||
|
||||
if (!iov_iter_count(iter))
|
||||
return 0;
|
||||
|
||||
if (iov_iter_rw(iter) == WRITE)
|
||||
return vmsplice_to_pipe(f, iter, flags);
|
||||
else
|
||||
return vmsplice_to_user(f, iter, flags);
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, uiov,
|
||||
unsigned long, nr_segs, unsigned int, flags)
|
||||
{
|
||||
|
@ -1376,6 +1361,9 @@ SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, uiov,
|
|||
struct fd f;
|
||||
int type;
|
||||
|
||||
if (unlikely(flags & ~SPLICE_F_ALL))
|
||||
return -EINVAL;
|
||||
|
||||
f = fdget(fd);
|
||||
error = vmsplice_type(f, &type);
|
||||
if (error)
|
||||
|
@ -1383,41 +1371,22 @@ SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, uiov,
|
|||
|
||||
error = import_iovec(type, uiov, nr_segs,
|
||||
ARRAY_SIZE(iovstack), &iov, &iter);
|
||||
if (error >= 0) {
|
||||
error = do_vmsplice(f.file, &iter, flags);
|
||||
kfree(iov);
|
||||
}
|
||||
if (error < 0)
|
||||
goto out_fdput;
|
||||
|
||||
if (!iov_iter_count(&iter))
|
||||
error = 0;
|
||||
else if (iov_iter_rw(&iter) == WRITE)
|
||||
error = vmsplice_to_pipe(f.file, &iter, flags);
|
||||
else
|
||||
error = vmsplice_to_user(f.file, &iter, flags);
|
||||
|
||||
kfree(iov);
|
||||
out_fdput:
|
||||
fdput(f);
|
||||
return error;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
COMPAT_SYSCALL_DEFINE4(vmsplice, int, fd, const struct compat_iovec __user *, iov32,
|
||||
unsigned int, nr_segs, unsigned int, flags)
|
||||
{
|
||||
struct iovec iovstack[UIO_FASTIOV];
|
||||
struct iovec *iov = iovstack;
|
||||
struct iov_iter iter;
|
||||
ssize_t error;
|
||||
struct fd f;
|
||||
int type;
|
||||
|
||||
f = fdget(fd);
|
||||
error = vmsplice_type(f, &type);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = compat_import_iovec(type, iov32, nr_segs,
|
||||
ARRAY_SIZE(iovstack), &iov, &iter);
|
||||
if (error >= 0) {
|
||||
error = do_vmsplice(f.file, &iter, flags);
|
||||
kfree(iov);
|
||||
}
|
||||
fdput(f);
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in,
|
||||
int, fd_out, loff_t __user *, off_out,
|
||||
size_t, len, unsigned int, flags)
|
||||
|
|
|
@ -91,6 +91,11 @@
|
|||
static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
|
||||
#endif /* COMPAT_SYSCALL_DEFINEx */
|
||||
|
||||
struct compat_iovec {
|
||||
compat_uptr_t iov_base;
|
||||
compat_size_t iov_len;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
#ifndef compat_user_stack_pointer
|
||||
|
@ -248,11 +253,6 @@ typedef struct compat_siginfo {
|
|||
} _sifields;
|
||||
} compat_siginfo_t;
|
||||
|
||||
struct compat_iovec {
|
||||
compat_uptr_t iov_base;
|
||||
compat_size_t iov_len;
|
||||
};
|
||||
|
||||
struct compat_rlimit {
|
||||
compat_ulong_t rlim_cur;
|
||||
compat_ulong_t rlim_max;
|
||||
|
@ -451,12 +451,6 @@ extern long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
|||
|
||||
struct epoll_event; /* fortunately, this one is fixed-layout */
|
||||
|
||||
extern ssize_t compat_rw_copy_check_uvector(int type,
|
||||
const struct compat_iovec __user *uvector,
|
||||
unsigned long nr_segs,
|
||||
unsigned long fast_segs, struct iovec *fast_pointer,
|
||||
struct iovec **ret_pointer);
|
||||
|
||||
extern void __user *compat_alloc_user_space(unsigned long len);
|
||||
|
||||
int compat_restore_altstack(const compat_stack_t __user *uss);
|
||||
|
@ -551,26 +545,22 @@ asmlinkage long compat_sys_getdents(unsigned int fd,
|
|||
|
||||
/* fs/read_write.c */
|
||||
asmlinkage long compat_sys_lseek(unsigned int, compat_off_t, unsigned int);
|
||||
asmlinkage ssize_t compat_sys_readv(compat_ulong_t fd,
|
||||
const struct compat_iovec __user *vec, compat_ulong_t vlen);
|
||||
asmlinkage ssize_t compat_sys_writev(compat_ulong_t fd,
|
||||
const struct compat_iovec __user *vec, compat_ulong_t vlen);
|
||||
/* No generic prototype for pread64 and pwrite64 */
|
||||
asmlinkage ssize_t compat_sys_preadv(compat_ulong_t fd,
|
||||
const struct compat_iovec __user *vec,
|
||||
const struct iovec __user *vec,
|
||||
compat_ulong_t vlen, u32 pos_low, u32 pos_high);
|
||||
asmlinkage ssize_t compat_sys_pwritev(compat_ulong_t fd,
|
||||
const struct compat_iovec __user *vec,
|
||||
const struct iovec __user *vec,
|
||||
compat_ulong_t vlen, u32 pos_low, u32 pos_high);
|
||||
#ifdef __ARCH_WANT_COMPAT_SYS_PREADV64
|
||||
asmlinkage long compat_sys_preadv64(unsigned long fd,
|
||||
const struct compat_iovec __user *vec,
|
||||
const struct iovec __user *vec,
|
||||
unsigned long vlen, loff_t pos);
|
||||
#endif
|
||||
|
||||
#ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64
|
||||
asmlinkage long compat_sys_pwritev64(unsigned long fd,
|
||||
const struct compat_iovec __user *vec,
|
||||
const struct iovec __user *vec,
|
||||
unsigned long vlen, loff_t pos);
|
||||
#endif
|
||||
|
||||
|
@ -607,10 +597,6 @@ asmlinkage long compat_sys_signalfd4(int ufd,
|
|||
const compat_sigset_t __user *sigmask,
|
||||
compat_size_t sigsetsize, int flags);
|
||||
|
||||
/* fs/splice.c */
|
||||
asmlinkage long compat_sys_vmsplice(int fd, const struct compat_iovec __user *,
|
||||
unsigned int nr_segs, unsigned int flags);
|
||||
|
||||
/* fs/stat.c */
|
||||
asmlinkage long compat_sys_newfstatat(unsigned int dfd,
|
||||
const char __user *filename,
|
||||
|
@ -794,32 +780,24 @@ asmlinkage long compat_sys_open_by_handle_at(int mountdirfd,
|
|||
int flags);
|
||||
asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg,
|
||||
unsigned vlen, unsigned int flags);
|
||||
asmlinkage ssize_t compat_sys_process_vm_readv(compat_pid_t pid,
|
||||
const struct compat_iovec __user *lvec,
|
||||
compat_ulong_t liovcnt, const struct compat_iovec __user *rvec,
|
||||
compat_ulong_t riovcnt, compat_ulong_t flags);
|
||||
asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid,
|
||||
const struct compat_iovec __user *lvec,
|
||||
compat_ulong_t liovcnt, const struct compat_iovec __user *rvec,
|
||||
compat_ulong_t riovcnt, compat_ulong_t flags);
|
||||
asmlinkage long compat_sys_execveat(int dfd, const char __user *filename,
|
||||
const compat_uptr_t __user *argv,
|
||||
const compat_uptr_t __user *envp, int flags);
|
||||
asmlinkage ssize_t compat_sys_preadv2(compat_ulong_t fd,
|
||||
const struct compat_iovec __user *vec,
|
||||
const struct iovec __user *vec,
|
||||
compat_ulong_t vlen, u32 pos_low, u32 pos_high, rwf_t flags);
|
||||
asmlinkage ssize_t compat_sys_pwritev2(compat_ulong_t fd,
|
||||
const struct compat_iovec __user *vec,
|
||||
const struct iovec __user *vec,
|
||||
compat_ulong_t vlen, u32 pos_low, u32 pos_high, rwf_t flags);
|
||||
#ifdef __ARCH_WANT_COMPAT_SYS_PREADV64V2
|
||||
asmlinkage long compat_sys_readv64v2(unsigned long fd,
|
||||
const struct compat_iovec __user *vec,
|
||||
asmlinkage long compat_sys_preadv64v2(unsigned long fd,
|
||||
const struct iovec __user *vec,
|
||||
unsigned long vlen, loff_t pos, rwf_t flags);
|
||||
#endif
|
||||
|
||||
#ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64V2
|
||||
asmlinkage long compat_sys_pwritev64v2(unsigned long fd,
|
||||
const struct compat_iovec __user *vec,
|
||||
const struct iovec __user *vec,
|
||||
unsigned long vlen, loff_t pos, rwf_t flags);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -178,14 +178,6 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
|
|||
/* File supports async buffered reads */
|
||||
#define FMODE_BUF_RASYNC ((__force fmode_t)0x40000000)
|
||||
|
||||
/*
|
||||
* Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector
|
||||
* that indicates that they should check the contents of the iovec are
|
||||
* valid, but not check the memory that the iovec elements
|
||||
* points too.
|
||||
*/
|
||||
#define CHECK_IOVEC_ONLY -1
|
||||
|
||||
/*
|
||||
* Attribute flags. These should be or-ed together to figure out what
|
||||
* has been changed!
|
||||
|
@ -1887,11 +1879,6 @@ static inline int call_mmap(struct file *file, struct vm_area_struct *vma)
|
|||
return file->f_op->mmap(file, vma);
|
||||
}
|
||||
|
||||
ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
|
||||
unsigned long nr_segs, unsigned long fast_segs,
|
||||
struct iovec *fast_pointer,
|
||||
struct iovec **ret_pointer);
|
||||
|
||||
extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *);
|
||||
extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *);
|
||||
extern ssize_t vfs_readv(struct file *, const struct iovec __user *,
|
||||
|
|
|
@ -266,17 +266,15 @@ bool csum_and_copy_from_iter_full(void *addr, size_t bytes, __wsum *csum, struct
|
|||
size_t hash_and_copy_to_iter(const void *addr, size_t bytes, void *hashp,
|
||||
struct iov_iter *i);
|
||||
|
||||
ssize_t import_iovec(int type, const struct iovec __user * uvector,
|
||||
unsigned nr_segs, unsigned fast_segs,
|
||||
struct iovec **iov, struct iov_iter *i);
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
struct compat_iovec;
|
||||
ssize_t compat_import_iovec(int type, const struct compat_iovec __user * uvector,
|
||||
unsigned nr_segs, unsigned fast_segs,
|
||||
struct iovec **iov, struct iov_iter *i);
|
||||
#endif
|
||||
|
||||
struct iovec *iovec_from_user(const struct iovec __user *uvector,
|
||||
unsigned long nr_segs, unsigned long fast_segs,
|
||||
struct iovec *fast_iov, bool compat);
|
||||
ssize_t import_iovec(int type, const struct iovec __user *uvec,
|
||||
unsigned nr_segs, unsigned fast_segs, struct iovec **iovp,
|
||||
struct iov_iter *i);
|
||||
ssize_t __import_iovec(int type, const struct iovec __user *uvec,
|
||||
unsigned nr_segs, unsigned fast_segs, struct iovec **iovp,
|
||||
struct iov_iter *i, bool compat);
|
||||
int import_single_range(int type, void __user *buf, size_t len,
|
||||
struct iovec *iov, struct iov_iter *i);
|
||||
|
||||
|
|
|
@ -207,9 +207,9 @@ __SYSCALL(__NR_read, sys_read)
|
|||
#define __NR_write 64
|
||||
__SYSCALL(__NR_write, sys_write)
|
||||
#define __NR_readv 65
|
||||
__SC_COMP(__NR_readv, sys_readv, compat_sys_readv)
|
||||
__SC_COMP(__NR_readv, sys_readv, sys_readv)
|
||||
#define __NR_writev 66
|
||||
__SC_COMP(__NR_writev, sys_writev, compat_sys_writev)
|
||||
__SC_COMP(__NR_writev, sys_writev, sys_writev)
|
||||
#define __NR_pread64 67
|
||||
__SC_COMP(__NR_pread64, sys_pread64, compat_sys_pread64)
|
||||
#define __NR_pwrite64 68
|
||||
|
@ -237,7 +237,7 @@ __SC_COMP(__NR_signalfd4, sys_signalfd4, compat_sys_signalfd4)
|
|||
|
||||
/* fs/splice.c */
|
||||
#define __NR_vmsplice 75
|
||||
__SC_COMP(__NR_vmsplice, sys_vmsplice, compat_sys_vmsplice)
|
||||
__SYSCALL(__NR_vmsplice, sys_vmsplice)
|
||||
#define __NR_splice 76
|
||||
__SYSCALL(__NR_splice, sys_splice)
|
||||
#define __NR_tee 77
|
||||
|
@ -727,11 +727,9 @@ __SYSCALL(__NR_setns, sys_setns)
|
|||
#define __NR_sendmmsg 269
|
||||
__SC_COMP(__NR_sendmmsg, sys_sendmmsg, compat_sys_sendmmsg)
|
||||
#define __NR_process_vm_readv 270
|
||||
__SC_COMP(__NR_process_vm_readv, sys_process_vm_readv, \
|
||||
compat_sys_process_vm_readv)
|
||||
__SYSCALL(__NR_process_vm_readv, sys_process_vm_readv)
|
||||
#define __NR_process_vm_writev 271
|
||||
__SC_COMP(__NR_process_vm_writev, sys_process_vm_writev, \
|
||||
compat_sys_process_vm_writev)
|
||||
__SYSCALL(__NR_process_vm_writev, sys_process_vm_writev)
|
||||
#define __NR_kcmp 272
|
||||
__SYSCALL(__NR_kcmp, sys_kcmp)
|
||||
#define __NR_finit_module 273
|
||||
|
|
178
lib/iov_iter.c
178
lib/iov_iter.c
|
@ -7,6 +7,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/splice.h>
|
||||
#include <linux/compat.h>
|
||||
#include <net/checksum.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/instrumented.h>
|
||||
|
@ -1645,16 +1646,145 @@ const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags)
|
|||
}
|
||||
EXPORT_SYMBOL(dup_iter);
|
||||
|
||||
static int copy_compat_iovec_from_user(struct iovec *iov,
|
||||
const struct iovec __user *uvec, unsigned long nr_segs)
|
||||
{
|
||||
const struct compat_iovec __user *uiov =
|
||||
(const struct compat_iovec __user *)uvec;
|
||||
int ret = -EFAULT, i;
|
||||
|
||||
if (!user_access_begin(uvec, nr_segs * sizeof(*uvec)))
|
||||
return -EFAULT;
|
||||
|
||||
for (i = 0; i < nr_segs; i++) {
|
||||
compat_uptr_t buf;
|
||||
compat_ssize_t len;
|
||||
|
||||
unsafe_get_user(len, &uiov[i].iov_len, uaccess_end);
|
||||
unsafe_get_user(buf, &uiov[i].iov_base, uaccess_end);
|
||||
|
||||
/* check for compat_size_t not fitting in compat_ssize_t .. */
|
||||
if (len < 0) {
|
||||
ret = -EINVAL;
|
||||
goto uaccess_end;
|
||||
}
|
||||
iov[i].iov_base = compat_ptr(buf);
|
||||
iov[i].iov_len = len;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
uaccess_end:
|
||||
user_access_end();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int copy_iovec_from_user(struct iovec *iov,
|
||||
const struct iovec __user *uvec, unsigned long nr_segs)
|
||||
{
|
||||
unsigned long seg;
|
||||
|
||||
if (copy_from_user(iov, uvec, nr_segs * sizeof(*uvec)))
|
||||
return -EFAULT;
|
||||
for (seg = 0; seg < nr_segs; seg++) {
|
||||
if ((ssize_t)iov[seg].iov_len < 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct iovec *iovec_from_user(const struct iovec __user *uvec,
|
||||
unsigned long nr_segs, unsigned long fast_segs,
|
||||
struct iovec *fast_iov, bool compat)
|
||||
{
|
||||
struct iovec *iov = fast_iov;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* SuS says "The readv() function *may* fail if the iovcnt argument was
|
||||
* less than or equal to 0, or greater than {IOV_MAX}. Linux has
|
||||
* traditionally returned zero for zero segments, so...
|
||||
*/
|
||||
if (nr_segs == 0)
|
||||
return iov;
|
||||
if (nr_segs > UIO_MAXIOV)
|
||||
return ERR_PTR(-EINVAL);
|
||||
if (nr_segs > fast_segs) {
|
||||
iov = kmalloc_array(nr_segs, sizeof(struct iovec), GFP_KERNEL);
|
||||
if (!iov)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
if (compat)
|
||||
ret = copy_compat_iovec_from_user(iov, uvec, nr_segs);
|
||||
else
|
||||
ret = copy_iovec_from_user(iov, uvec, nr_segs);
|
||||
if (ret) {
|
||||
if (iov != fast_iov)
|
||||
kfree(iov);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return iov;
|
||||
}
|
||||
|
||||
ssize_t __import_iovec(int type, const struct iovec __user *uvec,
|
||||
unsigned nr_segs, unsigned fast_segs, struct iovec **iovp,
|
||||
struct iov_iter *i, bool compat)
|
||||
{
|
||||
ssize_t total_len = 0;
|
||||
unsigned long seg;
|
||||
struct iovec *iov;
|
||||
|
||||
iov = iovec_from_user(uvec, nr_segs, fast_segs, *iovp, compat);
|
||||
if (IS_ERR(iov)) {
|
||||
*iovp = NULL;
|
||||
return PTR_ERR(iov);
|
||||
}
|
||||
|
||||
/*
|
||||
* According to the Single Unix Specification we should return EINVAL if
|
||||
* an element length is < 0 when cast to ssize_t or if the total length
|
||||
* would overflow the ssize_t return value of the system call.
|
||||
*
|
||||
* Linux caps all read/write calls to MAX_RW_COUNT, and avoids the
|
||||
* overflow case.
|
||||
*/
|
||||
for (seg = 0; seg < nr_segs; seg++) {
|
||||
ssize_t len = (ssize_t)iov[seg].iov_len;
|
||||
|
||||
if (!access_ok(iov[seg].iov_base, len)) {
|
||||
if (iov != *iovp)
|
||||
kfree(iov);
|
||||
*iovp = NULL;
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (len > MAX_RW_COUNT - total_len) {
|
||||
len = MAX_RW_COUNT - total_len;
|
||||
iov[seg].iov_len = len;
|
||||
}
|
||||
total_len += len;
|
||||
}
|
||||
|
||||
iov_iter_init(i, type, iov, nr_segs, total_len);
|
||||
if (iov == *iovp)
|
||||
*iovp = NULL;
|
||||
else
|
||||
*iovp = iov;
|
||||
return total_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* import_iovec() - Copy an array of &struct iovec from userspace
|
||||
* into the kernel, check that it is valid, and initialize a new
|
||||
* &struct iov_iter iterator to access it.
|
||||
*
|
||||
* @type: One of %READ or %WRITE.
|
||||
* @uvector: Pointer to the userspace array.
|
||||
* @uvec: Pointer to the userspace array.
|
||||
* @nr_segs: Number of elements in userspace array.
|
||||
* @fast_segs: Number of elements in @iov.
|
||||
* @iov: (input and output parameter) Pointer to pointer to (usually small
|
||||
* @iovp: (input and output parameter) Pointer to pointer to (usually small
|
||||
* on-stack) kernel array.
|
||||
* @i: Pointer to iterator that will be initialized on success.
|
||||
*
|
||||
|
@ -1667,51 +1797,15 @@ EXPORT_SYMBOL(dup_iter);
|
|||
*
|
||||
* Return: Negative error code on error, bytes imported on success
|
||||
*/
|
||||
ssize_t import_iovec(int type, const struct iovec __user * uvector,
|
||||
ssize_t import_iovec(int type, const struct iovec __user *uvec,
|
||||
unsigned nr_segs, unsigned fast_segs,
|
||||
struct iovec **iov, struct iov_iter *i)
|
||||
struct iovec **iovp, struct iov_iter *i)
|
||||
{
|
||||
ssize_t n;
|
||||
struct iovec *p;
|
||||
n = rw_copy_check_uvector(type, uvector, nr_segs, fast_segs,
|
||||
*iov, &p);
|
||||
if (n < 0) {
|
||||
if (p != *iov)
|
||||
kfree(p);
|
||||
*iov = NULL;
|
||||
return n;
|
||||
}
|
||||
iov_iter_init(i, type, p, nr_segs, n);
|
||||
*iov = p == *iov ? NULL : p;
|
||||
return n;
|
||||
return __import_iovec(type, uvec, nr_segs, fast_segs, iovp, i,
|
||||
in_compat_syscall());
|
||||
}
|
||||
EXPORT_SYMBOL(import_iovec);
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#include <linux/compat.h>
|
||||
|
||||
ssize_t compat_import_iovec(int type,
|
||||
const struct compat_iovec __user * uvector,
|
||||
unsigned nr_segs, unsigned fast_segs,
|
||||
struct iovec **iov, struct iov_iter *i)
|
||||
{
|
||||
ssize_t n;
|
||||
struct iovec *p;
|
||||
n = compat_rw_copy_check_uvector(type, uvector, nr_segs, fast_segs,
|
||||
*iov, &p);
|
||||
if (n < 0) {
|
||||
if (p != *iov)
|
||||
kfree(p);
|
||||
*iov = NULL;
|
||||
return n;
|
||||
}
|
||||
iov_iter_init(i, type, p, nr_segs, n);
|
||||
*iov = p == *iov ? NULL : p;
|
||||
return n;
|
||||
}
|
||||
EXPORT_SYMBOL(compat_import_iovec);
|
||||
#endif
|
||||
|
||||
int import_single_range(int rw, void __user *buf, size_t len,
|
||||
struct iovec *iov, struct iov_iter *i)
|
||||
{
|
||||
|
|
|
@ -14,10 +14,6 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/syscalls.h>
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#include <linux/compat.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* process_vm_rw_pages - read/write pages from task specified
|
||||
* @pages: array of pointers to pages we want to copy
|
||||
|
@ -276,20 +272,17 @@ static ssize_t process_vm_rw(pid_t pid,
|
|||
if (rc < 0)
|
||||
return rc;
|
||||
if (!iov_iter_count(&iter))
|
||||
goto free_iovecs;
|
||||
|
||||
rc = rw_copy_check_uvector(CHECK_IOVEC_ONLY, rvec, riovcnt, UIO_FASTIOV,
|
||||
iovstack_r, &iov_r);
|
||||
if (rc <= 0)
|
||||
goto free_iovecs;
|
||||
|
||||
goto free_iov_l;
|
||||
iov_r = iovec_from_user(rvec, riovcnt, UIO_FASTIOV, iovstack_r, false);
|
||||
if (IS_ERR(iov_r)) {
|
||||
rc = PTR_ERR(iov_r);
|
||||
goto free_iov_l;
|
||||
}
|
||||
rc = process_vm_rw_core(pid, &iter, iov_r, riovcnt, flags, vm_write);
|
||||
|
||||
free_iovecs:
|
||||
if (iov_r != iovstack_r)
|
||||
kfree(iov_r);
|
||||
free_iov_l:
|
||||
kfree(iov_l);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -307,68 +300,3 @@ SYSCALL_DEFINE6(process_vm_writev, pid_t, pid,
|
|||
{
|
||||
return process_vm_rw(pid, lvec, liovcnt, rvec, riovcnt, flags, 1);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
static ssize_t
|
||||
compat_process_vm_rw(compat_pid_t pid,
|
||||
const struct compat_iovec __user *lvec,
|
||||
unsigned long liovcnt,
|
||||
const struct compat_iovec __user *rvec,
|
||||
unsigned long riovcnt,
|
||||
unsigned long flags, int vm_write)
|
||||
{
|
||||
struct iovec iovstack_l[UIO_FASTIOV];
|
||||
struct iovec iovstack_r[UIO_FASTIOV];
|
||||
struct iovec *iov_l = iovstack_l;
|
||||
struct iovec *iov_r = iovstack_r;
|
||||
struct iov_iter iter;
|
||||
ssize_t rc = -EFAULT;
|
||||
int dir = vm_write ? WRITE : READ;
|
||||
|
||||
if (flags != 0)
|
||||
return -EINVAL;
|
||||
|
||||
rc = compat_import_iovec(dir, lvec, liovcnt, UIO_FASTIOV, &iov_l, &iter);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
if (!iov_iter_count(&iter))
|
||||
goto free_iovecs;
|
||||
rc = compat_rw_copy_check_uvector(CHECK_IOVEC_ONLY, rvec, riovcnt,
|
||||
UIO_FASTIOV, iovstack_r,
|
||||
&iov_r);
|
||||
if (rc <= 0)
|
||||
goto free_iovecs;
|
||||
|
||||
rc = process_vm_rw_core(pid, &iter, iov_r, riovcnt, flags, vm_write);
|
||||
|
||||
free_iovecs:
|
||||
if (iov_r != iovstack_r)
|
||||
kfree(iov_r);
|
||||
kfree(iov_l);
|
||||
return rc;
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE6(process_vm_readv, compat_pid_t, pid,
|
||||
const struct compat_iovec __user *, lvec,
|
||||
compat_ulong_t, liovcnt,
|
||||
const struct compat_iovec __user *, rvec,
|
||||
compat_ulong_t, riovcnt,
|
||||
compat_ulong_t, flags)
|
||||
{
|
||||
return compat_process_vm_rw(pid, lvec, liovcnt, rvec,
|
||||
riovcnt, flags, 0);
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE6(process_vm_writev, compat_pid_t, pid,
|
||||
const struct compat_iovec __user *, lvec,
|
||||
compat_ulong_t, liovcnt,
|
||||
const struct compat_iovec __user *, rvec,
|
||||
compat_ulong_t, riovcnt,
|
||||
compat_ulong_t, flags)
|
||||
{
|
||||
return compat_process_vm_rw(pid, lvec, liovcnt, rvec,
|
||||
riovcnt, flags, 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -98,8 +98,8 @@ int get_compat_msghdr(struct msghdr *kmsg,
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
err = compat_import_iovec(save_addr ? READ : WRITE, compat_ptr(ptr),
|
||||
len, UIO_FASTIOV, iov, &kmsg->msg_iter);
|
||||
err = import_iovec(save_addr ? READ : WRITE, compat_ptr(ptr), len,
|
||||
UIO_FASTIOV, iov, &kmsg->msg_iter);
|
||||
return err < 0 ? err : 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,39 +11,6 @@
|
|||
#include <linux/slab.h>
|
||||
#include "internal.h"
|
||||
|
||||
/*
|
||||
* Instantiate a key with the specified compatibility multipart payload and
|
||||
* link the key into the destination keyring if one is given.
|
||||
*
|
||||
* The caller must have the appropriate instantiation permit set for this to
|
||||
* work (see keyctl_assume_authority). No other permissions are required.
|
||||
*
|
||||
* If successful, 0 will be returned.
|
||||
*/
|
||||
static long compat_keyctl_instantiate_key_iov(
|
||||
key_serial_t id,
|
||||
const struct compat_iovec __user *_payload_iov,
|
||||
unsigned ioc,
|
||||
key_serial_t ringid)
|
||||
{
|
||||
struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
|
||||
struct iov_iter from;
|
||||
long ret;
|
||||
|
||||
if (!_payload_iov)
|
||||
ioc = 0;
|
||||
|
||||
ret = compat_import_iovec(WRITE, _payload_iov, ioc,
|
||||
ARRAY_SIZE(iovstack), &iov,
|
||||
&from);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = keyctl_instantiate_key_common(id, &from, ringid);
|
||||
kfree(iov);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The key control system call, 32-bit compatibility version for 64-bit archs
|
||||
*/
|
||||
|
@ -114,8 +81,8 @@ COMPAT_SYSCALL_DEFINE5(keyctl, u32, option,
|
|||
return keyctl_reject_key(arg2, arg3, arg4, arg5);
|
||||
|
||||
case KEYCTL_INSTANTIATE_IOV:
|
||||
return compat_keyctl_instantiate_key_iov(
|
||||
arg2, compat_ptr(arg3), arg4, arg5);
|
||||
return keyctl_instantiate_key_iov(arg2, compat_ptr(arg3), arg4,
|
||||
arg5);
|
||||
|
||||
case KEYCTL_INVALIDATE:
|
||||
return keyctl_invalidate_key(arg2);
|
||||
|
|
|
@ -262,11 +262,6 @@ extern long keyctl_instantiate_key_iov(key_serial_t,
|
|||
const struct iovec __user *,
|
||||
unsigned, key_serial_t);
|
||||
extern long keyctl_invalidate_key(key_serial_t);
|
||||
|
||||
struct iov_iter;
|
||||
extern long keyctl_instantiate_key_common(key_serial_t,
|
||||
struct iov_iter *,
|
||||
key_serial_t);
|
||||
extern long keyctl_restrict_keyring(key_serial_t id,
|
||||
const char __user *_type,
|
||||
const char __user *_restriction);
|
||||
|
|
|
@ -1164,7 +1164,7 @@ static int keyctl_change_reqkey_auth(struct key *key)
|
|||
*
|
||||
* If successful, 0 will be returned.
|
||||
*/
|
||||
long keyctl_instantiate_key_common(key_serial_t id,
|
||||
static long keyctl_instantiate_key_common(key_serial_t id,
|
||||
struct iov_iter *from,
|
||||
key_serial_t ringid)
|
||||
{
|
||||
|
|
|
@ -207,9 +207,9 @@ __SYSCALL(__NR_read, sys_read)
|
|||
#define __NR_write 64
|
||||
__SYSCALL(__NR_write, sys_write)
|
||||
#define __NR_readv 65
|
||||
__SC_COMP(__NR_readv, sys_readv, compat_sys_readv)
|
||||
__SC_COMP(__NR_readv, sys_readv, sys_readv)
|
||||
#define __NR_writev 66
|
||||
__SC_COMP(__NR_writev, sys_writev, compat_sys_writev)
|
||||
__SC_COMP(__NR_writev, sys_writev, sys_writev)
|
||||
#define __NR_pread64 67
|
||||
__SC_COMP(__NR_pread64, sys_pread64, compat_sys_pread64)
|
||||
#define __NR_pwrite64 68
|
||||
|
@ -237,7 +237,7 @@ __SC_COMP(__NR_signalfd4, sys_signalfd4, compat_sys_signalfd4)
|
|||
|
||||
/* fs/splice.c */
|
||||
#define __NR_vmsplice 75
|
||||
__SC_COMP(__NR_vmsplice, sys_vmsplice, compat_sys_vmsplice)
|
||||
__SYSCALL(__NR_vmsplice, sys_vmsplice)
|
||||
#define __NR_splice 76
|
||||
__SYSCALL(__NR_splice, sys_splice)
|
||||
#define __NR_tee 77
|
||||
|
@ -727,11 +727,9 @@ __SYSCALL(__NR_setns, sys_setns)
|
|||
#define __NR_sendmmsg 269
|
||||
__SC_COMP(__NR_sendmmsg, sys_sendmmsg, compat_sys_sendmmsg)
|
||||
#define __NR_process_vm_readv 270
|
||||
__SC_COMP(__NR_process_vm_readv, sys_process_vm_readv, \
|
||||
compat_sys_process_vm_readv)
|
||||
__SYSCALL(__NR_process_vm_readv, sys_process_vm_readv)
|
||||
#define __NR_process_vm_writev 271
|
||||
__SC_COMP(__NR_process_vm_writev, sys_process_vm_writev, \
|
||||
compat_sys_process_vm_writev)
|
||||
__SYSCALL(__NR_process_vm_writev, sys_process_vm_writev)
|
||||
#define __NR_kcmp 272
|
||||
__SYSCALL(__NR_kcmp, sys_kcmp)
|
||||
#define __NR_finit_module 273
|
||||
|
|
|
@ -189,8 +189,8 @@
|
|||
142 common _newselect sys_select compat_sys_select
|
||||
143 common flock sys_flock
|
||||
144 common msync sys_msync
|
||||
145 common readv sys_readv compat_sys_readv
|
||||
146 common writev sys_writev compat_sys_writev
|
||||
145 common readv sys_readv
|
||||
146 common writev sys_writev
|
||||
147 common getsid sys_getsid
|
||||
148 common fdatasync sys_fdatasync
|
||||
149 nospu _sysctl sys_ni_syscall
|
||||
|
@ -363,7 +363,7 @@
|
|||
282 common unshare sys_unshare
|
||||
283 common splice sys_splice
|
||||
284 common tee sys_tee
|
||||
285 common vmsplice sys_vmsplice compat_sys_vmsplice
|
||||
285 common vmsplice sys_vmsplice
|
||||
286 common openat sys_openat compat_sys_openat
|
||||
287 common mkdirat sys_mkdirat
|
||||
288 common mknodat sys_mknodat
|
||||
|
@ -443,8 +443,8 @@
|
|||
348 common syncfs sys_syncfs
|
||||
349 common sendmmsg sys_sendmmsg compat_sys_sendmmsg
|
||||
350 common setns sys_setns
|
||||
351 nospu process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv
|
||||
352 nospu process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev
|
||||
351 nospu process_vm_readv sys_process_vm_readv
|
||||
352 nospu process_vm_writev sys_process_vm_writev
|
||||
353 nospu finit_module sys_finit_module
|
||||
354 nospu kcmp sys_kcmp
|
||||
355 common sched_setattr sys_sched_setattr
|
||||
|
|
|
@ -134,8 +134,8 @@
|
|||
142 64 select sys_select -
|
||||
143 common flock sys_flock sys_flock
|
||||
144 common msync sys_msync compat_sys_msync
|
||||
145 common readv sys_readv compat_sys_readv
|
||||
146 common writev sys_writev compat_sys_writev
|
||||
145 common readv sys_readv
|
||||
146 common writev sys_writev
|
||||
147 common getsid sys_getsid sys_getsid
|
||||
148 common fdatasync sys_fdatasync sys_fdatasync
|
||||
149 common _sysctl - -
|
||||
|
@ -316,7 +316,7 @@
|
|||
306 common splice sys_splice compat_sys_splice
|
||||
307 common sync_file_range sys_sync_file_range compat_sys_s390_sync_file_range
|
||||
308 common tee sys_tee compat_sys_tee
|
||||
309 common vmsplice sys_vmsplice compat_sys_vmsplice
|
||||
309 common vmsplice sys_vmsplice sys_vmsplice
|
||||
310 common move_pages sys_move_pages compat_sys_move_pages
|
||||
311 common getcpu sys_getcpu compat_sys_getcpu
|
||||
312 common epoll_pwait sys_epoll_pwait compat_sys_epoll_pwait
|
||||
|
@ -347,8 +347,8 @@
|
|||
337 common clock_adjtime sys_clock_adjtime compat_sys_clock_adjtime
|
||||
338 common syncfs sys_syncfs sys_syncfs
|
||||
339 common setns sys_setns sys_setns
|
||||
340 common process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv
|
||||
341 common process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev
|
||||
340 common process_vm_readv sys_process_vm_readv sys_process_vm_readv
|
||||
341 common process_vm_writev sys_process_vm_writev sys_process_vm_writev
|
||||
342 common s390_runtime_instr sys_s390_runtime_instr sys_s390_runtime_instr
|
||||
343 common kcmp sys_kcmp compat_sys_kcmp
|
||||
344 common finit_module sys_finit_module compat_sys_finit_module
|
||||
|
|
|
@ -371,8 +371,8 @@
|
|||
512 x32 rt_sigaction compat_sys_rt_sigaction
|
||||
513 x32 rt_sigreturn compat_sys_x32_rt_sigreturn
|
||||
514 x32 ioctl compat_sys_ioctl
|
||||
515 x32 readv compat_sys_readv
|
||||
516 x32 writev compat_sys_writev
|
||||
515 x32 readv sys_readv
|
||||
516 x32 writev sys_writev
|
||||
517 x32 recvfrom compat_sys_recvfrom
|
||||
518 x32 sendmsg compat_sys_sendmsg
|
||||
519 x32 recvmsg compat_sys_recvmsg
|
||||
|
@ -388,15 +388,15 @@
|
|||
529 x32 waitid compat_sys_waitid
|
||||
530 x32 set_robust_list compat_sys_set_robust_list
|
||||
531 x32 get_robust_list compat_sys_get_robust_list
|
||||
532 x32 vmsplice compat_sys_vmsplice
|
||||
532 x32 vmsplice sys_vmsplice
|
||||
533 x32 move_pages compat_sys_move_pages
|
||||
534 x32 preadv compat_sys_preadv64
|
||||
535 x32 pwritev compat_sys_pwritev64
|
||||
536 x32 rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo
|
||||
537 x32 recvmmsg compat_sys_recvmmsg_time64
|
||||
538 x32 sendmmsg compat_sys_sendmmsg
|
||||
539 x32 process_vm_readv compat_sys_process_vm_readv
|
||||
540 x32 process_vm_writev compat_sys_process_vm_writev
|
||||
539 x32 process_vm_readv sys_process_vm_readv
|
||||
540 x32 process_vm_writev sys_process_vm_writev
|
||||
541 x32 setsockopt sys_setsockopt
|
||||
542 x32 getsockopt sys_getsockopt
|
||||
543 x32 io_setup compat_sys_io_setup
|
||||
|
|
Loading…
Reference in New Issue