History

aio/vfs: cleanup of rw_copy_check_uvector() and compat_rw_copy_check_uvector()

A cleanup of rw_copy_check_uvector and compat_rw_copy_check_uvector after changes made to support CMA in an earlier patch. Rather than having an additional check_access parameter to these functions, the first paramater type is overloaded to allow the caller to specify CHECK_IOVEC_ONLY which means check that the contents of the iovec are valid, but do not check the memory that they point to. This is used by process_vm_readv/writev where we need to validate that a iovec passed to the syscall is valid but do not want to check the memory that it points to at this point because it refers to an address space in another process.

Christopher Yeoh committed 14 years ago

Commit ac34ebb1 parent ee62c6b8 files · +29 −23Browse files

Unified · Split

8 files
  1. fs/aio.c +2 −2
  2. fs/compat.c +3 −3
  3. fs/read_write.c +3 −4
  4. include/linux/compat.h +1 −2
  5. include/linux/fs.h +10 −2
  6. mm/process_vm_access.c +8 −8
  7. security/keys/compat.c +1 −1
  8. security/keys/keyctl.c +1 −1
fs/aio.c+2−2
@@ -1446,13 +1446,13 @@ static ssize_t aio_setup_vectored_rw(int type, struct kiocb *kiocb, bool compat) · 1445 unmodified lines
1446 ret = compat_rw_copy_check_uvector(type,1446 ret = compat_rw_copy_check_uvector(type,
1447 (struct compat_iovec __user *)kiocb->ki_buf,1447 (struct compat_iovec __user *)kiocb->ki_buf,
1448 kiocb->ki_nbytes, 1, &kiocb->ki_inline_vec,1448 kiocb->ki_nbytes, 1, &kiocb->ki_inline_vec,
1449 &kiocb->ki_iovec, 1);1449 &kiocb->ki_iovec);
1450 else1450 else
1451#endif1451#endif
1452 ret = rw_copy_check_uvector(type,1452 ret = rw_copy_check_uvector(type,
1453 (struct iovec __user *)kiocb->ki_buf,1453 (struct iovec __user *)kiocb->ki_buf,
1454 kiocb->ki_nbytes, 1, &kiocb->ki_inline_vec,1454 kiocb->ki_nbytes, 1, &kiocb->ki_inline_vec,
1455 &kiocb->ki_iovec, 1);1455 &kiocb->ki_iovec);
1456 if (ret < 0)1456 if (ret < 0)
1457 goto out;1457 goto out;
1458 1458
fs/compat.c+3−3
@@ -532,7 +532,7 @@ out: · 531 unmodified lines
532ssize_t compat_rw_copy_check_uvector(int type,532ssize_t compat_rw_copy_check_uvector(int type,
533 const struct compat_iovec __user *uvector, unsigned long nr_segs,533 const struct compat_iovec __user *uvector, unsigned long nr_segs,
534 unsigned long fast_segs, struct iovec *fast_pointer,534 unsigned long fast_segs, struct iovec *fast_pointer,
535 struct iovec **ret_pointer, int check_access)535 struct iovec **ret_pointer)
536{536{
537 compat_ssize_t tot_len;537 compat_ssize_t tot_len;
538 struct iovec *iov = *ret_pointer = fast_pointer;538 struct iovec *iov = *ret_pointer = fast_pointer;
@@ -579,7 +579,7 @@ ssize_t compat_rw_copy_check_uvector(int type, · 40 unmodified lines
579 }579 }
580 if (len < 0) /* size_t not fitting in compat_ssize_t .. */580 if (len < 0) /* size_t not fitting in compat_ssize_t .. */
581 goto out;581 goto out;
582 if (check_access &&582 if (type >= 0 &&
583 !access_ok(vrfy_dir(type), compat_ptr(buf), len)) {583 !access_ok(vrfy_dir(type), compat_ptr(buf), len)) {
584 ret = -EFAULT;584 ret = -EFAULT;
585 goto out;585 goto out;
@@ -1094,7 +1094,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, · 508 unmodified lines
1094 goto out;1094 goto out;
1095 1095
1096 tot_len = compat_rw_copy_check_uvector(type, uvector, nr_segs,1096 tot_len = compat_rw_copy_check_uvector(type, uvector, nr_segs,
1097 UIO_FASTIOV, iovstack, &iov, 1);1097 UIO_FASTIOV, iovstack, &iov);
1098 if (tot_len == 0) {1098 if (tot_len == 0) {
1099 ret = 0;1099 ret = 0;
1100 goto out;1100 goto out;
fs/read_write.c+3−4
@@ -633,8 +633,7 @@ ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, · 632 unmodified lines
633ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,633ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
634 unsigned long nr_segs, unsigned long fast_segs,634 unsigned long nr_segs, unsigned long fast_segs,
635 struct iovec *fast_pointer,635 struct iovec *fast_pointer,
636 struct iovec **ret_pointer,636 struct iovec **ret_pointer)
637 int check_access)
638{637{
639 unsigned long seg;638 unsigned long seg;
640 ssize_t ret;639 ssize_t ret;
@@ -690,7 +689,7 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, · 49 unmodified lines
690 ret = -EINVAL;689 ret = -EINVAL;
691 goto out;690 goto out;
692 }691 }
693 if (check_access692 if (type >= 0
694 && unlikely(!access_ok(vrfy_dir(type), buf, len))) {693 && unlikely(!access_ok(vrfy_dir(type), buf, len))) {
695 ret = -EFAULT;694 ret = -EFAULT;
696 goto out;695 goto out;
@@ -723,7 +722,7 @@ static ssize_t do_readv_writev(int type, struct file *file, · 26 unmodified lines
723 }722 }
724 723
725 ret = rw_copy_check_uvector(type, uvector, nr_segs,724 ret = rw_copy_check_uvector(type, uvector, nr_segs,
726 ARRAY_SIZE(iovstack), iovstack, &iov, 1);725 ARRAY_SIZE(iovstack), iovstack, &iov);
727 if (ret <= 0)726 if (ret <= 0)
728 goto out;727 goto out;
729 728
include/linux/compat.h+1−2
@@ -577,8 +577,7 @@ extern ssize_t compat_rw_copy_check_uvector(int type, · 576 unmodified lines
577 const struct compat_iovec __user *uvector,577 const struct compat_iovec __user *uvector,
578 unsigned long nr_segs,578 unsigned long nr_segs,
579 unsigned long fast_segs, struct iovec *fast_pointer,579 unsigned long fast_segs, struct iovec *fast_pointer,
580 struct iovec **ret_pointer,580 struct iovec **ret_pointer);
581 int check_access);
582 581
583extern void __user *compat_alloc_user_space(unsigned long len);582extern void __user *compat_alloc_user_space(unsigned long len);
584 583
include/linux/fs.h+10−2
@@ -173,6 +173,15 @@ struct inodes_stat_t { · 172 unmodified lines
173#define WRITE_FUA (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_FUA)173#define WRITE_FUA (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_FUA)
174#define WRITE_FLUSH_FUA (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_FLUSH | REQ_FUA)174#define WRITE_FLUSH_FUA (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_FLUSH | REQ_FUA)
175 175
176
177/*
178 * Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector
179 * that indicates that they should check the contents of the iovec are
180 * valid, but not check the memory that the iovec elements
181 * points too.
182 */
183#define CHECK_IOVEC_ONLY -1
184
176#define SEL_IN 1185#define SEL_IN 1
177#define SEL_OUT 2186#define SEL_OUT 2
178#define SEL_EX 4187#define SEL_EX 4
@@ -1690,8 +1699,7 @@ struct seq_file; · 1511 unmodified lines
1690ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,1699ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
1691 unsigned long nr_segs, unsigned long fast_segs,1700 unsigned long nr_segs, unsigned long fast_segs,
1692 struct iovec *fast_pointer,1701 struct iovec *fast_pointer,
1693 struct iovec **ret_pointer,1702 struct iovec **ret_pointer);
1694 int check_access);
1695 1703
1696extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *);1704extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *);
1697extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *);1705extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *);
mm/process_vm_access.c+8−8
@@ -371,15 +371,15 @@ static ssize_t process_vm_rw(pid_t pid, · 370 unmodified lines
371 /* Check iovecs */371 /* Check iovecs */
372 if (vm_write)372 if (vm_write)
373 rc = rw_copy_check_uvector(WRITE, lvec, liovcnt, UIO_FASTIOV,373 rc = rw_copy_check_uvector(WRITE, lvec, liovcnt, UIO_FASTIOV,
374 iovstack_l, &iov_l, 1);374 iovstack_l, &iov_l);
375 else375 else
376 rc = rw_copy_check_uvector(READ, lvec, liovcnt, UIO_FASTIOV,376 rc = rw_copy_check_uvector(READ, lvec, liovcnt, UIO_FASTIOV,
377 iovstack_l, &iov_l, 1);377 iovstack_l, &iov_l);
378 if (rc <= 0)378 if (rc <= 0)
379 goto free_iovecs;379 goto free_iovecs;
380 380
381 rc = rw_copy_check_uvector(READ, rvec, riovcnt, UIO_FASTIOV,381 rc = rw_copy_check_uvector(CHECK_IOVEC_ONLY, rvec, riovcnt, UIO_FASTIOV,
382 iovstack_r, &iov_r, 0);382 iovstack_r, &iov_r);
383 if (rc <= 0)383 if (rc <= 0)
384 goto free_iovecs;384 goto free_iovecs;
385 385
@@ -438,16 +438,16 @@ compat_process_vm_rw(compat_pid_t pid, · 52 unmodified lines
438 if (vm_write)438 if (vm_write)
439 rc = compat_rw_copy_check_uvector(WRITE, lvec, liovcnt,439 rc = compat_rw_copy_check_uvector(WRITE, lvec, liovcnt,
440 UIO_FASTIOV, iovstack_l,440 UIO_FASTIOV, iovstack_l,
441 &iov_l, 1);441 &iov_l);
442 else442 else
443 rc = compat_rw_copy_check_uvector(READ, lvec, liovcnt,443 rc = compat_rw_copy_check_uvector(READ, lvec, liovcnt,
444 UIO_FASTIOV, iovstack_l,444 UIO_FASTIOV, iovstack_l,
445 &iov_l, 1);445 &iov_l);
446 if (rc <= 0)446 if (rc <= 0)
447 goto free_iovecs;447 goto free_iovecs;
448 rc = compat_rw_copy_check_uvector(READ, rvec, riovcnt,448 rc = compat_rw_copy_check_uvector(CHECK_IOVEC_ONLY, rvec, riovcnt,
449 UIO_FASTIOV, iovstack_r,449 UIO_FASTIOV, iovstack_r,
450 &iov_r, 0);450 &iov_r);
451 if (rc <= 0)451 if (rc <= 0)
452 goto free_iovecs;452 goto free_iovecs;
453 453
security/keys/compat.c+1−1
@@ -38,7 +38,7 @@ long compat_keyctl_instantiate_key_iov( · 37 unmodified lines
38 38
39 ret = compat_rw_copy_check_uvector(WRITE, _payload_iov, ioc,39 ret = compat_rw_copy_check_uvector(WRITE, _payload_iov, ioc,
40 ARRAY_SIZE(iovstack),40 ARRAY_SIZE(iovstack),
41 iovstack, &iov, 1);41 iovstack, &iov);
42 if (ret < 0)42 if (ret < 0)
43 return ret;43 return ret;
44 if (ret == 0)44 if (ret == 0)
security/keys/keyctl.c+1−1
@@ -1110,7 +1110,7 @@ long keyctl_instantiate_key_iov(key_serial_t id, · 1109 unmodified lines
1110 goto no_payload;1110 goto no_payload;
1111 1111
1112 ret = rw_copy_check_uvector(WRITE, _payload_iov, ioc,1112 ret = rw_copy_check_uvector(WRITE, _payload_iov, ioc,
1113 ARRAY_SIZE(iovstack), iovstack, &iov, 1);1113 ARRAY_SIZE(iovstack), iovstack, &iov);
1114 if (ret < 0)1114 if (ret < 0)
1115 return ret;1115 return ret;
1116 if (ret == 0)1116 if (ret == 0)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t