1 /* Copyright (C) 1994-2022 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3 
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8 
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <https://www.gnu.org/licenses/>.  */
17 
18 #include <errno.h>
19 #include <unistd.h>
20 #include <hurd.h>
21 #include <hurd/signal.h>
22 #include <hurd/threadvar.h>
23 #include <setjmp.h>
24 #include <thread_state.h>
25 #include <sysdep.h>		/* For stack growth direction.  */
26 #include "set-hooks.h"
27 #include <assert.h>
28 #include "hurdmalloc.h"		/* XXX */
29 #include <tls.h>
30 #include <malloc/malloc-internal.h>
31 #include <nss/nss_database.h>
32 #include <unwind-link.h>
33 #include <register-atfork.h>
34 
35 #undef __fork
36 
37 
38 /* Things that want to be locked while forking.  */
39 symbol_set_declare (_hurd_fork_locks)
40 
41 /* Things that want to be called before we fork, to prepare the parent for
42    task_create, when the new child task will inherit our address space.  */
43 DEFINE_HOOK (_hurd_fork_prepare_hook, (void));
44 
45 /* Things that want to be called when we are forking, with the above all
46    locked.  They are passed the task port of the child.  The child process
47    is all set up except for doing proc_child, and has no threads yet.  */
48 DEFINE_HOOK (_hurd_fork_setup_hook, (void));
49 
50 /* Things to be run in the child fork.  */
51 DEFINE_HOOK (_hurd_fork_child_hook, (void));
52 
53 /* Things to be run in the parent fork.  */
54 DEFINE_HOOK (_hurd_fork_parent_hook, (void));
55 
56 
57 /* Clone the calling process, creating an exact copy.
58    Return -1 for errors, 0 to the new process,
59    and the process ID of the new process to the old process.  */
60 pid_t
_Fork(void)61 _Fork (void)
62 {
63   jmp_buf env;
64   pid_t pid;
65   size_t i;
66   error_t err;
67   struct hurd_sigstate *volatile ss;
68 
69   ss = _hurd_self_sigstate ();
70 retry:
71   __spin_lock (&ss->critical_section_lock);
72 
73 #undef	LOSE
74 #define LOSE do { assert_perror (err); goto lose; } while (0) /* XXX */
75 
76   if (! setjmp (env))
77     {
78       process_t newproc;
79       task_t newtask;
80       thread_t thread, sigthread;
81       mach_port_urefs_t thread_refs, sigthread_refs;
82       struct machine_thread_state state;
83       mach_msg_type_number_t statecount;
84       mach_port_t *portnames = NULL;
85       mach_msg_type_number_t nportnames = 0;
86       mach_port_type_t *porttypes = NULL;
87       mach_msg_type_number_t nporttypes = 0;
88       thread_t *threads = NULL;
89       mach_msg_type_number_t nthreads = 0;
90       int ports_locked = 0, stopped = 0;
91 
92       void resume_threads (void)
93 	{
94 	  if (! stopped)
95 	    return;
96 
97 	  assert (threads);
98 
99 	  for (i = 0; i < nthreads; ++i)
100 	    if (threads[i] != ss->thread)
101 	      __thread_resume (threads[i]);
102 	  stopped = 0;
103 	}
104 
105       /* Run things that prepare for forking before we create the task.  */
106       RUN_HOOK (_hurd_fork_prepare_hook, ());
107 
108       /* Lock things that want to be locked before we fork.  */
109       {
110 	void *const *p;
111 	for (p = symbol_set_first_element (_hurd_fork_locks);
112 	     ! symbol_set_end_p (_hurd_fork_locks, p);
113 	     ++p)
114 	  __mutex_lock (*p);
115       }
116       __mutex_lock (&_hurd_siglock);
117 
118       /* Acquire malloc locks.  This needs to come last because fork
119 	 handlers may use malloc, and the libio list lock has an
120 	 indirect malloc dependency as well (via the getdelim
121 	 function).  */
122       _hurd_malloc_fork_prepare ();
123 
124       newtask = MACH_PORT_NULL;
125       thread = sigthread = MACH_PORT_NULL;
126       newproc = MACH_PORT_NULL;
127 
128       /* Lock all the port cells for the standard ports while we copy the
129 	 address space.  We want to insert all the send rights into the
130 	 child with the same names.  */
131       for (i = 0; i < _hurd_nports; ++i)
132 	__spin_lock (&_hurd_ports[i].lock);
133       ports_locked = 1;
134 
135 
136       /* Keep our SS locked while stopping other threads, so they don't get a
137          chance to have it locked in the copied space.  */
138       __spin_lock (&ss->lock);
139       /* Stop all other threads while copying the address space,
140 	 so nothing changes.  */
141       err = __proc_dostop (_hurd_ports[INIT_PORT_PROC].port, ss->thread);
142       __spin_unlock (&ss->lock);
143       if (!err)
144 	{
145 	  stopped = 1;
146 
147 #define XXX_KERNEL_PAGE_FAULT_BUG /* XXX work around page fault bug in mk */
148 
149 #ifdef XXX_KERNEL_PAGE_FAULT_BUG
150 	  /* Gag me with a pitchfork.
151 	     The bug scenario is this:
152 
153 	     - The page containing __mach_task_self_ is paged out.
154 	     - The signal thread was faulting on that page when we
155 	       suspended it via proc_dostop.  It holds some lock, or set
156 	       some busy bit, or somesuch.
157 	     - Now this thread faults on that same page.
158 	     - GRATUIOUS DEADLOCK
159 
160 	     We can break the deadlock by aborting the thread that faulted
161 	     first, which if the bug happened was the signal thread because
162 	     it is the only other thread and we just suspended it.
163 	     */
164 	  __thread_abort (_hurd_msgport_thread);
165 #endif
166 	  /* Create the child task.  It will inherit a copy of our memory.  */
167 	  err = __task_create (__mach_task_self (),
168 #ifdef KERN_INVALID_LEDGER
169 			       NULL, 0,	/* OSF Mach */
170 #endif
171 			       1, &newtask);
172 	}
173 
174       /* Unlock the global signal state lock, so we do not
175 	 block the signal thread any longer than necessary.  */
176       __mutex_unlock (&_hurd_siglock);
177 
178       if (err)
179 	LOSE;
180 
181       /* Fetch the names of all ports used in this task.  */
182       if (err = __mach_port_names (__mach_task_self (),
183 				   &portnames, &nportnames,
184 				   &porttypes, &nporttypes))
185 	LOSE;
186       if (nportnames != nporttypes)
187 	{
188 	  err = EGRATUITOUS;
189 	  LOSE;
190 	}
191 
192       /* Get send rights for all the threads in this task.
193 	 We want to avoid giving these rights to the child.  */
194       if (err = __task_threads (__mach_task_self (), &threads, &nthreads))
195 	LOSE;
196 
197       /* Get the child process's proc server port.  We will insert it into
198 	 the child with the same name as we use for our own proc server
199 	 port; and we will need it to set the child's message port.  */
200       if (err = __proc_task2proc (_hurd_ports[INIT_PORT_PROC].port,
201 				  newtask, &newproc))
202 	LOSE;
203 
204       /* Insert all our port rights into the child task.  */
205       thread_refs = sigthread_refs = 0;
206       for (i = 0; i < nportnames; ++i)
207 	{
208 	  if (porttypes[i] & MACH_PORT_TYPE_RECEIVE)
209 	    {
210 	      /* This is a receive right.  We want to give the child task
211 		 its own new receive right under the same name.  */
212 	      if (err = __mach_port_allocate_name (newtask,
213 						   MACH_PORT_RIGHT_RECEIVE,
214 						   portnames[i]))
215 		LOSE;
216 	      if (porttypes[i] & MACH_PORT_TYPE_SEND)
217 		{
218 		  /* Give the child as many send rights for its receive
219 		     right as we have for ours.  */
220 		  mach_port_urefs_t refs;
221 		  mach_port_t port;
222 		  mach_msg_type_name_t poly;
223 		  if (err = __mach_port_get_refs (__mach_task_self (),
224 						  portnames[i],
225 						  MACH_PORT_RIGHT_SEND,
226 						  &refs))
227 		    LOSE;
228 		  if (err = __mach_port_extract_right (newtask,
229 						       portnames[i],
230 						       MACH_MSG_TYPE_MAKE_SEND,
231 						       &port, &poly))
232 		    LOSE;
233 		  if (portnames[i] == _hurd_msgport)
234 		    {
235 		      /* We just created a receive right for the child's
236 			 message port and are about to insert send rights
237 			 for it.  Now, while we happen to have a send right
238 			 for it, give it to the proc server.  */
239 		      mach_port_t old;
240 		      if (err = __proc_setmsgport (newproc, port, &old))
241 			LOSE;
242 		      if (old != MACH_PORT_NULL)
243 			/* XXX what to do here? */
244 			__mach_port_deallocate (__mach_task_self (), old);
245 		      /* The new task will receive its own exceptions
246 			 on its message port.  */
247 		      if (err =
248 #ifdef TASK_EXCEPTION_PORT
249 			  __task_set_special_port (newtask,
250 						   TASK_EXCEPTION_PORT,
251 						   port)
252 #elif defined (EXC_MASK_ALL)
253 			  __task_set_exception_ports
254 			  (newtask, EXC_MASK_ALL & ~(EXC_MASK_SYSCALL
255 						     | EXC_MASK_MACH_SYSCALL
256 						     | EXC_MASK_RPC_ALERT),
257 			   port, EXCEPTION_DEFAULT, MACHINE_THREAD_STATE)
258 #else
259 # error task_set_exception_port?
260 #endif
261 			  )
262 			LOSE;
263 		    }
264 		  if (err = __mach_port_insert_right (newtask,
265 						      portnames[i],
266 						      port,
267 						      MACH_MSG_TYPE_MOVE_SEND))
268 		    LOSE;
269 		  if (refs > 1
270 		      && (err = __mach_port_mod_refs (newtask,
271 						      portnames[i],
272 						      MACH_PORT_RIGHT_SEND,
273 						      refs - 1)))
274 		    LOSE;
275 		}
276 	      if (porttypes[i] & MACH_PORT_TYPE_SEND_ONCE)
277 		{
278 		  /* Give the child a send-once right for its receive right,
279 		     since we have one for ours.  */
280 		  mach_port_t port;
281 		  mach_msg_type_name_t poly;
282 		  if (err = __mach_port_extract_right
283 		      (newtask,
284 		       portnames[i],
285 		       MACH_MSG_TYPE_MAKE_SEND_ONCE,
286 		       &port, &poly))
287 		    LOSE;
288 		  if (err = __mach_port_insert_right
289 		      (newtask,
290 		       portnames[i], port,
291 		       MACH_MSG_TYPE_MOVE_SEND_ONCE))
292 		    LOSE;
293 		}
294 	    }
295 	  else if (porttypes[i]
296 		   & (MACH_PORT_TYPE_SEND|MACH_PORT_TYPE_DEAD_NAME))
297 	    {
298 	      /* This is a send right or a dead name.
299 		 Give the child as many references for it as we have.  */
300 	      mach_port_urefs_t refs = 0, *record_refs = NULL;
301 	      mach_port_t insert;
302 	      mach_msg_type_name_t insert_type = MACH_MSG_TYPE_COPY_SEND;
303 	      if (portnames[i] == newtask || portnames[i] == newproc)
304 		/* Skip the name we use for the child's task or proc ports.  */
305 		continue;
306 	      if (portnames[i] == __mach_task_self ())
307 		/* For the name we use for our own task port,
308 		   insert the child's task port instead.  */
309 		insert = newtask;
310 	      else if (portnames[i] == _hurd_ports[INIT_PORT_PROC].port)
311 		{
312 		  /* Use the proc server port for the new task.  */
313 		  insert = newproc;
314 		  insert_type = MACH_MSG_TYPE_COPY_SEND;
315 		}
316 	      else if (portnames[i] == ss->thread)
317 		{
318 		  /* For the name we use for our own thread port, we will
319 		     insert the thread port for the child main user thread
320 		     after we create it.  */
321 		  insert = MACH_PORT_NULL;
322 		  record_refs = &thread_refs;
323 		  /* Allocate a dead name right for this name as a
324 		     placeholder, so the kernel will not chose this name
325 		     for any other new port (it might use it for one of the
326 		     rights created when a thread is created).  */
327 		  if (err = __mach_port_allocate_name
328 		      (newtask, MACH_PORT_RIGHT_DEAD_NAME, portnames[i]))
329 		    LOSE;
330 		}
331 	      else if (portnames[i] == _hurd_msgport_thread)
332 		/* For the name we use for our signal thread's thread port,
333 		   we will insert the thread port for the child's signal
334 		   thread after we create it.  */
335 		{
336 		  insert = MACH_PORT_NULL;
337 		  record_refs = &sigthread_refs;
338 		  /* Allocate a dead name right as a placeholder.  */
339 		  if (err = __mach_port_allocate_name
340 		      (newtask, MACH_PORT_RIGHT_DEAD_NAME, portnames[i]))
341 		    LOSE;
342 		}
343 	      else
344 		{
345 		  /* Skip the name we use for any of our own thread ports.  */
346 		  mach_msg_type_number_t j;
347 		  for (j = 0; j < nthreads; ++j)
348 		    if (portnames[i] == threads[j])
349 		      break;
350 		  if (j < nthreads)
351 		    continue;
352 
353 		  /* Copy our own send right.  */
354 		  insert = portnames[i];
355 		}
356 	      /* Find out how many user references we have for
357 		 the send right with this name.  */
358 	      if (err = __mach_port_get_refs (__mach_task_self (),
359 					      portnames[i],
360 					      MACH_PORT_RIGHT_SEND,
361 					      record_refs ?: &refs))
362 		LOSE;
363 	      if (insert == MACH_PORT_NULL)
364 		continue;
365 	      if (insert == portnames[i]
366 		  && (porttypes[i] & MACH_PORT_TYPE_DEAD_NAME))
367 		/* This is a dead name; allocate another dead name
368 		   with the same name in the child.  */
369 	      allocate_dead_name:
370 		err = __mach_port_allocate_name (newtask,
371 						 MACH_PORT_RIGHT_DEAD_NAME,
372 						 portnames[i]);
373 	      else
374 		/* Insert the chosen send right into the child.  */
375 		err = __mach_port_insert_right (newtask,
376 						portnames[i],
377 						insert, insert_type);
378 	      switch (err)
379 		{
380 		case KERN_NAME_EXISTS:
381 		  {
382 		    /* It already has a send right under this name (?!).
383 		       Well, it starts out with a send right for its task
384 		       port, and inherits the bootstrap and exception ports
385 		       from us.  */
386 		    mach_port_t childport;
387 		    mach_msg_type_name_t poly;
388 		    assert (__mach_port_extract_right (newtask, portnames[i],
389 						       MACH_MSG_TYPE_COPY_SEND,
390 						       &childport,
391 						       &poly) == 0
392 			    && childport == insert
393 			    && __mach_port_deallocate (__mach_task_self (),
394 						       childport) == 0);
395 		    break;
396 		  }
397 
398 		case KERN_INVALID_CAPABILITY:
399 		  /* The port just died.  It was a send right,
400 		     and now it's a dead name.  */
401 		  goto allocate_dead_name;
402 
403 		default:
404 		  LOSE;
405 		  break;
406 
407 		case KERN_SUCCESS:
408 		  /* Give the child as many user references as we have.  */
409 		  if (refs > 1
410 		      && (err = __mach_port_mod_refs (newtask,
411 						      portnames[i],
412 						      MACH_PORT_RIGHT_SEND,
413 						      refs - 1)))
414 		    LOSE;
415 		}
416 	    }
417 	}
418 
419       /* Unlock the standard port cells.  The child must unlock its own
420 	 copies too.  */
421       for (i = 0; i < _hurd_nports; ++i)
422 	__spin_unlock (&_hurd_ports[i].lock);
423       ports_locked = 0;
424 
425       /* All state has now been copied from the parent.  It is safe to
426 	 resume other parent threads.  */
427       resume_threads ();
428 
429       /* Create the child main user thread and signal thread.  */
430       if ((err = __thread_create (newtask, &thread))
431 	  || (err = __thread_create (newtask, &sigthread)))
432 	LOSE;
433 
434       /* Insert send rights for those threads.  We previously allocated
435 	 dead name rights with the names we want to give the thread ports
436 	 in the child as placeholders.  Now deallocate them so we can use
437 	 the names.  */
438       if ((err = __mach_port_deallocate (newtask, ss->thread))
439 	  || (err = __mach_port_insert_right (newtask, ss->thread,
440 					      thread,
441 					      MACH_MSG_TYPE_COPY_SEND)))
442 	LOSE;
443       /* XXX consumed? (_hurd_sigthread is no more) */
444       if (thread_refs > 1
445 	  && (err = __mach_port_mod_refs (newtask, ss->thread,
446 					  MACH_PORT_RIGHT_SEND,
447 					  thread_refs - 1)))
448 	LOSE;
449       if ((_hurd_msgport_thread != MACH_PORT_NULL) /* Let user have none.  */
450 	  && ((err = __mach_port_deallocate (newtask, _hurd_msgport_thread))
451 	      || (err = __mach_port_insert_right (newtask,
452 						  _hurd_msgport_thread,
453 						  sigthread,
454 						  MACH_MSG_TYPE_COPY_SEND))))
455 	LOSE;
456       if (sigthread_refs > 1
457 	  && (err = __mach_port_mod_refs (newtask, _hurd_msgport_thread,
458 					  MACH_PORT_RIGHT_SEND,
459 					  sigthread_refs - 1)))
460 	LOSE;
461 
462       /* This seems like a convenient juncture to copy the proc server's
463 	 idea of what addresses our argv and envp are found at from the
464 	 parent into the child.  Since we happen to know that the child
465 	 shares our memory image, it is we who should do this copying.  */
466       {
467 	vm_address_t argv, envp;
468 	err = (__USEPORT (PROC, __proc_get_arg_locations (port, &argv, &envp))
469 	       ?: __proc_set_arg_locations (newproc, argv, envp));
470 	if (err)
471 	  LOSE;
472       }
473 
474       /* Set the child signal thread up to run the msgport server function
475 	 using the same signal thread stack copied from our address space.
476 	 We fetch the state before longjmp'ing it so that miscellaneous
477 	 registers not affected by longjmp (such as i386 segment registers)
478 	 are in their normal default state.  */
479       statecount = MACHINE_THREAD_STATE_COUNT;
480       if (err = __thread_get_state (_hurd_msgport_thread,
481 				    MACHINE_THREAD_STATE_FLAVOR,
482 				    (natural_t *) &state, &statecount))
483 	LOSE;
484 #ifdef STACK_GROWTH_UP
485       if (__hurd_sigthread_stack_base == 0)
486 	{
487 	  state.SP &= __hurd_threadvar_stack_mask;
488 	  state.SP += __hurd_threadvar_stack_offset;
489 	}
490       else
491 	state.SP = __hurd_sigthread_stack_base;
492 #else
493       if (__hurd_sigthread_stack_end == 0)
494 	{
495 	  /* The signal thread has a stack assigned by pthread.
496 	     The threadvar_stack variables conveniently tell us how
497 	     to get to the highest address in the stack, just below
498 	     the per-thread variables.  */
499 	  state.SP &= __hurd_threadvar_stack_mask;
500 	  state.SP += __hurd_threadvar_stack_offset;
501 	}
502       else
503 	state.SP = __hurd_sigthread_stack_end;
504 #endif
505       MACHINE_THREAD_STATE_SET_PC (&state,
506 				   (unsigned long int) _hurd_msgport_receive);
507 
508       /* Do special signal thread setup for TLS if needed.  */
509       if (err = _hurd_tls_fork (sigthread, _hurd_msgport_thread, &state))
510 	LOSE;
511 
512       if (err = __thread_set_state (sigthread, MACHINE_THREAD_STATE_FLAVOR,
513 				    (natural_t *) &state, statecount))
514 	LOSE;
515       /* We do not thread_resume SIGTHREAD here because the child
516 	 fork needs to do more setup before it can take signals.  */
517 
518       /* Set the child user thread up to return 1 from the setjmp above.  */
519       _hurd_longjmp_thread_state (&state, env, 1);
520 
521       /* Do special thread setup for TLS if needed.  */
522       if (err = _hurd_tls_fork (thread, ss->thread, &state))
523 	LOSE;
524 
525       if (err = __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR,
526 				    (natural_t *) &state, statecount))
527 	LOSE;
528 
529       /* Get the PID of the child from the proc server.  We must do this
530 	 before calling proc_child below, because at that point any
531 	 authorized POSIX.1 process may kill the child task with SIGKILL.  */
532       if (err = __USEPORT (PROC, __proc_task2pid (port, newtask, &pid)))
533 	LOSE;
534 
535       /* Register the child with the proc server.  It is important that
536 	 this be that last thing we do before starting the child thread
537 	 running.  Once proc_child has been done for the task, it appears
538 	 as a POSIX.1 process.  Any errors we get must be detected before
539 	 this point, and the child must have a message port so it responds
540 	 to POSIX.1 signals.  */
541       if (err = __USEPORT (PROC, __proc_child (port, newtask)))
542 	LOSE;
543 
544       /* This must be the absolutely last thing we do; we can't assume that
545 	 the child will remain alive for even a moment once we do this.  We
546 	 ignore errors because we have committed to the fork and are not
547 	 allowed to return them after the process becomes visible to
548 	 POSIX.1 (which happened right above when we called proc_child).  */
549       (void) __thread_resume (thread);
550 
551     lose:
552       if (ports_locked)
553 	for (i = 0; i < _hurd_nports; ++i)
554 	  __spin_unlock (&_hurd_ports[i].lock);
555 
556       resume_threads ();
557 
558       if (newtask != MACH_PORT_NULL)
559 	{
560 	  if (err)
561 	    __task_terminate (newtask);
562 	  __mach_port_deallocate (__mach_task_self (), newtask);
563 	}
564       if (thread != MACH_PORT_NULL)
565 	__mach_port_deallocate (__mach_task_self (), thread);
566       if (sigthread != MACH_PORT_NULL)
567 	__mach_port_deallocate (__mach_task_self (), sigthread);
568       if (newproc != MACH_PORT_NULL)
569 	__mach_port_deallocate (__mach_task_self (), newproc);
570 
571       if (portnames)
572 	__vm_deallocate (__mach_task_self (),
573 			 (vm_address_t) portnames,
574 			 nportnames * sizeof (*portnames));
575       if (porttypes)
576 	__vm_deallocate (__mach_task_self (),
577 			 (vm_address_t) porttypes,
578 			 nporttypes * sizeof (*porttypes));
579       if (threads)
580 	{
581 	  for (i = 0; i < nthreads; ++i)
582 	    __mach_port_deallocate (__mach_task_self (), threads[i]);
583 	  __vm_deallocate (__mach_task_self (),
584 			   (vm_address_t) threads,
585 			   nthreads * sizeof (*threads));
586 	}
587 
588       /* Release malloc locks.  */
589       _hurd_malloc_fork_parent ();
590 
591       /* Run things that want to run in the parent to restore it to
592 	 normality.  Usually prepare hooks and parent hooks are
593 	 symmetrical: the prepare hook arrests state in some way for the
594 	 fork, and the parent hook restores the state for the parent to
595 	 continue executing normally.  */
596       RUN_HOOK (_hurd_fork_parent_hook, ());
597     }
598   else
599     {
600       struct hurd_sigstate *oldstates;
601 
602       /* We are the child task.  Unlock the standard port cells, which were
603 	 locked in the parent when we copied its memory.  The parent has
604 	 inserted send rights with the names that were in the cells then.  */
605       for (i = 0; i < _hurd_nports; ++i)
606 	__spin_unlock (&_hurd_ports[i].lock);
607 
608       /* Claim our sigstate structure and unchain the rest: the
609 	 threads existed in the parent task but don't exist in this
610 	 task (the child process).  Delay freeing them until later
611 	 because some of the further setup and unlocking might be
612 	 required for free to work.  Before we finish cleaning up,
613 	 we will reclaim the signal thread's sigstate structure (if
614 	 it had one).  */
615       oldstates = _hurd_sigstates;
616       if (oldstates == ss)
617 	oldstates = ss->next;
618       else
619 	{
620 	  while (_hurd_sigstates->next != ss)
621 	    _hurd_sigstates = _hurd_sigstates->next;
622 	  _hurd_sigstates->next = ss->next;
623 	}
624       ss->next = NULL;
625       _hurd_sigstates = ss;
626       __mutex_unlock (&_hurd_siglock);
627       /* Earlier on, the global sigstate may have been tainted and now needs to
628          be reinitialized.  Nobody is interested in its present state anymore:
629          we're not, the signal thread will be restarted, and there are no other
630          threads.
631 
632          We can't simply allocate a fresh global sigstate here, as
633          _hurd_thread_sigstate will call malloc and that will deadlock trying
634          to determine the current thread's sigstate.  */
635 #if 0
636       _hurd_thread_sigstate_init (_hurd_global_sigstate, MACH_PORT_NULL);
637 #else
638       /* Only reinitialize the lock -- otherwise we might have to do additional
639          setup as done in hurdsig.c:_hurdsig_init.  */
640       __spin_lock_init (&_hurd_global_sigstate->lock);
641 #endif
642 
643       /* We are one of the (exactly) two threads in this new task, we
644 	 will take the task-global signals.  */
645       _hurd_sigstate_set_global_rcv (ss);
646 
647       /* Fetch our new process IDs from the proc server.  No need to
648 	 refetch our pgrp; it is always inherited from the parent (so
649 	 _hurd_pgrp is already correct), and the proc server will send us a
650 	 proc_newids notification when it changes.  */
651       err = __USEPORT (PROC, __proc_getpids (port, &_hurd_pid, &_hurd_ppid,
652 					     &_hurd_orphaned));
653 
654       /* Forking clears the trace flag and pending masks.  */
655       __sigemptyset (&_hurdsig_traced);
656       __sigemptyset (&_hurd_global_sigstate->pending);
657       __sigemptyset (&ss->pending);
658 
659       __libc_unwind_link_after_fork ();
660 
661       /* Release malloc locks.  */
662       _hurd_malloc_fork_child ();
663       call_function_static_weak (__malloc_fork_unlock_child);
664 
665       /* Run things that want to run in the child task to set up.  */
666       RUN_HOOK (_hurd_fork_child_hook, ());
667 
668       /* Set up proc server-assisted fault recovery for the signal thread.  */
669       _hurdsig_fault_init ();
670 
671       /* Start the signal thread listening on the message port.  */
672       if (!err)
673 	err = __thread_resume (_hurd_msgport_thread);
674 
675       /* Reclaim the signal thread's sigstate structure and free the
676 	 other old sigstate structures.  */
677       while (oldstates != NULL)
678 	{
679 	  struct hurd_sigstate *next = oldstates->next;
680 
681 	  if (oldstates->thread == _hurd_msgport_thread)
682 	    {
683 	      /* If we have a second signal state structure then we
684 		 must have been through here before--not good.  */
685 	      assert (_hurd_sigstates->next == 0);
686 	      _hurd_sigstates->next = oldstates;
687 	      oldstates->next = 0;
688 	    }
689 	  else
690 	    free (oldstates);
691 
692 	  oldstates = next;
693 	}
694 
695       /* XXX what to do if we have any errors here? */
696 
697       pid = 0;
698     }
699 
700   /* Unlock things we locked before creating the child task.
701      They are locked in both the parent and child tasks.  */
702   {
703     void *const *p;
704     for (p = symbol_set_first_element (_hurd_fork_locks);
705 	 ! symbol_set_end_p (_hurd_fork_locks, p);
706 	 ++p)
707       __mutex_unlock (*p);
708   }
709 
710   _hurd_critical_section_unlock (ss);
711   if (err == EINTR)
712     /* Got a signal while inside an RPC of the critical section, retry again */
713     goto retry;
714 
715   return err ? __hurd_fail (err) : pid;
716 }
717 libc_hidden_def (_Fork)
718