1 /* Copyright (C) 1991-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 <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 
22 #include <lock-intern.h>	/* For `struct mutex'.  */
23 #include <pthreadP.h>
24 #include <mach.h>
25 #include <mach/thread_switch.h>
26 #include <mach/mig_support.h>
27 #include <mach/vm_param.h>
28 
29 #include <hurd.h>
30 #include <hurd/id.h>
31 #include <hurd/signal.h>
32 
33 #include "hurdfault.h"
34 #include "hurdmalloc.h"		/* XXX */
35 #include "../locale/localeinfo.h"
36 
37 #include <libc-diag.h>
38 
39 const char *_hurdsig_getenv (const char *);
40 
41 struct mutex _hurd_siglock;
42 int _hurd_stopped;
43 
44 /* Port that receives signals and other miscellaneous messages.  */
45 mach_port_t _hurd_msgport;
46 
47 /* Thread listening on it.  */
48 thread_t _hurd_msgport_thread;
49 
50 /* These are set up by _hurdsig_init.  */
51 unsigned long int __hurd_sigthread_stack_base;
52 unsigned long int __hurd_sigthread_stack_end;
53 
54 /* Linked-list of per-thread signal state.  */
55 struct hurd_sigstate *_hurd_sigstates;
56 
57 /* Sigstate for the task-global signals.  */
58 struct hurd_sigstate *_hurd_global_sigstate;
59 
60 /* Timeout for RPC's after interrupt_operation. */
61 mach_msg_timeout_t _hurd_interrupted_rpc_timeout = 60000;
62 
63 static void
default_sigaction(struct sigaction actions[NSIG])64 default_sigaction (struct sigaction actions[NSIG])
65 {
66   int signo;
67 
68   __sigemptyset (&actions[0].sa_mask);
69   actions[0].sa_flags = SA_RESTART;
70   actions[0].sa_handler = SIG_DFL;
71 
72   for (signo = 1; signo < NSIG; ++signo)
73     actions[signo] = actions[0];
74 }
75 
76 struct hurd_sigstate *
_hurd_thread_sigstate(thread_t thread)77 _hurd_thread_sigstate (thread_t thread)
78 {
79   struct hurd_sigstate *ss;
80   __mutex_lock (&_hurd_siglock);
81   for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
82     if (ss->thread == thread)
83        break;
84   if (ss == NULL)
85     {
86       ss = malloc (sizeof (*ss));
87       if (ss == NULL)
88 	__libc_fatal ("hurd: Can't allocate sigstate\n");
89       __spin_lock_init (&ss->critical_section_lock);
90       __spin_lock_init (&ss->lock);
91       ss->thread = thread;
92 
93       /* Initialize default state.  */
94       __sigemptyset (&ss->blocked);
95       __sigemptyset (&ss->pending);
96       memset (&ss->sigaltstack, 0, sizeof (ss->sigaltstack));
97       ss->sigaltstack.ss_flags |= SS_DISABLE;
98       ss->preemptors = NULL;
99       ss->suspended = MACH_PORT_NULL;
100       ss->intr_port = MACH_PORT_NULL;
101       ss->context = NULL;
102       ss->active_resources = NULL;
103       ss->cancel = 0;
104       ss->cancel_hook = NULL;
105 
106       if (thread == MACH_PORT_NULL)
107 	{
108 	  /* Process-wide sigstate, use the system defaults.  */
109 	  default_sigaction (ss->actions);
110 
111 	  /* The global sigstate is not added to the _hurd_sigstates list.
112 	     It is created with _hurd_thread_sigstate (MACH_PORT_NULL)
113 	     but should be accessed through _hurd_global_sigstate.  */
114 	}
115       else
116 	{
117 	  error_t err;
118 
119 	  /* Use the global actions as a default for new threads.  */
120 	  struct hurd_sigstate *s = _hurd_global_sigstate;
121 	  if (s)
122 	    {
123 	      __spin_lock (&s->lock);
124 	      memcpy (ss->actions, s->actions, sizeof (s->actions));
125 	      __spin_unlock (&s->lock);
126 	    }
127 	  else
128 	    default_sigaction (ss->actions);
129 
130 	  ss->next = _hurd_sigstates;
131 	  _hurd_sigstates = ss;
132 
133 	  err = __mach_port_mod_refs (__mach_task_self (), thread,
134 				      MACH_PORT_RIGHT_SEND, 1);
135 	  if (err)
136 	    __libc_fatal ("hurd: Can't add reference on Mach thread\n");
137 	}
138     }
139   __mutex_unlock (&_hurd_siglock);
140   return ss;
141 }
libc_hidden_def(_hurd_thread_sigstate)142 libc_hidden_def (_hurd_thread_sigstate)
143 
144 /* Destroy a sigstate structure.  Called by libpthread just before the
145  * corresponding thread is terminated.  */
146 void
147 _hurd_sigstate_delete (thread_t thread)
148 {
149   struct hurd_sigstate **ssp, *ss;
150 
151   __mutex_lock (&_hurd_siglock);
152   for (ssp = &_hurd_sigstates; *ssp; ssp = &(*ssp)->next)
153     if ((*ssp)->thread == thread)
154       break;
155 
156   ss = *ssp;
157   if (ss)
158     *ssp = ss->next;
159 
160   __mutex_unlock (&_hurd_siglock);
161   if (ss)
162     {
163       if (ss->thread != MACH_PORT_NULL)
164 	__mach_port_deallocate (__mach_task_self (), ss->thread);
165 
166       free (ss);
167     }
168 }
169 
170 /* Make SS a global receiver, with pthread signal semantics.  */
171 void
_hurd_sigstate_set_global_rcv(struct hurd_sigstate * ss)172 _hurd_sigstate_set_global_rcv (struct hurd_sigstate *ss)
173 {
174   assert (ss->thread != MACH_PORT_NULL);
175   ss->actions[0].sa_handler = SIG_IGN;
176 }
177 
178 /* Check whether SS is a global receiver.  */
179 static int
sigstate_is_global_rcv(const struct hurd_sigstate * ss)180 sigstate_is_global_rcv (const struct hurd_sigstate *ss)
181 {
182   return (_hurd_global_sigstate != NULL)
183 	 && (ss->actions[0].sa_handler == SIG_IGN);
184 }
libc_hidden_def(_hurd_sigstate_delete)185 libc_hidden_def (_hurd_sigstate_delete)
186 
187 /* Lock/unlock a hurd_sigstate structure.  If the accessors below require
188    it, the global sigstate will be locked as well.  */
189 void
190 _hurd_sigstate_lock (struct hurd_sigstate *ss)
191 {
192   if (sigstate_is_global_rcv (ss))
193     __spin_lock (&_hurd_global_sigstate->lock);
194   __spin_lock (&ss->lock);
195 }
196 void
_hurd_sigstate_unlock(struct hurd_sigstate * ss)197 _hurd_sigstate_unlock (struct hurd_sigstate *ss)
198 {
199   __spin_unlock (&ss->lock);
200   if (sigstate_is_global_rcv (ss))
201     __spin_unlock (&_hurd_global_sigstate->lock);
202 }
libc_hidden_def(_hurd_sigstate_set_global_rcv)203 libc_hidden_def (_hurd_sigstate_set_global_rcv)
204 
205 /* Retreive a thread's full set of pending signals, including the global
206    ones if appropriate.  SS must be locked.  */
207 sigset_t
208 _hurd_sigstate_pending (const struct hurd_sigstate *ss)
209 {
210   sigset_t pending = ss->pending;
211   if (sigstate_is_global_rcv (ss))
212     __sigorset (&pending, &pending, &_hurd_global_sigstate->pending);
213   return pending;
214 }
215 
216 /* Clear a pending signal and return the associated detailed
217    signal information. SS must be locked, and must have signal SIGNO
218    pending, either directly or through the global sigstate.  */
219 static struct hurd_signal_detail
sigstate_clear_pending(struct hurd_sigstate * ss,int signo)220 sigstate_clear_pending (struct hurd_sigstate *ss, int signo)
221 {
222   if (sigstate_is_global_rcv (ss)
223       && __sigismember (&_hurd_global_sigstate->pending, signo))
224     {
225       __sigdelset (&_hurd_global_sigstate->pending, signo);
226       return _hurd_global_sigstate->pending_data[signo];
227     }
228 
229   assert (__sigismember (&ss->pending, signo));
230   __sigdelset (&ss->pending, signo);
231   return ss->pending_data[signo];
232 }
233 libc_hidden_def (_hurd_sigstate_lock)
libc_hidden_def(_hurd_sigstate_unlock)234 libc_hidden_def (_hurd_sigstate_unlock)
235 
236 /* Retreive a thread's action vector.  SS must be locked.  */
237 struct sigaction *
238 _hurd_sigstate_actions (struct hurd_sigstate *ss)
239 {
240   if (sigstate_is_global_rcv (ss))
241     return _hurd_global_sigstate->actions;
242   else
243     return ss->actions;
244 }
libc_hidden_def(_hurd_sigstate_pending)245 libc_hidden_def (_hurd_sigstate_pending)
246 
247 
248 /* Signal delivery itself is on this page.  */
249 
250 #include <hurd/fd.h>
251 #include <hurd/crash.h>
252 #include <hurd/resource.h>
253 #include <hurd/paths.h>
254 #include <setjmp.h>
255 #include <fcntl.h>
256 #include <sys/wait.h>
257 #include <thread_state.h>
258 #include <hurd/msg_server.h>
259 #include <hurd/msg_reply.h>	/* For __msg_sig_post_reply.  */
260 #include <hurd/interrupt.h>
261 #include <assert.h>
262 #include <unistd.h>
263 
264 
265 /* Call the crash dump server to mummify us before we die.
266    Returns nonzero if a core file was written.  */
267 static int
268 write_corefile (int signo, const struct hurd_signal_detail *detail)
269 {
270   error_t err;
271   mach_port_t coreserver;
272   file_t file, coredir;
273   const char *name;
274 
275   /* Don't bother locking since we just read the one word.  */
276   rlim_t corelimit = _hurd_rlimits[RLIMIT_CORE].rlim_cur;
277 
278   if (corelimit == 0)
279     /* No core dumping, thank you very much.  Note that this makes
280        `ulimit -c 0' prevent crash-suspension too, which is probably
281        what the user wanted.  */
282     return 0;
283 
284   /* XXX RLIMIT_CORE:
285      When we have a protocol to make the server return an error
286      for RLIMIT_FSIZE, then tell the corefile fs server the RLIMIT_CORE
287      value in place of the RLIMIT_FSIZE value.  */
288 
289   /* First get a port to the core dumping server.  */
290   coreserver = MACH_PORT_NULL;
291   name = _hurdsig_getenv ("CRASHSERVER");
292   if (name != NULL)
293     coreserver = __file_name_lookup (name, 0, 0);
294   if (coreserver == MACH_PORT_NULL)
295     coreserver = __file_name_lookup (_SERVERS_CRASH, 0, 0);
296   if (coreserver == MACH_PORT_NULL)
297     return 0;
298 
299   /* Get a port to the directory where the new core file will reside.  */
300   file = MACH_PORT_NULL;
301   name = _hurdsig_getenv ("COREFILE");
302   if (name == NULL)
303     name = "core";
304   coredir = __file_name_split (name, (char **) &name);
305   if (coredir != MACH_PORT_NULL)
306     /* Create the new file, but don't link it into the directory yet.  */
307     __dir_mkfile (coredir, O_WRONLY|O_CREAT,
308 		  0600 & ~_hurd_umask, /* XXX ? */
309 		  &file);
310 
311   /* Call the core dumping server to write the core file.  */
312   err = __crash_dump_task (coreserver,
313 			   __mach_task_self (),
314 			   file,
315 			   signo, detail->code, detail->error,
316 			   detail->exc, detail->exc_code, detail->exc_subcode,
317 			   _hurd_ports[INIT_PORT_CTTYID].port,
318 			   MACH_MSG_TYPE_COPY_SEND);
319   __mach_port_deallocate (__mach_task_self (), coreserver);
320 
321   if (! err && file != MACH_PORT_NULL)
322     /* The core dump into FILE succeeded, so now link it into the
323        directory.  */
324     err = __dir_link (coredir, file, name, 1);
325   __mach_port_deallocate (__mach_task_self (), file);
326   __mach_port_deallocate (__mach_task_self (), coredir);
327   return !err && file != MACH_PORT_NULL;
328 }
329 
330 
331 /* The lowest-numbered thread state flavor value is 1,
332    so we use bit 0 in machine_thread_all_state.set to
333    record whether we have done thread_abort.  */
334 #define THREAD_ABORTED 1
335 
336 /* SS->thread is suspended.  Abort the thread and get its basic state.  */
337 static void
abort_thread(struct hurd_sigstate * ss,struct machine_thread_all_state * state,void (* reply)(void))338 abort_thread (struct hurd_sigstate *ss, struct machine_thread_all_state *state,
339 	      void (*reply) (void))
340 {
341   assert (ss->thread != MACH_PORT_NULL);
342 
343   if (!(state->set & THREAD_ABORTED))
344     {
345       error_t err = __thread_abort (ss->thread);
346       assert_perror (err);
347       /* Clear all thread state flavor set bits, because thread_abort may
348 	 have changed the state.  */
349       state->set = THREAD_ABORTED;
350     }
351 
352   if (reply)
353     (*reply) ();
354 
355   machine_get_basic_state (ss->thread, state);
356 }
357 
358 /* Find the location of the MiG reply port cell in use by the thread whose
359    state is described by THREAD_STATE.  If SIGTHREAD is nonzero, make sure
360    that this location can be set without faulting, or else return NULL.  */
361 
362 static mach_port_t *
interrupted_reply_port_location(thread_t thread,struct machine_thread_all_state * thread_state,int sigthread)363 interrupted_reply_port_location (thread_t thread,
364 				 struct machine_thread_all_state *thread_state,
365 				 int sigthread)
366 {
367   mach_port_t *portloc = &THREAD_TCB(thread, thread_state)->reply_port;
368 
369   if (sigthread && _hurdsig_catch_memory_fault (portloc))
370     /* Faulted trying to read the TCB.  */
371     return NULL;
372 
373   DIAG_PUSH_NEEDS_COMMENT;
374   /* GCC 6 and before seem to be confused by the setjmp call inside
375      _hurdsig_catch_memory_fault and think that we may be returning a second
376      time to here with portloc uninitialized (but we never do). */
377   DIAG_IGNORE_NEEDS_COMMENT (6, "-Wmaybe-uninitialized");
378   /* Fault now if this pointer is bogus.  */
379   *(volatile mach_port_t *) portloc = *portloc;
380   DIAG_POP_NEEDS_COMMENT;
381 
382   if (sigthread)
383     _hurdsig_end_catch_fault ();
384 
385   return portloc;
386 }
387 
388 #include <hurd/sigpreempt.h>
389 #include <intr-msg.h>
390 
391 /* Timeout on interrupt_operation calls.  */
392 mach_msg_timeout_t _hurdsig_interrupt_timeout = 1000;
393 
394 /* SS->thread is suspended.
395 
396    Abort any interruptible RPC operation the thread is doing.
397 
398    This uses only the constant member SS->thread and the unlocked, atomically
399    set member SS->intr_port, so no locking is needed.
400 
401    If successfully sent an interrupt_operation and therefore the thread should
402    wait for its pending RPC to return (possibly EINTR) before taking the
403    incoming signal, returns the reply port to be received on.  Otherwise
404    returns MACH_PORT_NULL.
405 
406    SIGNO is used to find the applicable SA_RESTART bit.  If SIGNO is zero,
407    the RPC fails with EINTR instead of restarting (thread_cancel).
408 
409    *STATE_CHANGE is set nonzero if STATE->basic was modified and should
410    be applied back to the thread if it might ever run again, else zero.  */
411 
412 mach_port_t
_hurdsig_abort_rpcs(struct hurd_sigstate * ss,int signo,int sigthread,struct machine_thread_all_state * state,int * state_change,void (* reply)(void))413 _hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, int sigthread,
414 		     struct machine_thread_all_state *state, int *state_change,
415 		     void (*reply) (void))
416 {
417   extern const void _hurd_intr_rpc_msg_about_to;
418   extern const void _hurd_intr_rpc_msg_in_trap;
419   mach_port_t rcv_port = MACH_PORT_NULL;
420   mach_port_t intr_port;
421 
422   *state_change = 0;
423 
424   intr_port = ss->intr_port;
425   if (intr_port == MACH_PORT_NULL)
426     /* No interruption needs done.  */
427     return MACH_PORT_NULL;
428 
429   /* Abort the thread's kernel context, so any pending message send or
430      receive completes immediately or aborts.  */
431   abort_thread (ss, state, reply);
432 
433   if (state->basic.PC >= (natural_t) &_hurd_intr_rpc_msg_about_to
434       && state->basic.PC < (natural_t) &_hurd_intr_rpc_msg_in_trap)
435     {
436       /* The thread is about to do the RPC, but hasn't yet entered
437 	 mach_msg.  Mutate the thread's state so it knows not to try
438 	 the RPC.  */
439       INTR_MSG_BACK_OUT (&state->basic);
440       MACHINE_THREAD_STATE_SET_PC (&state->basic,
441 				   &_hurd_intr_rpc_msg_in_trap);
442       state->basic.SYSRETURN = MACH_SEND_INTERRUPTED;
443       *state_change = 1;
444     }
445   else if (state->basic.PC == (natural_t) &_hurd_intr_rpc_msg_in_trap
446 	   /* The thread was blocked in the system call.  After thread_abort,
447 	      the return value register indicates what state the RPC was in
448 	      when interrupted.  */
449 	   && state->basic.SYSRETURN == MACH_RCV_INTERRUPTED)
450       {
451 	/* The RPC request message was sent and the thread was waiting for
452 	   the reply message; now the message receive has been aborted, so
453 	   the mach_msg call will return MACH_RCV_INTERRUPTED.  We must tell
454 	   the server to interrupt the pending operation.  The thread must
455 	   wait for the reply message before running the signal handler (to
456 	   guarantee that the operation has finished being interrupted), so
457 	   our nonzero return tells the trampoline code to finish the message
458 	   receive operation before running the handler.  */
459 
460 	mach_port_t *reply = interrupted_reply_port_location (ss->thread,
461 							      state,
462 							      sigthread);
463 	error_t err = __interrupt_operation (intr_port, _hurdsig_interrupt_timeout);
464 
465 	if (err)
466 	  {
467 	    if (reply)
468 	      {
469 		/* The interrupt didn't work.
470 		   Destroy the receive right the thread is blocked on.  */
471 		__mach_port_destroy (__mach_task_self (), *reply);
472 		*reply = MACH_PORT_NULL;
473 	      }
474 
475 	    /* The system call return value register now contains
476 	       MACH_RCV_INTERRUPTED; when mach_msg resumes, it will retry the
477 	       call.  Since we have just destroyed the receive right, the
478 	       retry will fail with MACH_RCV_INVALID_NAME.  Instead, just
479 	       change the return value here to EINTR so mach_msg will not
480 	       retry and the EINTR error code will propagate up.  */
481 	    state->basic.SYSRETURN = EINTR;
482 	    *state_change = 1;
483 	  }
484 	else if (reply)
485 	  rcv_port = *reply;
486 
487 	/* All threads whose RPCs were interrupted by the interrupt_operation
488 	   call above will retry their RPCs unless we clear SS->intr_port.
489 	   So we clear it for the thread taking a signal when SA_RESTART is
490 	   clear, so that its call returns EINTR.  */
491 	if (! signo || !(_hurd_sigstate_actions (ss) [signo].sa_flags & SA_RESTART))
492 	  ss->intr_port = MACH_PORT_NULL;
493       }
494 
495   return rcv_port;
496 }
497 
498 
499 /* Abort the RPCs being run by all threads but this one;
500    all other threads should be suspended.  If LIVE is nonzero, those
501    threads may run again, so they should be adjusted as necessary to be
502    happy when resumed.  STATE is clobbered as a scratch area; its initial
503    contents are ignored, and its contents on return are not useful.  */
504 
505 static void
abort_all_rpcs(int signo,struct machine_thread_all_state * state,int live)506 abort_all_rpcs (int signo, struct machine_thread_all_state *state, int live)
507 {
508   /* We can just loop over the sigstates.  Any thread doing something
509      interruptible must have one.  We needn't bother locking because all
510      other threads are stopped.  */
511 
512   struct hurd_sigstate *ss;
513   size_t nthreads;
514   mach_port_t *reply_ports;
515 
516   /* First loop over the sigstates to count them.
517      We need to know how big a vector we will need for REPLY_PORTS.  */
518   nthreads = 0;
519   for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
520     ++nthreads;
521 
522   reply_ports = alloca (nthreads * sizeof *reply_ports);
523 
524   nthreads = 0;
525   for (ss = _hurd_sigstates; ss != NULL; ss = ss->next, ++nthreads)
526     if (ss->thread == _hurd_msgport_thread)
527       reply_ports[nthreads] = MACH_PORT_NULL;
528     else
529       {
530 	int state_changed;
531 	state->set = 0;		/* Reset scratch area.  */
532 
533 	/* Abort any operation in progress with interrupt_operation.
534 	   Record the reply port the thread is waiting on.
535 	   We will wait for all the replies below.  */
536 	reply_ports[nthreads] = _hurdsig_abort_rpcs (ss, signo, 1,
537 						     state, &state_changed,
538 						     NULL);
539 	if (live)
540 	  {
541 	    if (reply_ports[nthreads] != MACH_PORT_NULL)
542 	      {
543 		/* We will wait for the reply to this RPC below, so the
544 		   thread must issue a new RPC rather than waiting for the
545 		   reply to the one it sent.  */
546 		state->basic.SYSRETURN = EINTR;
547 		state_changed = 1;
548 	      }
549 	    if (state_changed)
550 	      /* Aborting the RPC needed to change this thread's state,
551 		 and it might ever run again.  So write back its state.  */
552 	      __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR,
553 				  (natural_t *) &state->basic,
554 				  MACHINE_THREAD_STATE_COUNT);
555 	  }
556       }
557 
558   /* Wait for replies from all the successfully interrupted RPCs.  */
559   while (nthreads-- > 0)
560     if (reply_ports[nthreads] != MACH_PORT_NULL)
561       {
562 	error_t err;
563 	mach_msg_header_t head;
564 	err = __mach_msg (&head, MACH_RCV_MSG|MACH_RCV_TIMEOUT, 0, sizeof head,
565 			  reply_ports[nthreads],
566 			  _hurd_interrupted_rpc_timeout, MACH_PORT_NULL);
567 	switch (err)
568 	  {
569 	  case MACH_RCV_TIMED_OUT:
570 	  case MACH_RCV_TOO_LARGE:
571 	    break;
572 
573 	  default:
574 	    assert_perror (err);
575 	  }
576       }
577 }
578 
579 /* Wake up any sigsuspend or pselect call that is blocking SS->thread.  SS must
580    be locked.  */
581 static void
wake_sigsuspend(struct hurd_sigstate * ss)582 wake_sigsuspend (struct hurd_sigstate *ss)
583 {
584   error_t err;
585   mach_msg_header_t msg;
586 
587   if (ss->suspended == MACH_PORT_NULL)
588     return;
589 
590   /* There is a sigsuspend waiting.  Tell it to wake up.  */
591   msg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_MAKE_SEND, 0);
592   msg.msgh_remote_port = ss->suspended;
593   msg.msgh_local_port = MACH_PORT_NULL;
594   /* These values do not matter.  */
595   msg.msgh_id = 8675309; /* Jenny, Jenny.  */
596   ss->suspended = MACH_PORT_NULL;
597   err = __mach_msg (&msg, MACH_SEND_MSG, sizeof msg, 0,
598       MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
599       MACH_PORT_NULL);
600   assert_perror (err);
601 }
602 
603 struct hurd_signal_preemptor *_hurdsig_preemptors = 0;
604 sigset_t _hurdsig_preempted_set;
605 
606 /* XXX temporary to deal with spelling fix */
weak_alias(_hurdsig_preemptors,_hurdsig_preempters)607 weak_alias (_hurdsig_preemptors, _hurdsig_preempters)
608 
609 /* Mask of stop signals.  */
610 #define STOPSIGS (__sigmask (SIGTTIN) | __sigmask (SIGTTOU) \
611 		  | __sigmask (SIGSTOP) | __sigmask (SIGTSTP))
612 
613 /* Actual delivery of a single signal.  Called with SS unlocked.  When
614    the signal is delivered, return SS, locked (or, if SS was originally
615    _hurd_global_sigstate, the sigstate of the actual thread the signal
616    was delivered to).  If the signal is being traced, return NULL with
617    SS unlocked.   */
618 static struct hurd_sigstate *
619 post_signal (struct hurd_sigstate *ss,
620 	     int signo, struct hurd_signal_detail *detail,
621 	     int untraced, void (*reply) (void))
622 {
623   struct machine_thread_all_state thread_state;
624   enum { stop, ignore, core, term, handle } act;
625   int ss_suspended;
626 
627   /* sigaction for preemptors */
628   struct sigaction preempt_sigaction = {
629     .sa_flags = SA_RESTART
630   };
631 
632   struct sigaction *action;
633 
634   /* Mark the signal as pending.  */
635   void mark_pending (void)
636     {
637       __sigaddset (&ss->pending, signo);
638       /* Save the details to be given to the handler when SIGNO is
639 	 unblocked.  */
640       ss->pending_data[signo] = *detail;
641     }
642 
643   /* Suspend the process with SIGNO.  */
644   void suspend (void)
645     {
646       /* Stop all other threads and mark ourselves stopped.  */
647       __USEPORT (PROC,
648 		 ({
649 		   /* Hold the siglock while stopping other threads to be
650 		      sure it is not held by another thread afterwards.  */
651 		   __mutex_lock (&_hurd_siglock);
652 		   __proc_dostop (port, _hurd_msgport_thread);
653 		   __mutex_unlock (&_hurd_siglock);
654 		   abort_all_rpcs (signo, &thread_state, 1);
655 		   reply ();
656 		   __proc_mark_stop (port, signo, detail->code);
657 		 }));
658       _hurd_stopped = 1;
659     }
660   /* Resume the process after a suspension.  */
661   void resume (void)
662     {
663       /* Resume the process from being stopped.  */
664       thread_t *threads;
665       mach_msg_type_number_t nthreads, i;
666       error_t err;
667 
668       if (! _hurd_stopped)
669 	return;
670 
671       /* Tell the proc server we are continuing.  */
672       __USEPORT (PROC, __proc_mark_cont (port));
673       /* Fetch ports to all our threads and resume them.  */
674       err = __task_threads (__mach_task_self (), &threads, &nthreads);
675       assert_perror (err);
676       for (i = 0; i < nthreads; ++i)
677 	{
678 	  if (act == handle && threads[i] == ss->thread)
679 	    {
680 	      /* The thread that will run the handler is kept suspended.  */
681 	      ss_suspended = 1;
682 	    }
683 	  else if (threads[i] != _hurd_msgport_thread)
684 	    {
685 	      err = __thread_resume (threads[i]);
686 	      assert_perror (err);
687 	    }
688 	  err = __mach_port_deallocate (__mach_task_self (),
689 					threads[i]);
690 	  assert_perror (err);
691 	}
692       __vm_deallocate (__mach_task_self (),
693 		       (vm_address_t) threads,
694 		       nthreads * sizeof *threads);
695       _hurd_stopped = 0;
696     }
697 
698   error_t err;
699   sighandler_t handler;
700 
701   if (signo == 0)
702     {
703       if (untraced)
704 	{
705 	  /* This is PTRACE_CONTINUE.  */
706 	  act = ignore;
707 	  resume ();
708 	}
709 
710       /* This call is just to check for pending signals.  */
711       _hurd_sigstate_lock (ss);
712       return ss;
713     }
714 
715   thread_state.set = 0;		/* We know nothing.  */
716 
717   _hurd_sigstate_lock (ss);
718 
719   /* If this is a global signal, try to find a thread ready to accept
720      it right away.  This is especially important for untraced signals,
721      since going through the global pending mask would de-untrace them.  */
722   if (ss->thread == MACH_PORT_NULL)
723   {
724     struct hurd_sigstate *rss;
725 
726     __mutex_lock (&_hurd_siglock);
727     for (rss = _hurd_sigstates; rss != NULL; rss = rss->next)
728       {
729 	if (! sigstate_is_global_rcv (rss))
730 	  continue;
731 
732 	/* The global sigstate is already locked.  */
733 	__spin_lock (&rss->lock);
734 	if (! __sigismember (&rss->blocked, signo))
735 	  {
736 	    ss = rss;
737 	    break;
738 	  }
739 	__spin_unlock (&rss->lock);
740       }
741     __mutex_unlock (&_hurd_siglock);
742   }
743 
744   /* We want the preemptors to be able to update the blocking mask
745      without affecting the delivery of this signal, so we save the
746      current value to test against later.  */
747   sigset_t blocked = ss->blocked;
748 
749   /* Check for a preempted signal.  Preempted signals can arrive during
750      critical sections.  */
751   {
752     inline sighandler_t try_preemptor (struct hurd_signal_preemptor *pe)
753       {				/* PE cannot be null.  */
754 	do
755 	  {
756 	    if (HURD_PREEMPT_SIGNAL_P (pe, signo, detail->exc_subcode))
757 	      {
758 		if (pe->preemptor)
759 		  {
760 		    sighandler_t handler = (*pe->preemptor) (pe, ss,
761 							     &signo, detail);
762 		    if (handler != SIG_ERR)
763 		      return handler;
764 		  }
765 		else
766 		  return pe->handler;
767 	      }
768 	    pe = pe->next;
769 	  } while (pe != 0);
770 	return SIG_ERR;
771       }
772 
773     handler = ss->preemptors ? try_preemptor (ss->preemptors) : SIG_ERR;
774 
775     /* If no thread-specific preemptor, check for a global one.  */
776     if (handler == SIG_ERR && __sigismember (&_hurdsig_preempted_set, signo))
777       {
778 	__mutex_lock (&_hurd_siglock);
779 	handler = try_preemptor (_hurdsig_preemptors);
780 	__mutex_unlock (&_hurd_siglock);
781       }
782   }
783 
784   ss_suspended = 0;
785 
786   if (handler == SIG_IGN)
787     /* Ignore the signal altogether.  */
788     act = ignore;
789   else if (handler != SIG_ERR)
790     {
791       /* Run the preemption-provided handler.  */
792       action = &preempt_sigaction;
793       act = handle;
794     }
795   else
796     {
797       /* No preemption.  Do normal handling.  */
798 
799       action = & _hurd_sigstate_actions (ss) [signo];
800 
801       if (!untraced && __sigismember (&_hurdsig_traced, signo))
802 	{
803 	  /* We are being traced.  Stop to tell the debugger of the signal.  */
804 	  if (_hurd_stopped)
805 	    /* Already stopped.  Mark the signal as pending;
806 	       when resumed, we will notice it and stop again.  */
807 	    mark_pending ();
808 	  else
809 	    suspend ();
810 	  _hurd_sigstate_unlock (ss);
811 	  reply ();
812 	  return NULL;
813 	}
814 
815       handler = action->sa_handler;
816 
817       if (handler == SIG_DFL)
818 	/* Figure out the default action for this signal.  */
819 	switch (signo)
820 	  {
821 	  case 0:
822 	    /* A sig_post msg with SIGNO==0 is sent to
823 	       tell us to check for pending signals.  */
824 	    act = ignore;
825 	    break;
826 
827 	  case SIGTTIN:
828 	  case SIGTTOU:
829 	  case SIGSTOP:
830 	  case SIGTSTP:
831 	    act = stop;
832 	    break;
833 
834 	  case SIGCONT:
835 	  case SIGIO:
836 	  case SIGURG:
837 	  case SIGCHLD:
838 	  case SIGWINCH:
839 	    act = ignore;
840 	    break;
841 
842 	  case SIGQUIT:
843 	  case SIGILL:
844 	  case SIGTRAP:
845 	  case SIGIOT:
846 	  case SIGEMT:
847 	  case SIGFPE:
848 	  case SIGBUS:
849 	  case SIGSEGV:
850 	  case SIGSYS:
851 	    act = core;
852 	    break;
853 
854 	  case SIGINFO:
855 	    if (_hurd_pgrp == _hurd_pid)
856 	      {
857 		/* We are the process group leader.  Since there is no
858 		   user-specified handler for SIGINFO, we use a default one
859 		   which prints something interesting.  We use the normal
860 		   handler mechanism instead of just doing it here to avoid
861 		   the signal thread faulting or blocking in this
862 		   potentially hairy operation.  */
863 		act = handle;
864 		handler = _hurd_siginfo_handler;
865 	      }
866 	    else
867 	      act = ignore;
868 	    break;
869 
870 	  default:
871 	    act = term;
872 	    break;
873 	  }
874       else if (handler == SIG_IGN)
875 	act = ignore;
876       else
877 	act = handle;
878 
879       if (__sigmask (signo) & STOPSIGS)
880 	/* Stop signals clear a pending SIGCONT even if they
881 	   are handled or ignored (but not if preempted).  */
882 	__sigdelset (&ss->pending, SIGCONT);
883       else
884 	{
885 	  if (signo == SIGCONT)
886 	    /* Even if handled or ignored (but not preempted), SIGCONT clears
887 	       stop signals and resumes the process.  */
888 	    ss->pending &= ~STOPSIGS;
889 
890 	  if (_hurd_stopped && act != stop && (untraced || signo == SIGCONT))
891 	    resume ();
892 	}
893     }
894 
895   if (_hurd_orphaned && act == stop
896       && (__sigmask (signo) & (__sigmask (SIGTTIN) | __sigmask (SIGTTOU)
897 			       | __sigmask (SIGTSTP))))
898     {
899       /* If we would ordinarily stop for a job control signal, but we are
900 	 orphaned so noone would ever notice and continue us again, we just
901 	 quietly die, alone and in the dark.  */
902       detail->code = signo;
903       signo = SIGKILL;
904       act = term;
905     }
906 
907   /* Handle receipt of a blocked signal, or any signal while stopped.  */
908   if (__sigismember (&blocked, signo) || (signo != SIGKILL && _hurd_stopped))
909     {
910       mark_pending ();
911       act = ignore;
912     }
913 
914   /* Perform the chosen action for the signal.  */
915   switch (act)
916     {
917     case stop:
918       if (_hurd_stopped)
919 	{
920 	  /* We are already stopped, but receiving an untraced stop
921 	     signal.  Instead of resuming and suspending again, just
922 	     notify the proc server of the new stop signal.  */
923 	  error_t err = __USEPORT (PROC, __proc_mark_stop
924 				   (port, signo, detail->code));
925 	  assert_perror (err);
926 	}
927       else
928 	/* Suspend the process.  */
929 	suspend ();
930       break;
931 
932     case ignore:
933       if (detail->exc)
934 	/* Blocking or ignoring a machine exception is fatal.
935 	   Otherwise we could just spin on the faulting instruction.  */
936 	goto fatal;
937 
938       /* Nobody cares about this signal.  If there was a call to resume
939 	 above in SIGCONT processing and we've left a thread suspended,
940 	 now's the time to set it going. */
941       if (ss_suspended)
942 	{
943 	  assert (ss->thread != MACH_PORT_NULL);
944 	  err = __thread_resume (ss->thread);
945 	  assert_perror (err);
946 	  ss_suspended = 0;
947 	}
948       break;
949 
950     sigbomb:
951       /* We got a fault setting up the stack frame for the handler.
952 	 Nothing to do but die; BSD gets SIGILL in this case.  */
953       detail->code = signo;	/* XXX ? */
954       signo = SIGILL;
955 
956     fatal:
957       act = core;
958       /* FALLTHROUGH */
959 
960     case term:			/* Time to die.  */
961     case core:			/* And leave a rotting corpse.  */
962       /* Have the proc server stop all other threads in our task.  */
963       err = __USEPORT (PROC, __proc_dostop (port, _hurd_msgport_thread));
964       assert_perror (err);
965       /* No more user instructions will be executed.
966 	 The signal can now be considered delivered.  */
967       reply ();
968       /* Abort all server operations now in progress.  */
969       abort_all_rpcs (signo, &thread_state, 0);
970 
971       {
972 	int status = W_EXITCODE (0, signo);
973 	/* Do a core dump if desired.  Only set the wait status bit saying we
974 	   in fact dumped core if the operation was actually successful.  */
975 	if (act == core && write_corefile (signo, detail))
976 	  status |= WCOREFLAG;
977 	/* Tell proc how we died and then stick the saber in the gut.  */
978 	_hurd_exit (status);
979 	/* NOTREACHED */
980       }
981 
982     case handle:
983       /* Call a handler for this signal.  */
984       {
985 	struct sigcontext *scp, ocontext;
986 	int wait_for_reply, state_changed;
987 
988 	assert (ss->thread != MACH_PORT_NULL);
989 
990 	/* Stop the thread and abort its pending RPC operations.  */
991 	if (! ss_suspended)
992 	  {
993 	    err = __thread_suspend (ss->thread);
994 	    assert_perror (err);
995 	  }
996 
997 	/* Abort the thread's kernel context, so any pending message send
998 	   or receive completes immediately or aborts.  If an interruptible
999 	   RPC is in progress, abort_rpcs will do this.  But we must always
1000 	   do it before fetching the thread's state, because
1001 	   thread_get_state is never kosher before thread_abort.  */
1002 	abort_thread (ss, &thread_state, NULL);
1003 
1004 	if (ss->context)
1005 	  {
1006 	    /* We have a previous sigcontext that sigreturn was about
1007 	       to restore when another signal arrived.  */
1008 
1009 	    mach_port_t *loc;
1010 
1011 	    if (_hurdsig_catch_memory_fault (ss->context))
1012 	      {
1013 		/* We faulted reading the thread's stack.  Forget that
1014 		   context and pretend it wasn't there.  It almost
1015 		   certainly crash if this handler returns, but that's it's
1016 		   problem.  */
1017 		ss->context = NULL;
1018 	      }
1019 	    else
1020 	      {
1021 		/* Copy the context from the thread's stack before
1022 		   we start diddling the stack to set up the handler.  */
1023 		ocontext = *ss->context;
1024 		ss->context = &ocontext;
1025 	      }
1026 	    _hurdsig_end_catch_fault ();
1027 
1028 	    if (! machine_get_basic_state (ss->thread, &thread_state))
1029 	      goto sigbomb;
1030 	    loc = interrupted_reply_port_location (ss->thread,
1031 						   &thread_state, 1);
1032 	    if (loc && *loc != MACH_PORT_NULL)
1033 	      /* This is the reply port for the context which called
1034 		 sigreturn.  Since we are abandoning that context entirely
1035 		 and restoring SS->context instead, destroy this port.  */
1036 	      __mach_port_destroy (__mach_task_self (), *loc);
1037 
1038 	    /* The thread was in sigreturn, not in any interruptible RPC.  */
1039 	    wait_for_reply = 0;
1040 
1041 	    assert (! __spin_lock_locked (&ss->critical_section_lock));
1042 	  }
1043 	else
1044 	  {
1045 	    int crit = __spin_lock_locked (&ss->critical_section_lock);
1046 
1047 	    wait_for_reply
1048 	      = (_hurdsig_abort_rpcs (ss,
1049 				      /* In a critical section, any RPC
1050 					 should be cancelled instead of
1051 					 restarted, regardless of
1052 					 SA_RESTART, so the entire
1053 					 "atomic" operation can be aborted
1054 					 as a unit.  */
1055 				      crit ? 0 : signo, 1,
1056 				      &thread_state, &state_changed,
1057 				      reply)
1058 		 != MACH_PORT_NULL);
1059 
1060 	    if (crit)
1061 	      {
1062 		/* The thread is in a critical section.  Mark the signal as
1063 		   pending.  When it finishes the critical section, it will
1064 		   check for pending signals.  */
1065 		mark_pending ();
1066 		if (state_changed)
1067 		  /* Some cases of interrupting an RPC must change the
1068 		     thread state to back out the call.  Normally this
1069 		     change is rolled into the warping to the handler and
1070 		     sigreturn, but we are not running the handler now
1071 		     because the thread is in a critical section.  Instead,
1072 		     mutate the thread right away for the RPC interruption
1073 		     and resume it; the RPC will return early so the
1074 		     critical section can end soon.  */
1075 		  __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR,
1076 				      (natural_t *) &thread_state.basic,
1077 				      MACHINE_THREAD_STATE_COUNT);
1078 		/* */
1079 		ss->intr_port = MACH_PORT_NULL;
1080 		__thread_resume (ss->thread);
1081 		break;
1082 	      }
1083 	  }
1084 
1085 	/* Call the machine-dependent function to set the thread up
1086 	   to run the signal handler, and preserve its old context.  */
1087 	scp = _hurd_setup_sighandler (ss, action, handler, signo, detail,
1088 				      wait_for_reply, &thread_state);
1089 	if (scp == NULL)
1090 	  goto sigbomb;
1091 
1092 	/* Set the machine-independent parts of the signal context.  */
1093 
1094 	{
1095 	  /* Fetch the thread variable for the MiG reply port,
1096 	     and set it to MACH_PORT_NULL.  */
1097 	  mach_port_t *loc = interrupted_reply_port_location (ss->thread,
1098 							      &thread_state,
1099 							      1);
1100 	  if (loc)
1101 	    {
1102 	      scp->sc_reply_port = *loc;
1103 	      *loc = MACH_PORT_NULL;
1104 	    }
1105 	  else
1106 	    scp->sc_reply_port = MACH_PORT_NULL;
1107 
1108 	  /* Save the intr_port in use by the interrupted code,
1109 	     and clear the cell before running the trampoline.  */
1110 	  scp->sc_intr_port = ss->intr_port;
1111 	  ss->intr_port = MACH_PORT_NULL;
1112 
1113 	  if (ss->context)
1114 	    {
1115 	      /* After the handler runs we will restore to the state in
1116 		 SS->context, not the state of the thread now.  So restore
1117 		 that context's reply port and intr port.  */
1118 
1119 	      scp->sc_reply_port = ss->context->sc_reply_port;
1120 	      scp->sc_intr_port = ss->context->sc_intr_port;
1121 
1122 	      ss->context = NULL;
1123 	    }
1124 	}
1125 
1126 	/* Backdoor extra argument to signal handler.  */
1127 	scp->sc_error = detail->error;
1128 
1129 	/* Block requested signals while running the handler.  */
1130 	scp->sc_mask = ss->blocked;
1131 	__sigorset (&ss->blocked, &ss->blocked, &action->sa_mask);
1132 
1133 	/* Also block SIGNO unless we're asked not to.  */
1134 	if (! (action->sa_flags & (SA_RESETHAND | SA_NODEFER)))
1135 	  __sigaddset (&ss->blocked, signo);
1136 
1137 	/* Reset to SIG_DFL if requested.  SIGILL and SIGTRAP cannot
1138            be automatically reset when delivered; the system silently
1139            enforces this restriction.  */
1140 	if (action->sa_flags & SA_RESETHAND
1141 	    && signo != SIGILL && signo != SIGTRAP)
1142 	  action->sa_handler = SIG_DFL;
1143 
1144 	/* Any sigsuspend call must return after the handler does.  */
1145 	wake_sigsuspend (ss);
1146 
1147 	/* Start the thread running the handler (or possibly waiting for an
1148 	   RPC reply before running the handler).  */
1149 	err = __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR,
1150 				  (natural_t *) &thread_state.basic,
1151 				  MACHINE_THREAD_STATE_COUNT);
1152 	assert_perror (err);
1153 	err = __thread_resume (ss->thread);
1154 	assert_perror (err);
1155 	thread_state.set = 0;	/* Everything we know is now wrong.  */
1156 	break;
1157       }
1158     }
1159 
1160   return ss;
1161 }
1162 
1163 /* Return the set of pending signals in SS which should be delivered. */
1164 static sigset_t
pending_signals(struct hurd_sigstate * ss)1165 pending_signals (struct hurd_sigstate *ss)
1166 {
1167   /* We don't worry about any pending signals if we are stopped, nor if
1168      SS is in a critical section.  We are guaranteed to get a sig_post
1169      message before any of them become deliverable: either the SIGCONT
1170      signal, or a sig_post with SIGNO==0 as an explicit poll when the
1171      thread finishes its critical section.  */
1172   if (_hurd_stopped || __spin_lock_locked (&ss->critical_section_lock))
1173     return 0;
1174 
1175   return _hurd_sigstate_pending (ss) & ~ss->blocked;
1176 }
1177 
1178 /* Post the specified pending signals in SS and return 1.  If one of
1179    them is traced, abort immediately and return 0.  SS must be locked on
1180    entry and will be unlocked in all cases.  */
1181 static int
post_pending(struct hurd_sigstate * ss,sigset_t pending,void (* reply)(void))1182 post_pending (struct hurd_sigstate *ss, sigset_t pending, void (*reply) (void))
1183 {
1184   int signo;
1185   struct hurd_signal_detail detail;
1186 
1187   /* Make sure SS corresponds to an actual thread, since we assume it won't
1188      change in post_signal. */
1189   assert (ss->thread != MACH_PORT_NULL);
1190 
1191   for (signo = 1; signo < NSIG; ++signo)
1192     if (__sigismember (&pending, signo))
1193       {
1194 	detail = sigstate_clear_pending (ss, signo);
1195 	_hurd_sigstate_unlock (ss);
1196 
1197 	/* Will reacquire the lock, except if the signal is traced.  */
1198 	if (! post_signal (ss, signo, &detail, 0, reply))
1199 	  return 0;
1200       }
1201 
1202   /* No more signals pending; SS->lock is still locked.  */
1203   _hurd_sigstate_unlock (ss);
1204 
1205   return 1;
1206 }
1207 
1208 /* Post all the pending signals of all threads and return 1.  If a traced
1209    signal is encountered, abort immediately and return 0.  */
1210 static int
post_all_pending_signals(void (* reply)(void))1211 post_all_pending_signals (void (*reply) (void))
1212 {
1213   struct hurd_sigstate *ss;
1214   sigset_t pending = 0;
1215 
1216   for (;;)
1217     {
1218       __mutex_lock (&_hurd_siglock);
1219       for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
1220         {
1221 	  _hurd_sigstate_lock (ss);
1222 
1223 	  pending = pending_signals (ss);
1224 	  if (pending)
1225 	    /* post_pending() below will unlock SS. */
1226 	    break;
1227 
1228 	  _hurd_sigstate_unlock (ss);
1229 	}
1230       __mutex_unlock (&_hurd_siglock);
1231 
1232       if (! pending)
1233 	return 1;
1234       if (! post_pending (ss, pending, reply))
1235 	return 0;
1236     }
1237 }
1238 
1239 /* Deliver a signal.  SS is not locked.  */
1240 void
_hurd_internal_post_signal(struct hurd_sigstate * ss,int signo,struct hurd_signal_detail * detail,mach_port_t reply_port,mach_msg_type_name_t reply_port_type,int untraced)1241 _hurd_internal_post_signal (struct hurd_sigstate *ss,
1242 			    int signo, struct hurd_signal_detail *detail,
1243 			    mach_port_t reply_port,
1244 			    mach_msg_type_name_t reply_port_type,
1245 			    int untraced)
1246 {
1247   /* Reply to this sig_post message.  */
1248   __typeof (__msg_sig_post_reply) *reply_rpc
1249     = (untraced ? __msg_sig_post_untraced_reply : __msg_sig_post_reply);
1250   void reply (void)
1251     {
1252       error_t err;
1253       if (reply_port == MACH_PORT_NULL)
1254 	return;
1255       err = (*reply_rpc) (reply_port, reply_port_type, 0);
1256       reply_port = MACH_PORT_NULL;
1257       if (err != MACH_SEND_INVALID_DEST) /* Ignore dead reply port.  */
1258 	assert_perror (err);
1259     }
1260 
1261   ss = post_signal (ss, signo, detail, untraced, reply);
1262   if (! ss)
1263     return;
1264 
1265   /* The signal was neither fatal nor traced.  We still hold SS->lock.  */
1266   if (signo != 0 && ss->thread != MACH_PORT_NULL)
1267     {
1268       /* The signal has either been ignored or is now being handled.  We can
1269 	 consider it delivered and reply to the killer.  */
1270       reply ();
1271 
1272       /* Post any pending signals for this thread.  */
1273       if (! post_pending (ss, pending_signals (ss), reply))
1274 	return;
1275     }
1276   else
1277     {
1278       /* If this was a process-wide signal or a poll request, we need
1279 	 to check for pending signals for all threads.  */
1280       _hurd_sigstate_unlock (ss);
1281       if (! post_all_pending_signals (reply))
1282 	return;
1283 
1284       /* All pending signals delivered to all threads.
1285 	 Now we can send the reply message even for signal 0.  */
1286       reply ();
1287     }
1288 }
1289 
1290 /* Decide whether REFPORT enables the sender to send us a SIGNO signal.
1291    Returns zero if so, otherwise the error code to return to the sender.  */
1292 
1293 static error_t
signal_allowed(int signo,mach_port_t refport)1294 signal_allowed (int signo, mach_port_t refport)
1295 {
1296   if (signo < 0 || signo >= NSIG)
1297     return EINVAL;
1298 
1299   if (refport == __mach_task_self ())
1300     /* Can send any signal.  */
1301     goto win;
1302 
1303   /* Avoid needing to check for this below.  */
1304   if (refport == MACH_PORT_NULL)
1305     return EPERM;
1306 
1307   switch (signo)
1308     {
1309     case SIGINT:
1310     case SIGQUIT:
1311     case SIGTSTP:
1312     case SIGHUP:
1313     case SIGINFO:
1314     case SIGTTIN:
1315     case SIGTTOU:
1316     case SIGWINCH:
1317       /* Job control signals can be sent by the controlling terminal.  */
1318       if (__USEPORT (CTTYID, port == refport))
1319 	goto win;
1320       break;
1321 
1322     case SIGCONT:
1323       {
1324 	/* A continue signal can be sent by anyone in the session.  */
1325 	mach_port_t sessport;
1326 	if (! __USEPORT (PROC, __proc_getsidport (port, &sessport)))
1327 	  {
1328 	    __mach_port_deallocate (__mach_task_self (), sessport);
1329 	    if (refport == sessport)
1330 	      goto win;
1331 	  }
1332       }
1333       break;
1334 
1335     case SIGIO:
1336     case SIGURG:
1337       {
1338 	/* Any io object a file descriptor refers to might send us
1339 	   one of these signals using its async ID port for REFPORT.
1340 
1341 	   This is pretty wide open; it is not unlikely that some random
1342 	   process can at least open for reading something we have open,
1343 	   get its async ID port, and send us a spurious SIGIO or SIGURG
1344 	   signal.  But BSD is actually wider open than that!--you can set
1345 	   the owner of an io object to any process or process group
1346 	   whatsoever and send them gratuitous signals.
1347 
1348 	   Someday we could implement some reasonable scheme for
1349 	   authorizing SIGIO and SIGURG signals properly.  */
1350 
1351 	int d;
1352 	int lucky = 0;		/* True if we find a match for REFPORT.  */
1353 	__mutex_lock (&_hurd_dtable_lock);
1354 	for (d = 0; !lucky && (unsigned) d < (unsigned) _hurd_dtablesize; ++d)
1355 	  {
1356 	    struct hurd_userlink ulink;
1357 	    io_t port;
1358 	    mach_port_t asyncid;
1359 	    if (_hurd_dtable[d] == NULL)
1360 	      continue;
1361 	    port = _hurd_port_get (&_hurd_dtable[d]->port, &ulink);
1362 	    if (! __io_get_icky_async_id (port, &asyncid))
1363 	      {
1364 		if (refport == asyncid)
1365 		  /* Break out of the loop on the next iteration.  */
1366 		  lucky = 1;
1367 		__mach_port_deallocate (__mach_task_self (), asyncid);
1368 	      }
1369 	    _hurd_port_free (&_hurd_dtable[d]->port, &ulink, port);
1370 	  }
1371 	__mutex_unlock (&_hurd_dtable_lock);
1372 	/* If we found a lucky winner, we've set D to -1 in the loop.  */
1373 	if (lucky)
1374 	  goto win;
1375       }
1376     }
1377 
1378   /* If this signal is legit, we have done `goto win' by now.
1379      When we return the error, mig deallocates REFPORT.  */
1380   return EPERM;
1381 
1382  win:
1383   /* Deallocate the REFPORT send right; we are done with it.  */
1384   __mach_port_deallocate (__mach_task_self (), refport);
1385 
1386   return 0;
1387 }
1388 
1389 /* Implement the sig_post RPC from <hurd/msg.defs>;
1390    sent when someone wants us to get a signal.  */
1391 kern_return_t
_S_msg_sig_post(mach_port_t me,mach_port_t reply_port,mach_msg_type_name_t reply_port_type,int signo,natural_t sigcode,mach_port_t refport)1392 _S_msg_sig_post (mach_port_t me,
1393 		 mach_port_t reply_port, mach_msg_type_name_t reply_port_type,
1394 		 int signo, natural_t sigcode,
1395 		 mach_port_t refport)
1396 {
1397   error_t err;
1398   struct hurd_signal_detail d;
1399 
1400   if (err = signal_allowed (signo, refport))
1401     return err;
1402 
1403   d.code = d.exc_subcode = sigcode;
1404   d.exc = 0;
1405 
1406   /* Post the signal to a global receiver thread (or mark it pending in
1407      the global sigstate).  This will reply when the signal can be
1408      considered delivered.  */
1409   _hurd_internal_post_signal (_hurd_global_sigstate,
1410 			      signo, &d, reply_port, reply_port_type,
1411 			      0); /* Stop if traced.  */
1412 
1413   return MIG_NO_REPLY;		/* Already replied.  */
1414 }
1415 
1416 /* Implement the sig_post_untraced RPC from <hurd/msg.defs>;
1417    sent when the debugger wants us to really get a signal
1418    even if we are traced.  */
1419 kern_return_t
_S_msg_sig_post_untraced(mach_port_t me,mach_port_t reply_port,mach_msg_type_name_t reply_port_type,int signo,natural_t sigcode,mach_port_t refport)1420 _S_msg_sig_post_untraced (mach_port_t me,
1421 			  mach_port_t reply_port,
1422 			  mach_msg_type_name_t reply_port_type,
1423 			  int signo, natural_t sigcode,
1424 			  mach_port_t refport)
1425 {
1426   error_t err;
1427   struct hurd_signal_detail d;
1428 
1429   if (err = signal_allowed (signo, refport))
1430     return err;
1431 
1432   d.code = d.exc_subcode = sigcode;
1433   d.exc = 0;
1434 
1435   /* Post the signal to the designated signal-receiving thread.  This will
1436      reply when the signal can be considered delivered.  */
1437   _hurd_internal_post_signal (_hurd_global_sigstate,
1438 			      signo, &d, reply_port, reply_port_type,
1439 			      1); /* Untraced flag. */
1440 
1441   return MIG_NO_REPLY;		/* Already replied.  */
1442 }
1443 
1444 extern void __mig_init (void *);
1445 
1446 #include <mach/task_special_ports.h>
1447 
1448 /* Initialize the message port, _hurd_global_sigstate, and start the
1449    signal thread.  */
1450 
1451 void
_hurdsig_init(const int * intarray,size_t intarraysize)1452 _hurdsig_init (const int *intarray, size_t intarraysize)
1453 {
1454   error_t err;
1455   vm_size_t stacksize;
1456   struct hurd_sigstate *ss;
1457 
1458   __mutex_init (&_hurd_siglock);
1459 
1460   err = __mach_port_allocate (__mach_task_self (),
1461 			      MACH_PORT_RIGHT_RECEIVE,
1462 			      &_hurd_msgport);
1463   assert_perror (err);
1464 
1465   /* Make a send right to the signal port.  */
1466   err = __mach_port_insert_right (__mach_task_self (),
1467 				  _hurd_msgport,
1468 				  _hurd_msgport,
1469 				  MACH_MSG_TYPE_MAKE_SEND);
1470   assert_perror (err);
1471 
1472   /* Initialize the global signal state.  */
1473   _hurd_global_sigstate = _hurd_thread_sigstate (MACH_PORT_NULL);
1474 
1475   /* We block all signals, and let actual threads pull them from the
1476      pending mask.  */
1477   __sigfillset(& _hurd_global_sigstate->blocked);
1478 
1479   /* Initialize the main thread's signal state.  */
1480   ss = _hurd_self_sigstate ();
1481 
1482   /* Mark it as a process-wide signal receiver.  Threads in this set use
1483      the common action vector in _hurd_global_sigstate.  */
1484   _hurd_sigstate_set_global_rcv (ss);
1485 
1486   /* Copy inherited signal settings from our parent (or pre-exec process
1487      state) */
1488   if (intarraysize > INIT_SIGMASK)
1489     ss->blocked = intarray[INIT_SIGMASK];
1490   if (intarraysize > INIT_SIGPENDING)
1491     _hurd_global_sigstate->pending = intarray[INIT_SIGPENDING];
1492   if (intarraysize > INIT_SIGIGN && intarray[INIT_SIGIGN] != 0)
1493     {
1494       int signo;
1495       for (signo = 1; signo < NSIG; ++signo)
1496 	if (intarray[INIT_SIGIGN] & __sigmask(signo))
1497 	  _hurd_global_sigstate->actions[signo].sa_handler = SIG_IGN;
1498     }
1499 
1500   /* Start the signal thread listening on the message port.  */
1501 
1502 #pragma weak __pthread_create
1503   if (!__pthread_create)
1504     {
1505       err = __thread_create (__mach_task_self (), &_hurd_msgport_thread);
1506       assert_perror (err);
1507 
1508       stacksize = __vm_page_size * 8; /* Small stack for signal thread.  */
1509       err = __mach_setup_thread (__mach_task_self (), _hurd_msgport_thread,
1510 				 _hurd_msgport_receive,
1511 				 (vm_address_t *) &__hurd_sigthread_stack_base,
1512 				 &stacksize);
1513       assert_perror (err);
1514       err = __mach_setup_tls (_hurd_msgport_thread);
1515       assert_perror (err);
1516 
1517       __hurd_sigthread_stack_end = __hurd_sigthread_stack_base + stacksize;
1518 
1519       /* Reinitialize the MiG support routines so they will use a per-thread
1520 	 variable for the cached reply port.  */
1521       __mig_init ((void *) __hurd_sigthread_stack_base);
1522 
1523       err = __thread_resume (_hurd_msgport_thread);
1524       assert_perror (err);
1525     }
1526   else
1527     {
1528       pthread_t thread;
1529       pthread_attr_t attr;
1530       void *addr;
1531       size_t size;
1532 
1533       /* When pthread is being used, we need to make the signal thread a
1534          proper pthread.  Otherwise it cannot use mutex_lock et al, which
1535          will be the pthread versions.  Various of the message port RPC
1536          handlers need to take locks, so we need to be able to call into
1537          pthread code and meet its assumptions about how our thread and
1538          its stack are arranged.  Since pthread puts it there anyway,
1539          we'll let the signal thread's per-thread variables be found as for
1540          any normal pthread, and just leave the magic __hurd_sigthread_*
1541          values all zero so they'll be ignored.  */
1542 
1543 #pragma weak __pthread_detach
1544 #pragma weak __pthread_getattr_np
1545 #pragma weak __pthread_attr_getstack
1546       __pthread_create(&thread, NULL, &_hurd_msgport_receive, NULL);
1547 
1548       /* Record signal thread stack layout for fork() */
1549       __pthread_getattr_np (thread, &attr);
1550       __pthread_attr_getstack (&attr, &addr, &size);
1551       __hurd_sigthread_stack_base = (uintptr_t) addr;
1552       __hurd_sigthread_stack_end = __hurd_sigthread_stack_base + size;
1553 
1554       __pthread_detach(thread);
1555 
1556       /* XXX We need the thread port for the signal thread further on
1557          in this thread (see hurdfault.c:_hurdsigfault_init).
1558          Therefore we block until _hurd_msgport_thread is initialized
1559          by the newly created thread.  This really shouldn't be
1560          necessary; we should be able to fetch the thread port for a
1561          pthread from here.  */
1562       while (_hurd_msgport_thread == 0)
1563 	__swtch_pri (0);
1564     }
1565 
1566   /* Receive exceptions on the signal port.  */
1567 #ifdef TASK_EXCEPTION_PORT
1568   __task_set_special_port (__mach_task_self (),
1569 			   TASK_EXCEPTION_PORT, _hurd_msgport);
1570 #elif defined (EXC_MASK_ALL)
1571   __task_set_exception_ports (__mach_task_self (),
1572 			      EXC_MASK_ALL & ~(EXC_MASK_SYSCALL
1573 					       | EXC_MASK_MACH_SYSCALL
1574 					       | EXC_MASK_RPC_ALERT),
1575 			      _hurd_msgport,
1576 			      EXCEPTION_DEFAULT, MACHINE_THREAD_STATE);
1577 #else
1578 # error task_set_exception_port?
1579 #endif
1580 
1581   /* Sanity check.  Any pending, unblocked signals should have been
1582      taken by our predecessor incarnation (i.e. parent or pre-exec state)
1583      before packing up our init ints.  This assert is last (not above)
1584      so that signal handling is all set up to handle the abort.  */
1585   assert ((ss->pending &~ ss->blocked) == 0);
1586 }
1587 				/* XXXX */
1588 /* Reauthenticate with the proc server.  */
1589 
1590 static void
reauth_proc(mach_port_t new)1591 reauth_proc (mach_port_t new)
1592 {
1593   mach_port_t ref, ignore;
1594 
1595   ref = __mach_reply_port ();
1596   if (! HURD_PORT_USE (&_hurd_ports[INIT_PORT_PROC],
1597 		       __proc_reauthenticate (port, ref,
1598 					      MACH_MSG_TYPE_MAKE_SEND)
1599 		       || __auth_user_authenticate (new, ref,
1600 						    MACH_MSG_TYPE_MAKE_SEND,
1601 						    &ignore))
1602       && ignore != MACH_PORT_NULL)
1603     __mach_port_deallocate (__mach_task_self (), ignore);
1604   __mach_port_destroy (__mach_task_self (), ref);
1605 
1606   /* Set the owner of the process here too. */
1607   __mutex_lock (&_hurd_id.lock);
1608   if (!_hurd_check_ids ())
1609     HURD_PORT_USE (&_hurd_ports[INIT_PORT_PROC],
1610 		   __proc_setowner (port,
1611 				    (_hurd_id.gen.nuids
1612 				     ? _hurd_id.gen.uids[0] : 0),
1613 				    !_hurd_id.gen.nuids));
1614   __mutex_unlock (&_hurd_id.lock);
1615 
1616   (void) &reauth_proc;		/* Silence compiler warning.  */
1617 }
1618 text_set_element (_hurd_reauth_hook, reauth_proc);
1619 
1620 /* Like `getenv', but safe for the signal thread to run.
1621    If the environment is trashed, this will just return NULL.  */
1622 
1623 const char *
_hurdsig_getenv(const char * variable)1624 _hurdsig_getenv (const char *variable)
1625 {
1626   if (__libc_enable_secure)
1627     return NULL;
1628 
1629   if (_hurdsig_catch_memory_fault (__environ))
1630     /* We bombed in getenv.  */
1631     return NULL;
1632   else
1633     {
1634       const size_t len = strlen (variable);
1635       char *value = NULL;
1636       char *volatile *ep = __environ;
1637       while (*ep)
1638 	{
1639 	  const char *p = *ep;
1640 	  _hurdsig_fault_preemptor.first = (long int) p;
1641 	  _hurdsig_fault_preemptor.last = VM_MAX_ADDRESS;
1642 	  if (! strncmp (p, variable, len) && p[len] == '=')
1643 	    {
1644 	      size_t valuelen;
1645 	      p += len + 1;
1646 	      valuelen = strlen (p);
1647 	      _hurdsig_fault_preemptor.last = (long int) (p + valuelen);
1648 	      value = malloc (++valuelen);
1649 	      if (value)
1650 		memcpy (value, p, valuelen);
1651 	      break;
1652 	    }
1653 	  _hurdsig_fault_preemptor.first = (long int) ++ep;
1654 	  _hurdsig_fault_preemptor.last = (long int) (ep + 1);
1655 	}
1656       _hurdsig_end_catch_fault ();
1657       return value;
1658     }
1659 }
1660