- * Determine whether td may deliver the specified signal to p. * Returns: 0 for permitted, an errno value otherwise * Locks: Sufficient locks to protect various components of td and p * must be held. td must be curthread, and a lock must be * held for p. * References: td and p must be valid for the lifetime of the call */
| 1568 | * References: td and p must be valid for the lifetime of the call |
| 1569 | */ |
| 1570 | int |
| 1571 | p_cansignal(struct thread *td, struct proc *p, int signum) |
| 1572 | { |
| 1573 | |
| 1574 | KASSERT(td == curthread, ("%s: td not curthread", __func__)); |
| 1575 | PROC_LOCK_ASSERT(p, MA_OWNED); |
| 1576 | if (td->td_proc == p) |
| 1577 | return (0); |
| 1578 | |
| 1579 | /* |
| 1580 | * UNIX signalling semantics require that processes in the same |
| 1581 | * session always be able to deliver SIGCONT to one another, |
| 1582 | * overriding the remaining protections. |
| 1583 | */ |
| 1584 | /* XXX: This will require an additional lock of some sort. */ |
| 1585 | if (signum == SIGCONT && td->td_proc->p_session == p->p_session) |
| 1586 | return (0); |
| 1587 | /* |
| 1588 | * Some compat layers use SIGTHR and higher signals for |
| 1589 | * communication between different kernel threads of the same |
| 1590 | * process, so that they expect that it's always possible to |
| 1591 | * deliver them, even for suid applications where cr_cansignal() can |
| 1592 | * deny such ability for security consideration. It should be |
| 1593 | * pretty safe to do since the only way to create two processes |
| 1594 | * with the same p_leader is via rfork(2). |
| 1595 | */ |
| 1596 | if (td->td_proc->p_leader != NULL && signum >= SIGTHR && |
| 1597 | signum < SIGTHR + 4 && td->td_proc->p_leader == p->p_leader) |
| 1598 | return (0); |
| 1599 | |
| 1600 | return (cr_cansignal(td->td_ucred, p, signum)); |
| 1601 | } |
| 1602 | |
| 1603 | /*- |
| 1604 | * Determine whether td may reschedule p. |
no test coverage detected