xref: /OK3568_Linux_fs/kernel/mm/process_vm_access.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * linux/mm/process_vm_access.c
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2010-2011 Christopher Yeoh <cyeoh@au1.ibm.com>, IBM Corp.
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <linux/compat.h>
9*4882a593Smuzhiyun #include <linux/mm.h>
10*4882a593Smuzhiyun #include <linux/uio.h>
11*4882a593Smuzhiyun #include <linux/sched.h>
12*4882a593Smuzhiyun #include <linux/compat.h>
13*4882a593Smuzhiyun #include <linux/sched/mm.h>
14*4882a593Smuzhiyun #include <linux/highmem.h>
15*4882a593Smuzhiyun #include <linux/ptrace.h>
16*4882a593Smuzhiyun #include <linux/slab.h>
17*4882a593Smuzhiyun #include <linux/syscalls.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun /**
20*4882a593Smuzhiyun  * process_vm_rw_pages - read/write pages from task specified
21*4882a593Smuzhiyun  * @pages: array of pointers to pages we want to copy
22*4882a593Smuzhiyun  * @offset: offset in page to start copying from/to
23*4882a593Smuzhiyun  * @len: number of bytes to copy
24*4882a593Smuzhiyun  * @iter: where to copy to/from locally
25*4882a593Smuzhiyun  * @vm_write: 0 means copy from, 1 means copy to
26*4882a593Smuzhiyun  * Returns 0 on success, error code otherwise
27*4882a593Smuzhiyun  */
process_vm_rw_pages(struct page ** pages,unsigned offset,size_t len,struct iov_iter * iter,int vm_write)28*4882a593Smuzhiyun static int process_vm_rw_pages(struct page **pages,
29*4882a593Smuzhiyun 			       unsigned offset,
30*4882a593Smuzhiyun 			       size_t len,
31*4882a593Smuzhiyun 			       struct iov_iter *iter,
32*4882a593Smuzhiyun 			       int vm_write)
33*4882a593Smuzhiyun {
34*4882a593Smuzhiyun 	/* Do the copy for each page */
35*4882a593Smuzhiyun 	while (len && iov_iter_count(iter)) {
36*4882a593Smuzhiyun 		struct page *page = *pages++;
37*4882a593Smuzhiyun 		size_t copy = PAGE_SIZE - offset;
38*4882a593Smuzhiyun 		size_t copied;
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun 		if (copy > len)
41*4882a593Smuzhiyun 			copy = len;
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 		if (vm_write)
44*4882a593Smuzhiyun 			copied = copy_page_from_iter(page, offset, copy, iter);
45*4882a593Smuzhiyun 		else
46*4882a593Smuzhiyun 			copied = copy_page_to_iter(page, offset, copy, iter);
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun 		len -= copied;
49*4882a593Smuzhiyun 		if (copied < copy && iov_iter_count(iter))
50*4882a593Smuzhiyun 			return -EFAULT;
51*4882a593Smuzhiyun 		offset = 0;
52*4882a593Smuzhiyun 	}
53*4882a593Smuzhiyun 	return 0;
54*4882a593Smuzhiyun }
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun /* Maximum number of pages kmalloc'd to hold struct page's during copy */
57*4882a593Smuzhiyun #define PVM_MAX_KMALLOC_PAGES (PAGE_SIZE * 2)
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun /**
60*4882a593Smuzhiyun  * process_vm_rw_single_vec - read/write pages from task specified
61*4882a593Smuzhiyun  * @addr: start memory address of target process
62*4882a593Smuzhiyun  * @len: size of area to copy to/from
63*4882a593Smuzhiyun  * @iter: where to copy to/from locally
64*4882a593Smuzhiyun  * @process_pages: struct pages area that can store at least
65*4882a593Smuzhiyun  *  nr_pages_to_copy struct page pointers
66*4882a593Smuzhiyun  * @mm: mm for task
67*4882a593Smuzhiyun  * @task: task to read/write from
68*4882a593Smuzhiyun  * @vm_write: 0 means copy from, 1 means copy to
69*4882a593Smuzhiyun  * Returns 0 on success or on failure error code
70*4882a593Smuzhiyun  */
process_vm_rw_single_vec(unsigned long addr,unsigned long len,struct iov_iter * iter,struct page ** process_pages,struct mm_struct * mm,struct task_struct * task,int vm_write)71*4882a593Smuzhiyun static int process_vm_rw_single_vec(unsigned long addr,
72*4882a593Smuzhiyun 				    unsigned long len,
73*4882a593Smuzhiyun 				    struct iov_iter *iter,
74*4882a593Smuzhiyun 				    struct page **process_pages,
75*4882a593Smuzhiyun 				    struct mm_struct *mm,
76*4882a593Smuzhiyun 				    struct task_struct *task,
77*4882a593Smuzhiyun 				    int vm_write)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun 	unsigned long pa = addr & PAGE_MASK;
80*4882a593Smuzhiyun 	unsigned long start_offset = addr - pa;
81*4882a593Smuzhiyun 	unsigned long nr_pages;
82*4882a593Smuzhiyun 	ssize_t rc = 0;
83*4882a593Smuzhiyun 	unsigned long max_pages_per_loop = PVM_MAX_KMALLOC_PAGES
84*4882a593Smuzhiyun 		/ sizeof(struct pages *);
85*4882a593Smuzhiyun 	unsigned int flags = 0;
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	/* Work out address and page range required */
88*4882a593Smuzhiyun 	if (len == 0)
89*4882a593Smuzhiyun 		return 0;
90*4882a593Smuzhiyun 	nr_pages = (addr + len - 1) / PAGE_SIZE - addr / PAGE_SIZE + 1;
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 	if (vm_write)
93*4882a593Smuzhiyun 		flags |= FOLL_WRITE;
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 	while (!rc && nr_pages && iov_iter_count(iter)) {
96*4882a593Smuzhiyun 		int pinned_pages = min(nr_pages, max_pages_per_loop);
97*4882a593Smuzhiyun 		int locked = 1;
98*4882a593Smuzhiyun 		size_t bytes;
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 		/*
101*4882a593Smuzhiyun 		 * Get the pages we're interested in.  We must
102*4882a593Smuzhiyun 		 * access remotely because task/mm might not
103*4882a593Smuzhiyun 		 * current/current->mm
104*4882a593Smuzhiyun 		 */
105*4882a593Smuzhiyun 		mmap_read_lock(mm);
106*4882a593Smuzhiyun 		pinned_pages = pin_user_pages_remote(mm, pa, pinned_pages,
107*4882a593Smuzhiyun 						     flags, process_pages,
108*4882a593Smuzhiyun 						     NULL, &locked);
109*4882a593Smuzhiyun 		if (locked)
110*4882a593Smuzhiyun 			mmap_read_unlock(mm);
111*4882a593Smuzhiyun 		if (pinned_pages <= 0)
112*4882a593Smuzhiyun 			return -EFAULT;
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 		bytes = pinned_pages * PAGE_SIZE - start_offset;
115*4882a593Smuzhiyun 		if (bytes > len)
116*4882a593Smuzhiyun 			bytes = len;
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 		rc = process_vm_rw_pages(process_pages,
119*4882a593Smuzhiyun 					 start_offset, bytes, iter,
120*4882a593Smuzhiyun 					 vm_write);
121*4882a593Smuzhiyun 		len -= bytes;
122*4882a593Smuzhiyun 		start_offset = 0;
123*4882a593Smuzhiyun 		nr_pages -= pinned_pages;
124*4882a593Smuzhiyun 		pa += pinned_pages * PAGE_SIZE;
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 		/* If vm_write is set, the pages need to be made dirty: */
127*4882a593Smuzhiyun 		unpin_user_pages_dirty_lock(process_pages, pinned_pages,
128*4882a593Smuzhiyun 					    vm_write);
129*4882a593Smuzhiyun 	}
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	return rc;
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun /* Maximum number of entries for process pages array
135*4882a593Smuzhiyun    which lives on stack */
136*4882a593Smuzhiyun #define PVM_MAX_PP_ARRAY_COUNT 16
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun /**
139*4882a593Smuzhiyun  * process_vm_rw_core - core of reading/writing pages from task specified
140*4882a593Smuzhiyun  * @pid: PID of process to read/write from/to
141*4882a593Smuzhiyun  * @iter: where to copy to/from locally
142*4882a593Smuzhiyun  * @rvec: iovec array specifying where to copy to/from in the other process
143*4882a593Smuzhiyun  * @riovcnt: size of rvec array
144*4882a593Smuzhiyun  * @flags: currently unused
145*4882a593Smuzhiyun  * @vm_write: 0 if reading from other process, 1 if writing to other process
146*4882a593Smuzhiyun  *
147*4882a593Smuzhiyun  * Returns the number of bytes read/written or error code. May
148*4882a593Smuzhiyun  *  return less bytes than expected if an error occurs during the copying
149*4882a593Smuzhiyun  *  process.
150*4882a593Smuzhiyun  */
process_vm_rw_core(pid_t pid,struct iov_iter * iter,const struct iovec * rvec,unsigned long riovcnt,unsigned long flags,int vm_write)151*4882a593Smuzhiyun static ssize_t process_vm_rw_core(pid_t pid, struct iov_iter *iter,
152*4882a593Smuzhiyun 				  const struct iovec *rvec,
153*4882a593Smuzhiyun 				  unsigned long riovcnt,
154*4882a593Smuzhiyun 				  unsigned long flags, int vm_write)
155*4882a593Smuzhiyun {
156*4882a593Smuzhiyun 	struct task_struct *task;
157*4882a593Smuzhiyun 	struct page *pp_stack[PVM_MAX_PP_ARRAY_COUNT];
158*4882a593Smuzhiyun 	struct page **process_pages = pp_stack;
159*4882a593Smuzhiyun 	struct mm_struct *mm;
160*4882a593Smuzhiyun 	unsigned long i;
161*4882a593Smuzhiyun 	ssize_t rc = 0;
162*4882a593Smuzhiyun 	unsigned long nr_pages = 0;
163*4882a593Smuzhiyun 	unsigned long nr_pages_iov;
164*4882a593Smuzhiyun 	ssize_t iov_len;
165*4882a593Smuzhiyun 	size_t total_len = iov_iter_count(iter);
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	/*
168*4882a593Smuzhiyun 	 * Work out how many pages of struct pages we're going to need
169*4882a593Smuzhiyun 	 * when eventually calling get_user_pages
170*4882a593Smuzhiyun 	 */
171*4882a593Smuzhiyun 	for (i = 0; i < riovcnt; i++) {
172*4882a593Smuzhiyun 		iov_len = rvec[i].iov_len;
173*4882a593Smuzhiyun 		if (iov_len > 0) {
174*4882a593Smuzhiyun 			nr_pages_iov = ((unsigned long)rvec[i].iov_base
175*4882a593Smuzhiyun 					+ iov_len)
176*4882a593Smuzhiyun 				/ PAGE_SIZE - (unsigned long)rvec[i].iov_base
177*4882a593Smuzhiyun 				/ PAGE_SIZE + 1;
178*4882a593Smuzhiyun 			nr_pages = max(nr_pages, nr_pages_iov);
179*4882a593Smuzhiyun 		}
180*4882a593Smuzhiyun 	}
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 	if (nr_pages == 0)
183*4882a593Smuzhiyun 		return 0;
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	if (nr_pages > PVM_MAX_PP_ARRAY_COUNT) {
186*4882a593Smuzhiyun 		/* For reliability don't try to kmalloc more than
187*4882a593Smuzhiyun 		   2 pages worth */
188*4882a593Smuzhiyun 		process_pages = kmalloc(min_t(size_t, PVM_MAX_KMALLOC_PAGES,
189*4882a593Smuzhiyun 					      sizeof(struct pages *)*nr_pages),
190*4882a593Smuzhiyun 					GFP_KERNEL);
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun 		if (!process_pages)
193*4882a593Smuzhiyun 			return -ENOMEM;
194*4882a593Smuzhiyun 	}
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	/* Get process information */
197*4882a593Smuzhiyun 	task = find_get_task_by_vpid(pid);
198*4882a593Smuzhiyun 	if (!task) {
199*4882a593Smuzhiyun 		rc = -ESRCH;
200*4882a593Smuzhiyun 		goto free_proc_pages;
201*4882a593Smuzhiyun 	}
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 	mm = mm_access(task, PTRACE_MODE_ATTACH_REALCREDS);
204*4882a593Smuzhiyun 	if (!mm || IS_ERR(mm)) {
205*4882a593Smuzhiyun 		rc = IS_ERR(mm) ? PTR_ERR(mm) : -ESRCH;
206*4882a593Smuzhiyun 		/*
207*4882a593Smuzhiyun 		 * Explicitly map EACCES to EPERM as EPERM is a more
208*4882a593Smuzhiyun 		 * appropriate error code for process_vw_readv/writev
209*4882a593Smuzhiyun 		 */
210*4882a593Smuzhiyun 		if (rc == -EACCES)
211*4882a593Smuzhiyun 			rc = -EPERM;
212*4882a593Smuzhiyun 		goto put_task_struct;
213*4882a593Smuzhiyun 	}
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	for (i = 0; i < riovcnt && iov_iter_count(iter) && !rc; i++)
216*4882a593Smuzhiyun 		rc = process_vm_rw_single_vec(
217*4882a593Smuzhiyun 			(unsigned long)rvec[i].iov_base, rvec[i].iov_len,
218*4882a593Smuzhiyun 			iter, process_pages, mm, task, vm_write);
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	/* copied = space before - space after */
221*4882a593Smuzhiyun 	total_len -= iov_iter_count(iter);
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun 	/* If we have managed to copy any data at all then
224*4882a593Smuzhiyun 	   we return the number of bytes copied. Otherwise
225*4882a593Smuzhiyun 	   we return the error code */
226*4882a593Smuzhiyun 	if (total_len)
227*4882a593Smuzhiyun 		rc = total_len;
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	mmput(mm);
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun put_task_struct:
232*4882a593Smuzhiyun 	put_task_struct(task);
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun free_proc_pages:
235*4882a593Smuzhiyun 	if (process_pages != pp_stack)
236*4882a593Smuzhiyun 		kfree(process_pages);
237*4882a593Smuzhiyun 	return rc;
238*4882a593Smuzhiyun }
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun /**
241*4882a593Smuzhiyun  * process_vm_rw - check iovecs before calling core routine
242*4882a593Smuzhiyun  * @pid: PID of process to read/write from/to
243*4882a593Smuzhiyun  * @lvec: iovec array specifying where to copy to/from locally
244*4882a593Smuzhiyun  * @liovcnt: size of lvec array
245*4882a593Smuzhiyun  * @rvec: iovec array specifying where to copy to/from in the other process
246*4882a593Smuzhiyun  * @riovcnt: size of rvec array
247*4882a593Smuzhiyun  * @flags: currently unused
248*4882a593Smuzhiyun  * @vm_write: 0 if reading from other process, 1 if writing to other process
249*4882a593Smuzhiyun  *
250*4882a593Smuzhiyun  * Returns the number of bytes read/written or error code. May
251*4882a593Smuzhiyun  *  return less bytes than expected if an error occurs during the copying
252*4882a593Smuzhiyun  *  process.
253*4882a593Smuzhiyun  */
process_vm_rw(pid_t pid,const struct iovec __user * lvec,unsigned long liovcnt,const struct iovec __user * rvec,unsigned long riovcnt,unsigned long flags,int vm_write)254*4882a593Smuzhiyun static ssize_t process_vm_rw(pid_t pid,
255*4882a593Smuzhiyun 			     const struct iovec __user *lvec,
256*4882a593Smuzhiyun 			     unsigned long liovcnt,
257*4882a593Smuzhiyun 			     const struct iovec __user *rvec,
258*4882a593Smuzhiyun 			     unsigned long riovcnt,
259*4882a593Smuzhiyun 			     unsigned long flags, int vm_write)
260*4882a593Smuzhiyun {
261*4882a593Smuzhiyun 	struct iovec iovstack_l[UIO_FASTIOV];
262*4882a593Smuzhiyun 	struct iovec iovstack_r[UIO_FASTIOV];
263*4882a593Smuzhiyun 	struct iovec *iov_l = iovstack_l;
264*4882a593Smuzhiyun 	struct iovec *iov_r = iovstack_r;
265*4882a593Smuzhiyun 	struct iov_iter iter;
266*4882a593Smuzhiyun 	ssize_t rc;
267*4882a593Smuzhiyun 	int dir = vm_write ? WRITE : READ;
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun 	if (flags != 0)
270*4882a593Smuzhiyun 		return -EINVAL;
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	/* Check iovecs */
273*4882a593Smuzhiyun 	rc = import_iovec(dir, lvec, liovcnt, UIO_FASTIOV, &iov_l, &iter);
274*4882a593Smuzhiyun 	if (rc < 0)
275*4882a593Smuzhiyun 		return rc;
276*4882a593Smuzhiyun 	if (!iov_iter_count(&iter))
277*4882a593Smuzhiyun 		goto free_iov_l;
278*4882a593Smuzhiyun 	iov_r = iovec_from_user(rvec, riovcnt, UIO_FASTIOV, iovstack_r,
279*4882a593Smuzhiyun 				in_compat_syscall());
280*4882a593Smuzhiyun 	if (IS_ERR(iov_r)) {
281*4882a593Smuzhiyun 		rc = PTR_ERR(iov_r);
282*4882a593Smuzhiyun 		goto free_iov_l;
283*4882a593Smuzhiyun 	}
284*4882a593Smuzhiyun 	rc = process_vm_rw_core(pid, &iter, iov_r, riovcnt, flags, vm_write);
285*4882a593Smuzhiyun 	if (iov_r != iovstack_r)
286*4882a593Smuzhiyun 		kfree(iov_r);
287*4882a593Smuzhiyun free_iov_l:
288*4882a593Smuzhiyun 	kfree(iov_l);
289*4882a593Smuzhiyun 	return rc;
290*4882a593Smuzhiyun }
291*4882a593Smuzhiyun 
SYSCALL_DEFINE6(process_vm_readv,pid_t,pid,const struct iovec __user *,lvec,unsigned long,liovcnt,const struct iovec __user *,rvec,unsigned long,riovcnt,unsigned long,flags)292*4882a593Smuzhiyun SYSCALL_DEFINE6(process_vm_readv, pid_t, pid, const struct iovec __user *, lvec,
293*4882a593Smuzhiyun 		unsigned long, liovcnt, const struct iovec __user *, rvec,
294*4882a593Smuzhiyun 		unsigned long, riovcnt,	unsigned long, flags)
295*4882a593Smuzhiyun {
296*4882a593Smuzhiyun 	return process_vm_rw(pid, lvec, liovcnt, rvec, riovcnt, flags, 0);
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun 
SYSCALL_DEFINE6(process_vm_writev,pid_t,pid,const struct iovec __user *,lvec,unsigned long,liovcnt,const struct iovec __user *,rvec,unsigned long,riovcnt,unsigned long,flags)299*4882a593Smuzhiyun SYSCALL_DEFINE6(process_vm_writev, pid_t, pid,
300*4882a593Smuzhiyun 		const struct iovec __user *, lvec,
301*4882a593Smuzhiyun 		unsigned long, liovcnt, const struct iovec __user *, rvec,
302*4882a593Smuzhiyun 		unsigned long, riovcnt,	unsigned long, flags)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun 	return process_vm_rw(pid, lvec, liovcnt, rvec, riovcnt, flags, 1);
305*4882a593Smuzhiyun }
306