xref: /freebsd-11-stable/sys/compat/linux/linux_fork.c (revision 45107956a61702d4bd16a543e92a24cad745869d)
1 /*-
2  * Copyright (c) 2004 Tim J. Robbins
3  * Copyright (c) 2002 Doug Rabson
4  * Copyright (c) 2000 Marcel Moolenaar
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer
12  *    in this position and unchanged.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31 
32 #include "opt_compat.h"
33 
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/imgact.h>
37 #include <sys/ktr.h>
38 #include <sys/lock.h>
39 #include <sys/mutex.h>
40 #include <sys/proc.h>
41 #include <sys/ptrace.h>
42 #include <sys/racct.h>
43 #include <sys/sched.h>
44 #include <sys/syscallsubr.h>
45 #include <sys/sx.h>
46 #include <sys/umtx.h>
47 #include <sys/unistd.h>
48 #include <sys/wait.h>
49 
50 #include <vm/vm.h>
51 #include <vm/pmap.h>
52 #include <vm/vm_map.h>
53 
54 #ifdef COMPAT_LINUX32
55 #include <machine/../linux32/linux.h>
56 #include <machine/../linux32/linux32_proto.h>
57 #else
58 #include <machine/../linux/linux.h>
59 #include <machine/../linux/linux_proto.h>
60 #endif
61 #include <compat/linux/linux_emul.h>
62 #include <compat/linux/linux_futex.h>
63 #include <compat/linux/linux_misc.h>
64 #include <compat/linux/linux_util.h>
65 
66 #ifdef LINUX_LEGACY_SYSCALLS
67 int
linux_fork(struct thread * td,struct linux_fork_args * args)68 linux_fork(struct thread *td, struct linux_fork_args *args)
69 {
70 	struct fork_req fr;
71 	int error;
72 	struct proc *p2;
73 	struct thread *td2;
74 
75 #ifdef DEBUG
76 	if (ldebug(fork))
77 		printf(ARGS(fork, ""));
78 #endif
79 
80 	bzero(&fr, sizeof(fr));
81 	fr.fr_flags = RFFDG | RFPROC | RFSTOPPED;
82 	fr.fr_procp = &p2;
83 	if ((error = fork1(td, &fr)) != 0)
84 		return (error);
85 
86 	td2 = FIRST_THREAD_IN_PROC(p2);
87 
88 	linux_proc_init(td, td2, 0);
89 
90 	td->td_retval[0] = p2->p_pid;
91 
92 	/*
93 	 * Make this runnable after we are finished with it.
94 	 */
95 	thread_lock(td2);
96 	TD_SET_CAN_RUN(td2);
97 	sched_add(td2, SRQ_BORING);
98 	thread_unlock(td2);
99 
100 	return (0);
101 }
102 
103 int
linux_vfork(struct thread * td,struct linux_vfork_args * args)104 linux_vfork(struct thread *td, struct linux_vfork_args *args)
105 {
106 	struct fork_req fr;
107 	int error;
108 	struct proc *p2;
109 	struct thread *td2;
110 
111 #ifdef DEBUG
112 	if (ldebug(vfork))
113 		printf(ARGS(vfork, ""));
114 #endif
115 
116 	bzero(&fr, sizeof(fr));
117 	fr.fr_flags = RFFDG | RFPROC | RFMEM | RFPPWAIT | RFSTOPPED;
118 	fr.fr_procp = &p2;
119 	if ((error = fork1(td, &fr)) != 0)
120 		return (error);
121 
122 	td2 = FIRST_THREAD_IN_PROC(p2);
123 
124 	linux_proc_init(td, td2, 0);
125 
126 	td->td_retval[0] = p2->p_pid;
127 
128 	/*
129 	 * Make this runnable after we are finished with it.
130 	 */
131 	thread_lock(td2);
132 	TD_SET_CAN_RUN(td2);
133 	sched_add(td2, SRQ_BORING);
134 	thread_unlock(td2);
135 
136 	return (0);
137 }
138 #endif
139 
140 static int
linux_clone_proc(struct thread * td,struct linux_clone_args * args)141 linux_clone_proc(struct thread *td, struct linux_clone_args *args)
142 {
143 	struct fork_req fr;
144 	int error, ff = RFPROC | RFSTOPPED;
145 	struct proc *p2;
146 	struct thread *td2;
147 	int exit_signal;
148 	struct linux_emuldata *em;
149 
150 #ifdef DEBUG
151 	if (ldebug(clone)) {
152 		printf(ARGS(clone, "flags %x, stack %p, parent tid: %p, "
153 		    "child tid: %p"), (unsigned)args->flags,
154 		    args->stack, args->parent_tidptr, args->child_tidptr);
155 	}
156 #endif
157 
158 	exit_signal = args->flags & 0x000000ff;
159 	if (LINUX_SIG_VALID(exit_signal)) {
160 		exit_signal = linux_to_bsd_signal(exit_signal);
161 	} else if (exit_signal != 0)
162 		return (EINVAL);
163 
164 	if (args->flags & LINUX_CLONE_VM)
165 		ff |= RFMEM;
166 	if (args->flags & LINUX_CLONE_SIGHAND)
167 		ff |= RFSIGSHARE;
168 	/*
169 	 * XXX: In Linux, sharing of fs info (chroot/cwd/umask)
170 	 * and open files is independent.  In FreeBSD, its in one
171 	 * structure but in reality it does not cause any problems
172 	 * because both of these flags are usually set together.
173 	 */
174 	if (!(args->flags & (LINUX_CLONE_FILES | LINUX_CLONE_FS)))
175 		ff |= RFFDG;
176 
177 	if (args->flags & LINUX_CLONE_PARENT_SETTID)
178 		if (args->parent_tidptr == NULL)
179 			return (EINVAL);
180 
181 	if (args->flags & LINUX_CLONE_VFORK)
182 		ff |= RFPPWAIT;
183 
184 	bzero(&fr, sizeof(fr));
185 	fr.fr_flags = ff;
186 	fr.fr_procp = &p2;
187 	error = fork1(td, &fr);
188 	if (error)
189 		return (error);
190 
191 	td2 = FIRST_THREAD_IN_PROC(p2);
192 
193 	/* create the emuldata */
194 	linux_proc_init(td, td2, args->flags);
195 
196 	em = em_find(td2);
197 	KASSERT(em != NULL, ("clone_proc: emuldata not found.\n"));
198 
199 	if (args->flags & LINUX_CLONE_CHILD_SETTID)
200 		em->child_set_tid = args->child_tidptr;
201 	else
202 		em->child_set_tid = NULL;
203 
204 	if (args->flags & LINUX_CLONE_CHILD_CLEARTID)
205 		em->child_clear_tid = args->child_tidptr;
206 	else
207 		em->child_clear_tid = NULL;
208 
209 	if (args->flags & LINUX_CLONE_PARENT_SETTID) {
210 		error = copyout(&p2->p_pid, args->parent_tidptr,
211 		    sizeof(p2->p_pid));
212 		if (error)
213 			printf(LMSG("copyout failed!"));
214 	}
215 
216 	PROC_LOCK(p2);
217 	p2->p_sigparent = exit_signal;
218 	PROC_UNLOCK(p2);
219 	/*
220 	 * In a case of stack = NULL, we are supposed to COW calling process
221 	 * stack. This is what normal fork() does, so we just keep tf_rsp arg
222 	 * intact.
223 	 */
224 	linux_set_upcall_kse(td2, PTROUT(args->stack));
225 
226 	if (args->flags & LINUX_CLONE_SETTLS)
227 		linux_set_cloned_tls(td2, args->tls);
228 
229 	/*
230 	 * If CLONE_PARENT is set, then the parent of the new process will be
231 	 * the same as that of the calling process.
232 	 */
233 	if (args->flags & LINUX_CLONE_PARENT) {
234 		sx_xlock(&proctree_lock);
235 		PROC_LOCK(p2);
236 		proc_reparent(p2, td->td_proc->p_pptr);
237 		PROC_UNLOCK(p2);
238 		sx_xunlock(&proctree_lock);
239 	}
240 
241 #ifdef DEBUG
242 	if (ldebug(clone))
243 		printf(LMSG("clone: successful rfork to %d, "
244 		    "stack %p sig = %d"), (int)p2->p_pid, args->stack,
245 		    exit_signal);
246 #endif
247 
248 	/*
249 	 * Make this runnable after we are finished with it.
250 	 */
251 	thread_lock(td2);
252 	TD_SET_CAN_RUN(td2);
253 	sched_add(td2, SRQ_BORING);
254 	thread_unlock(td2);
255 
256 	td->td_retval[0] = p2->p_pid;
257 
258 	return (0);
259 }
260 
261 static int
linux_clone_thread(struct thread * td,struct linux_clone_args * args)262 linux_clone_thread(struct thread *td, struct linux_clone_args *args)
263 {
264 	struct linux_emuldata *em;
265 	struct thread *newtd;
266 	struct proc *p;
267 	int error;
268 
269 #ifdef DEBUG
270 	if (ldebug(clone)) {
271 		printf(ARGS(clone, "thread: flags %x, stack %p, parent tid: %p, "
272 		    "child tid: %p"), (unsigned)args->flags,
273 		    args->stack, args->parent_tidptr, args->child_tidptr);
274 	}
275 #endif
276 
277 	LINUX_CTR4(clone_thread, "thread(%d) flags %x ptid %p ctid %p",
278 	    td->td_tid, (unsigned)args->flags,
279 	    args->parent_tidptr, args->child_tidptr);
280 
281 	if ((args->flags & LINUX_CLONE_PARENT) != 0)
282 		return (EINVAL);
283 	if (args->flags & LINUX_CLONE_PARENT_SETTID)
284 		if (args->parent_tidptr == NULL)
285 			return (EINVAL);
286 
287 	/* Threads should be created with own stack */
288 	if (args->stack == NULL)
289 		return (EINVAL);
290 
291 	p = td->td_proc;
292 
293 #ifdef RACCT
294 	if (racct_enable) {
295 		PROC_LOCK(p);
296 		error = racct_add(p, RACCT_NTHR, 1);
297 		PROC_UNLOCK(p);
298 		if (error != 0)
299 			return (EPROCLIM);
300 	}
301 #endif
302 
303 	/* Initialize our td */
304 	error = kern_thr_alloc(p, 0, &newtd);
305 	if (error)
306 		goto fail;
307 
308 	cpu_copy_thread(newtd, td);
309 
310 	bzero(&newtd->td_startzero,
311 	    __rangeof(struct thread, td_startzero, td_endzero));
312 	bcopy(&td->td_startcopy, &newtd->td_startcopy,
313 	    __rangeof(struct thread, td_startcopy, td_endcopy));
314 	newtd->td_sa = td->td_sa;
315 
316 	newtd->td_proc = p;
317 	thread_cow_get(newtd, td);
318 
319 	/* create the emuldata */
320 	linux_proc_init(td, newtd, args->flags);
321 
322 	em = em_find(newtd);
323 	KASSERT(em != NULL, ("clone_thread: emuldata not found.\n"));
324 
325 	if (args->flags & LINUX_CLONE_SETTLS)
326 		linux_set_cloned_tls(newtd, args->tls);
327 
328 	if (args->flags & LINUX_CLONE_CHILD_SETTID)
329 		em->child_set_tid = args->child_tidptr;
330 	else
331 		em->child_set_tid = NULL;
332 
333 	if (args->flags & LINUX_CLONE_CHILD_CLEARTID)
334 		em->child_clear_tid = args->child_tidptr;
335 	else
336 		em->child_clear_tid = NULL;
337 
338 	cpu_thread_clean(newtd);
339 
340 	linux_set_upcall_kse(newtd, PTROUT(args->stack));
341 
342 	PROC_LOCK(p);
343 	p->p_flag |= P_HADTHREADS;
344 	thread_link(newtd, p);
345 	bcopy(p->p_comm, newtd->td_name, sizeof(newtd->td_name));
346 
347 	thread_lock(td);
348 	/* let the scheduler know about these things. */
349 	sched_fork_thread(td, newtd);
350 	thread_unlock(td);
351 	if (P_SHOULDSTOP(p))
352 		newtd->td_flags |= TDF_ASTPENDING | TDF_NEEDSUSPCHK;
353 
354 	if (p->p_ptevents & PTRACE_LWP)
355 		newtd->td_dbgflags |= TDB_BORN;
356 	PROC_UNLOCK(p);
357 
358 	tidhash_add(newtd);
359 
360 #ifdef DEBUG
361 	if (ldebug(clone))
362 		printf(ARGS(clone, "successful clone to %d, stack %p"),
363 		(int)newtd->td_tid, args->stack);
364 #endif
365 
366 	LINUX_CTR2(clone_thread, "thread(%d) successful clone to %d",
367 	    td->td_tid, newtd->td_tid);
368 
369 	if (args->flags & LINUX_CLONE_PARENT_SETTID) {
370 		error = copyout(&newtd->td_tid, args->parent_tidptr,
371 		    sizeof(newtd->td_tid));
372 		if (error)
373 			printf(LMSG("clone_thread: copyout failed!"));
374 	}
375 
376 	/*
377 	 * Make this runnable after we are finished with it.
378 	 */
379 	thread_lock(newtd);
380 	TD_SET_CAN_RUN(newtd);
381 	sched_add(newtd, SRQ_BORING);
382 	thread_unlock(newtd);
383 
384 	td->td_retval[0] = newtd->td_tid;
385 
386 	return (0);
387 
388 fail:
389 #ifdef RACCT
390 	if (racct_enable) {
391 		PROC_LOCK(p);
392 		racct_sub(p, RACCT_NTHR, 1);
393 		PROC_UNLOCK(p);
394 	}
395 #endif
396 	return (error);
397 }
398 
399 int
linux_clone(struct thread * td,struct linux_clone_args * args)400 linux_clone(struct thread *td, struct linux_clone_args *args)
401 {
402 
403 	if (args->flags & LINUX_CLONE_THREAD)
404 		return (linux_clone_thread(td, args));
405 	else
406 		return (linux_clone_proc(td, args));
407 }
408 
409 int
linux_exit(struct thread * td,struct linux_exit_args * args)410 linux_exit(struct thread *td, struct linux_exit_args *args)
411 {
412 	struct linux_emuldata *em;
413 
414 	em = em_find(td);
415 	KASSERT(em != NULL, ("exit: emuldata not found.\n"));
416 
417 	LINUX_CTR2(exit, "thread(%d) (%d)", em->em_tid, args->rval);
418 
419 	umtx_thread_exit(td);
420 
421 	linux_thread_detach(td);
422 
423 	/*
424 	 * XXX. When the last two threads of a process
425 	 * exit via pthread_exit() try thr_exit() first.
426 	 */
427 	kern_thr_exit(td);
428 	exit1(td, args->rval, 0);
429 		/* NOTREACHED */
430 }
431 
432 int
linux_set_tid_address(struct thread * td,struct linux_set_tid_address_args * args)433 linux_set_tid_address(struct thread *td, struct linux_set_tid_address_args *args)
434 {
435 	struct linux_emuldata *em;
436 
437 	em = em_find(td);
438 	KASSERT(em != NULL, ("set_tid_address: emuldata not found.\n"));
439 
440 	em->child_clear_tid = args->tidptr;
441 
442 	td->td_retval[0] = em->em_tid;
443 
444 	LINUX_CTR3(set_tid_address, "tidptr(%d) %p, returns %d",
445 	    em->em_tid, args->tidptr, td->td_retval[0]);
446 
447 	return (0);
448 }
449 
450 void
linux_thread_detach(struct thread * td)451 linux_thread_detach(struct thread *td)
452 {
453 	struct linux_sys_futex_args cup;
454 	struct linux_emuldata *em;
455 	int *child_clear_tid;
456 	int error;
457 
458 	em = em_find(td);
459 	KASSERT(em != NULL, ("thread_detach: emuldata not found.\n"));
460 
461 	LINUX_CTR1(thread_detach, "thread(%d)", em->em_tid);
462 
463 	release_futexes(td, em);
464 
465 	child_clear_tid = em->child_clear_tid;
466 
467 	if (child_clear_tid != NULL) {
468 
469 		LINUX_CTR2(thread_detach, "thread(%d) %p",
470 		    em->em_tid, child_clear_tid);
471 
472 		error = suword32(child_clear_tid, 0);
473 		if (error != 0)
474 			return;
475 
476 		cup.uaddr = child_clear_tid;
477 		cup.op = LINUX_FUTEX_WAKE;
478 		cup.val = 1;		/* wake one */
479 		cup.timeout = NULL;
480 		cup.uaddr2 = NULL;
481 		cup.val3 = 0;
482 		error = linux_sys_futex(td, &cup);
483 		/*
484 		 * this cannot happen at the moment and if this happens it
485 		 * probably means there is a user space bug
486 		 */
487 		if (error != 0)
488 			linux_msg(td, "futex stuff in thread_detach failed.");
489 	}
490 }
491