untangling process_vm_..., part 1
[pandora-kernel.git] / mm / process_vm_access.c
1 /*
2  * linux/mm/process_vm_access.c
3  *
4  * Copyright (C) 2010-2011 Christopher Yeoh <cyeoh@au1.ibm.com>, IBM Corp.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  */
11
12 #include <linux/mm.h>
13 #include <linux/uio.h>
14 #include <linux/sched.h>
15 #include <linux/highmem.h>
16 #include <linux/ptrace.h>
17 #include <linux/slab.h>
18 #include <linux/syscalls.h>
19
20 #ifdef CONFIG_COMPAT
21 #include <linux/compat.h>
22 #endif
23
24 /**
25  * process_vm_rw_pages - read/write pages from task specified
26  * @task: task to read/write from
27  * @mm: mm for task
28  * @process_pages: struct pages area that can store at least
29  *  nr_pages_to_copy struct page pointers
30  * @pa: address of page in task to start copying from/to
31  * @start_offset: offset in page to start copying from/to
32  * @len: number of bytes to copy
33  * @lvec: iovec array specifying where to copy to/from
34  * @lvec_cnt: number of elements in iovec array
35  * @lvec_current: index in iovec array we are up to
36  * @lvec_offset: offset in bytes from current iovec iov_base we are up to
37  * @vm_write: 0 means copy from, 1 means copy to
38  * @nr_pages_to_copy: number of pages to copy
39  * @bytes_copied: returns number of bytes successfully copied
40  * Returns 0 on success, error code otherwise
41  */
42 static int process_vm_rw_pages(struct task_struct *task,
43                                struct mm_struct *mm,
44                                struct page **process_pages,
45                                unsigned long pa,
46                                unsigned long start_offset,
47                                unsigned long len,
48                                const struct iovec *lvec,
49                                unsigned long lvec_cnt,
50                                unsigned long *lvec_current,
51                                size_t *lvec_offset,
52                                int vm_write,
53                                unsigned int nr_pages_to_copy,
54                                ssize_t *bytes_copied)
55 {
56         int pages_pinned;
57         void *target_kaddr;
58         int pgs_copied = 0;
59         int j;
60         int ret;
61         ssize_t bytes_to_copy;
62         ssize_t rc = 0;
63         const struct iovec *iov = lvec + *lvec_current;
64
65         *bytes_copied = 0;
66
67         /* Get the pages we're interested in */
68         down_read(&mm->mmap_sem);
69         pages_pinned = get_user_pages(task, mm, pa,
70                                       nr_pages_to_copy,
71                                       vm_write, 0, process_pages, NULL);
72         up_read(&mm->mmap_sem);
73
74         if (pages_pinned != nr_pages_to_copy) {
75                 rc = -EFAULT;
76                 goto end;
77         }
78
79         /* Do the copy for each page */
80         for (pgs_copied = 0;
81              (pgs_copied < nr_pages_to_copy) && (*lvec_current < lvec_cnt);
82              pgs_copied++) {
83                 /* Make sure we have a non zero length iovec */
84                 while (*lvec_current < lvec_cnt
85                        && iov->iov_len == 0) {
86                         iov++;
87                         (*lvec_current)++;
88                 }
89                 if (*lvec_current == lvec_cnt)
90                         break;
91
92                 /*
93                  * Will copy smallest of:
94                  * - bytes remaining in page
95                  * - bytes remaining in destination iovec
96                  */
97                 bytes_to_copy = min_t(ssize_t, PAGE_SIZE - start_offset,
98                                       len - *bytes_copied);
99                 bytes_to_copy = min_t(ssize_t, bytes_to_copy,
100                                       iov->iov_len
101                                       - *lvec_offset);
102
103                 target_kaddr = kmap(process_pages[pgs_copied]) + start_offset;
104
105                 if (vm_write)
106                         ret = copy_from_user(target_kaddr,
107                                              iov->iov_base
108                                              + *lvec_offset,
109                                              bytes_to_copy);
110                 else
111                         ret = copy_to_user(iov->iov_base
112                                            + *lvec_offset,
113                                            target_kaddr, bytes_to_copy);
114                 kunmap(process_pages[pgs_copied]);
115                 if (ret) {
116                         *bytes_copied += bytes_to_copy - ret;
117                         pgs_copied++;
118                         rc = -EFAULT;
119                         goto end;
120                 }
121                 *bytes_copied += bytes_to_copy;
122                 *lvec_offset += bytes_to_copy;
123                 if (*lvec_offset == iov->iov_len) {
124                         /*
125                          * Need to copy remaining part of page into the
126                          * next iovec if there are any bytes left in page
127                          */
128                         (*lvec_current)++;
129                         iov++;
130                         *lvec_offset = 0;
131                         start_offset = (start_offset + bytes_to_copy)
132                                 % PAGE_SIZE;
133                         if (start_offset)
134                                 pgs_copied--;
135                 } else {
136                         start_offset = 0;
137                 }
138         }
139
140 end:
141         if (vm_write) {
142                 for (j = 0; j < pages_pinned; j++) {
143                         if (j < pgs_copied)
144                                 set_page_dirty_lock(process_pages[j]);
145                         put_page(process_pages[j]);
146                 }
147         } else {
148                 for (j = 0; j < pages_pinned; j++)
149                         put_page(process_pages[j]);
150         }
151
152         return rc;
153 }
154
155 /* Maximum number of pages kmalloc'd to hold struct page's during copy */
156 #define PVM_MAX_KMALLOC_PAGES (PAGE_SIZE * 2)
157
158 /**
159  * process_vm_rw_single_vec - read/write pages from task specified
160  * @addr: start memory address of target process
161  * @len: size of area to copy to/from
162  * @lvec: iovec array specifying where to copy to/from locally
163  * @lvec_cnt: number of elements in iovec array
164  * @lvec_current: index in iovec array we are up to
165  * @lvec_offset: offset in bytes from current iovec iov_base we are up to
166  * @process_pages: struct pages area that can store at least
167  *  nr_pages_to_copy struct page pointers
168  * @mm: mm for task
169  * @task: task to read/write from
170  * @vm_write: 0 means copy from, 1 means copy to
171  * @bytes_copied: returns number of bytes successfully copied
172  * Returns 0 on success or on failure error code
173  */
174 static int process_vm_rw_single_vec(unsigned long addr,
175                                     unsigned long len,
176                                     const struct iovec *lvec,
177                                     unsigned long lvec_cnt,
178                                     unsigned long *lvec_current,
179                                     size_t *lvec_offset,
180                                     struct page **process_pages,
181                                     struct mm_struct *mm,
182                                     struct task_struct *task,
183                                     int vm_write,
184                                     ssize_t *bytes_copied)
185 {
186         unsigned long pa = addr & PAGE_MASK;
187         unsigned long start_offset = addr - pa;
188         unsigned long nr_pages;
189         ssize_t bytes_copied_loop;
190         ssize_t rc = 0;
191         unsigned long nr_pages_copied = 0;
192         unsigned long nr_pages_to_copy;
193         unsigned long max_pages_per_loop = PVM_MAX_KMALLOC_PAGES
194                 / sizeof(struct pages *);
195
196         *bytes_copied = 0;
197
198         /* Work out address and page range required */
199         if (len == 0)
200                 return 0;
201         nr_pages = (addr + len - 1) / PAGE_SIZE - addr / PAGE_SIZE + 1;
202
203         while ((nr_pages_copied < nr_pages) && (*lvec_current < lvec_cnt)) {
204                 nr_pages_to_copy = min(nr_pages - nr_pages_copied,
205                                        max_pages_per_loop);
206
207                 rc = process_vm_rw_pages(task, mm, process_pages, pa,
208                                          start_offset, len,
209                                          lvec, lvec_cnt,
210                                          lvec_current, lvec_offset,
211                                          vm_write, nr_pages_to_copy,
212                                          &bytes_copied_loop);
213                 start_offset = 0;
214                 *bytes_copied += bytes_copied_loop;
215
216                 if (rc < 0) {
217                         return rc;
218                 } else {
219                         len -= bytes_copied_loop;
220                         nr_pages_copied += nr_pages_to_copy;
221                         pa += nr_pages_to_copy * PAGE_SIZE;
222                 }
223         }
224
225         return rc;
226 }
227
228 /* Maximum number of entries for process pages array
229    which lives on stack */
230 #define PVM_MAX_PP_ARRAY_COUNT 16
231
232 /**
233  * process_vm_rw_core - core of reading/writing pages from task specified
234  * @pid: PID of process to read/write from/to
235  * @lvec: iovec array specifying where to copy to/from locally
236  * @liovcnt: size of lvec array
237  * @rvec: iovec array specifying where to copy to/from in the other process
238  * @riovcnt: size of rvec array
239  * @flags: currently unused
240  * @vm_write: 0 if reading from other process, 1 if writing to other process
241  * Returns the number of bytes read/written or error code. May
242  *  return less bytes than expected if an error occurs during the copying
243  *  process.
244  */
245 static ssize_t process_vm_rw_core(pid_t pid, const struct iovec *lvec,
246                                   unsigned long liovcnt,
247                                   const struct iovec *rvec,
248                                   unsigned long riovcnt,
249                                   unsigned long flags, int vm_write)
250 {
251         struct task_struct *task;
252         struct page *pp_stack[PVM_MAX_PP_ARRAY_COUNT];
253         struct page **process_pages = pp_stack;
254         struct mm_struct *mm;
255         unsigned long i;
256         ssize_t rc = 0;
257         ssize_t bytes_copied_loop;
258         ssize_t bytes_copied = 0;
259         unsigned long nr_pages = 0;
260         unsigned long nr_pages_iov;
261         unsigned long iov_l_curr_idx = 0;
262         size_t iov_l_curr_offset = 0;
263         ssize_t iov_len;
264
265         /*
266          * Work out how many pages of struct pages we're going to need
267          * when eventually calling get_user_pages
268          */
269         for (i = 0; i < riovcnt; i++) {
270                 iov_len = rvec[i].iov_len;
271                 if (iov_len > 0) {
272                         nr_pages_iov = ((unsigned long)rvec[i].iov_base
273                                         + iov_len)
274                                 / PAGE_SIZE - (unsigned long)rvec[i].iov_base
275                                 / PAGE_SIZE + 1;
276                         nr_pages = max(nr_pages, nr_pages_iov);
277                 }
278         }
279
280         if (nr_pages == 0)
281                 return 0;
282
283         if (nr_pages > PVM_MAX_PP_ARRAY_COUNT) {
284                 /* For reliability don't try to kmalloc more than
285                    2 pages worth */
286                 process_pages = kmalloc(min_t(size_t, PVM_MAX_KMALLOC_PAGES,
287                                               sizeof(struct pages *)*nr_pages),
288                                         GFP_KERNEL);
289
290                 if (!process_pages)
291                         return -ENOMEM;
292         }
293
294         /* Get process information */
295         rcu_read_lock();
296         task = find_task_by_vpid(pid);
297         if (task)
298                 get_task_struct(task);
299         rcu_read_unlock();
300         if (!task) {
301                 rc = -ESRCH;
302                 goto free_proc_pages;
303         }
304
305         mm = mm_access(task, PTRACE_MODE_ATTACH);
306         if (!mm || IS_ERR(mm)) {
307                 rc = IS_ERR(mm) ? PTR_ERR(mm) : -ESRCH;
308                 /*
309                  * Explicitly map EACCES to EPERM as EPERM is a more a
310                  * appropriate error code for process_vw_readv/writev
311                  */
312                 if (rc == -EACCES)
313                         rc = -EPERM;
314                 goto put_task_struct;
315         }
316
317         for (i = 0; i < riovcnt && iov_l_curr_idx < liovcnt; i++) {
318                 rc = process_vm_rw_single_vec(
319                         (unsigned long)rvec[i].iov_base, rvec[i].iov_len,
320                         lvec, liovcnt, &iov_l_curr_idx, &iov_l_curr_offset,
321                         process_pages, mm, task, vm_write, &bytes_copied_loop);
322                 bytes_copied += bytes_copied_loop;
323                 if (rc != 0) {
324                         /* If we have managed to copy any data at all then
325                            we return the number of bytes copied. Otherwise
326                            we return the error code */
327                         if (bytes_copied)
328                                 rc = bytes_copied;
329                         goto put_mm;
330                 }
331         }
332
333         rc = bytes_copied;
334 put_mm:
335         mmput(mm);
336
337 put_task_struct:
338         put_task_struct(task);
339
340 free_proc_pages:
341         if (process_pages != pp_stack)
342                 kfree(process_pages);
343         return rc;
344 }
345
346 /**
347  * process_vm_rw - check iovecs before calling core routine
348  * @pid: PID of process to read/write from/to
349  * @lvec: iovec array specifying where to copy to/from locally
350  * @liovcnt: size of lvec array
351  * @rvec: iovec array specifying where to copy to/from in the other process
352  * @riovcnt: size of rvec array
353  * @flags: currently unused
354  * @vm_write: 0 if reading from other process, 1 if writing to other process
355  * Returns the number of bytes read/written or error code. May
356  *  return less bytes than expected if an error occurs during the copying
357  *  process.
358  */
359 static ssize_t process_vm_rw(pid_t pid,
360                              const struct iovec __user *lvec,
361                              unsigned long liovcnt,
362                              const struct iovec __user *rvec,
363                              unsigned long riovcnt,
364                              unsigned long flags, int vm_write)
365 {
366         struct iovec iovstack_l[UIO_FASTIOV];
367         struct iovec iovstack_r[UIO_FASTIOV];
368         struct iovec *iov_l = iovstack_l;
369         struct iovec *iov_r = iovstack_r;
370         ssize_t rc;
371
372         if (flags != 0)
373                 return -EINVAL;
374
375         /* Check iovecs */
376         if (vm_write)
377                 rc = rw_copy_check_uvector(WRITE, lvec, liovcnt, UIO_FASTIOV,
378                                            iovstack_l, &iov_l);
379         else
380                 rc = rw_copy_check_uvector(READ, lvec, liovcnt, UIO_FASTIOV,
381                                            iovstack_l, &iov_l);
382         if (rc <= 0)
383                 goto free_iovecs;
384
385         rc = rw_copy_check_uvector(CHECK_IOVEC_ONLY, rvec, riovcnt, UIO_FASTIOV,
386                                    iovstack_r, &iov_r);
387         if (rc <= 0)
388                 goto free_iovecs;
389
390         rc = process_vm_rw_core(pid, iov_l, liovcnt, iov_r, riovcnt, flags,
391                                 vm_write);
392
393 free_iovecs:
394         if (iov_r != iovstack_r)
395                 kfree(iov_r);
396         if (iov_l != iovstack_l)
397                 kfree(iov_l);
398
399         return rc;
400 }
401
402 SYSCALL_DEFINE6(process_vm_readv, pid_t, pid, const struct iovec __user *, lvec,
403                 unsigned long, liovcnt, const struct iovec __user *, rvec,
404                 unsigned long, riovcnt, unsigned long, flags)
405 {
406         return process_vm_rw(pid, lvec, liovcnt, rvec, riovcnt, flags, 0);
407 }
408
409 SYSCALL_DEFINE6(process_vm_writev, pid_t, pid,
410                 const struct iovec __user *, lvec,
411                 unsigned long, liovcnt, const struct iovec __user *, rvec,
412                 unsigned long, riovcnt, unsigned long, flags)
413 {
414         return process_vm_rw(pid, lvec, liovcnt, rvec, riovcnt, flags, 1);
415 }
416
417 #ifdef CONFIG_COMPAT
418
419 asmlinkage ssize_t
420 compat_process_vm_rw(compat_pid_t pid,
421                      const struct compat_iovec __user *lvec,
422                      unsigned long liovcnt,
423                      const struct compat_iovec __user *rvec,
424                      unsigned long riovcnt,
425                      unsigned long flags, int vm_write)
426 {
427         struct iovec iovstack_l[UIO_FASTIOV];
428         struct iovec iovstack_r[UIO_FASTIOV];
429         struct iovec *iov_l = iovstack_l;
430         struct iovec *iov_r = iovstack_r;
431         ssize_t rc = -EFAULT;
432
433         if (flags != 0)
434                 return -EINVAL;
435
436         if (vm_write)
437                 rc = compat_rw_copy_check_uvector(WRITE, lvec, liovcnt,
438                                                   UIO_FASTIOV, iovstack_l,
439                                                   &iov_l);
440         else
441                 rc = compat_rw_copy_check_uvector(READ, lvec, liovcnt,
442                                                   UIO_FASTIOV, iovstack_l,
443                                                   &iov_l);
444         if (rc <= 0)
445                 goto free_iovecs;
446         rc = compat_rw_copy_check_uvector(CHECK_IOVEC_ONLY, rvec, riovcnt,
447                                           UIO_FASTIOV, iovstack_r,
448                                           &iov_r);
449         if (rc <= 0)
450                 goto free_iovecs;
451
452         rc = process_vm_rw_core(pid, iov_l, liovcnt, iov_r, riovcnt, flags,
453                            vm_write);
454
455 free_iovecs:
456         if (iov_r != iovstack_r)
457                 kfree(iov_r);
458         if (iov_l != iovstack_l)
459                 kfree(iov_l);
460         return rc;
461 }
462
463 asmlinkage ssize_t
464 compat_sys_process_vm_readv(compat_pid_t pid,
465                             const struct compat_iovec __user *lvec,
466                             unsigned long liovcnt,
467                             const struct compat_iovec __user *rvec,
468                             unsigned long riovcnt,
469                             unsigned long flags)
470 {
471         return compat_process_vm_rw(pid, lvec, liovcnt, rvec,
472                                     riovcnt, flags, 0);
473 }
474
475 asmlinkage ssize_t
476 compat_sys_process_vm_writev(compat_pid_t pid,
477                              const struct compat_iovec __user *lvec,
478                              unsigned long liovcnt,
479                              const struct compat_iovec __user *rvec,
480                              unsigned long riovcnt,
481                              unsigned long flags)
482 {
483         return compat_process_vm_rw(pid, lvec, liovcnt, rvec,
484                                     riovcnt, flags, 1);
485 }
486
487 #endif