1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 30 #include <sys/types.h> 31 #include <sys/systm.h> 32 #include <sys/errno.h> 33 #include <sys/proc.h> 34 #include <sys/zone.h> 35 #include <sys/thread.h> 36 #include <sys/signal.h> 37 #include <sys/brand.h> 38 #include <sys/lx_brand.h> 39 #include <sys/lx_pid.h> 40 #include <lx_signum.h> 41 42 extern int kill(pid_t, int); 43 44 /* 45 * Check if it is legal to send this signal to the init process. Linux 46 * kill(2) semantics dictate that no _unhandled_ signal may be sent to pid 47 * 1. 48 */ 49 static int 50 init_sig_check(int sig, pid_t pid) 51 { 52 proc_t *p; 53 int rv = 0; 54 55 mutex_enter(&pidlock); 56 57 if (((p = prfind(pid)) == NULL) || (p->p_stat == SIDL)) 58 rv = ESRCH; 59 else if (sig && (sigismember(&cantmask, sig) || 60 (PTOU(p)->u_signal[sig-1] == SIG_DFL) || 61 (PTOU(p)->u_signal[sig-1] == SIG_IGN))) 62 rv = EPERM; 63 64 mutex_exit(&pidlock); 65 66 return (rv); 67 } 68 69 long 70 lx_tkill(pid_t pid, int lx_sig) 71 { 72 kthread_t *t; 73 proc_t *pp; 74 pid_t initpid; 75 sigqueue_t *sqp; 76 struct lx_lwp_data *br = ttolxlwp(curthread); 77 int tid = 1; /* default tid */ 78 int sig, rv; 79 80 /* 81 * Unlike kill(2), Linux tkill(2) doesn't allow signals to 82 * be sent to process IDs <= 0 as it doesn't overlay any special 83 * semantics on the pid. 84 */ 85 if ((pid <= 0) || ((lx_sig < 0) || (lx_sig >= LX_NSIG)) || 86 ((sig = ltos_signo[lx_sig]) < 0)) 87 return (set_errno(EINVAL)); 88 89 /* 90 * If the Linux pid is 1, translate the pid to the actual init 91 * pid for the zone. Note that Linux dictates that no unhandled 92 * signals may be sent to init, so check for that, too. 93 * 94 * Otherwise, extract the tid and real pid from the Linux pid. 95 */ 96 initpid = curproc->p_zone->zone_proc_initpid; 97 if (pid == 1) 98 pid = initpid; 99 if ((pid == initpid) && ((rv = init_sig_check(sig, pid)) != 0)) 100 return (set_errno(rv)); 101 else if (lx_lpid_to_spair(pid, &pid, &tid) < 0) 102 return (set_errno(ESRCH)); 103 104 sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP); 105 106 /* 107 * Find the process for the passed pid... 108 */ 109 mutex_enter(&pidlock); 110 if (((pp = prfind(pid)) == NULL) || (pp->p_stat == SIDL)) { 111 mutex_exit(&pidlock); 112 rv = set_errno(ESRCH); 113 goto free_and_exit; 114 } 115 mutex_enter(&pp->p_lock); 116 mutex_exit(&pidlock); 117 118 /* 119 * Deny permission to send the signal if either of the following 120 * is true: 121 * 122 * + The signal is SIGCONT and the target pid is not in the same 123 * session as the sender 124 * 125 * + prochasprocperm() shows the user lacks sufficient permission 126 * to send the signal to the target pid 127 */ 128 if (((sig == SIGCONT) && (pp->p_sessp != curproc->p_sessp)) || 129 (!prochasprocperm(pp, curproc, CRED()))) { 130 mutex_exit(&pp->p_lock); 131 rv = set_errno(EPERM); 132 goto free_and_exit; 133 } 134 135 /* check for the tid */ 136 if ((t = idtot(pp, tid)) == NULL) { 137 mutex_exit(&pp->p_lock); 138 rv = set_errno(ESRCH); 139 goto free_and_exit; 140 } 141 142 /* a signal of 0 means just check for the existence of the thread */ 143 if (lx_sig == 0) { 144 mutex_exit(&pp->p_lock); 145 rv = 0; 146 goto free_and_exit; 147 } 148 149 sqp->sq_info.si_signo = sig; 150 sqp->sq_info.si_code = SI_LWP; 151 sqp->sq_info.si_pid = br->br_pid; 152 sqp->sq_info.si_uid = crgetruid(CRED()); 153 sigaddqa(pp, t, sqp); 154 155 mutex_exit(&pp->p_lock); 156 157 return (0); 158 159 free_and_exit: 160 kmem_free(sqp, sizeof (sigqueue_t)); 161 return (rv); 162 } 163 164 long 165 lx_kill(pid_t lx_pid, int lx_sig) 166 { 167 pid_t s_pid, initpid; 168 sigsend_t v; 169 zone_t *zone = curproc->p_zone; 170 struct proc *p; 171 int err, sig, nfound; 172 173 if ((lx_sig < 0) || (lx_sig >= LX_NSIG) || 174 ((sig = ltos_signo[lx_sig]) < 0)) 175 return (set_errno(EINVAL)); 176 177 /* 178 * Since some linux apps rely on init(1M) having PID 1, we 179 * transparently translate 1 to the real init(1M)'s pid. We then 180 * check to be sure that it is legal for this process to send this 181 * signal to init(1M). 182 */ 183 initpid = zone->zone_proc_initpid; 184 if (lx_pid == 1 || lx_pid == -1) { 185 s_pid = initpid; 186 } else if (lx_pid == 0) { 187 s_pid = 0; 188 } else if (lx_pid > 0) { 189 if (lx_lpid_to_spair(lx_pid, &s_pid, NULL) != 0) { 190 /* 191 * If we didn't find this pid that means it doesn't 192 * exist in this zone. 193 */ 194 return (set_errno(ESRCH)); 195 } 196 } else { 197 ASSERT(lx_pid < 0); 198 if (lx_lpid_to_spair(-lx_pid, &s_pid, NULL) != 0) { 199 /* 200 * If we didn't find this pid it means that the 201 * process group leader doesn't exist in this zone. 202 * In this case assuming that the Linux pid is 203 * the same as the Solaris pid will get us the 204 * correct behavior. 205 */ 206 s_pid = -lx_pid; 207 } 208 } 209 210 if ((s_pid == initpid) && ((err = init_sig_check(sig, s_pid)) != 0)) 211 return (set_errno(err)); 212 213 /* 214 * For individual processes, kill() semantics are the same between 215 * Solaris and Linux. 216 */ 217 if (lx_pid >= 0) 218 return (kill(s_pid, sig)); 219 220 /* 221 * In Solaris, sending a signal to -pid means "send a signal to 222 * everyone in process group pid." In Linux it means "send a 223 * signal to everyone in the group other than init." Sending a 224 * signal to -1 means "send a signal to every process except init 225 * and myself." 226 */ 227 228 bzero(&v, sizeof (v)); 229 v.sig = sig; 230 v.checkperm = 1; 231 v.sicode = SI_USER; 232 err = 0; 233 234 mutex_enter(&pidlock); 235 236 p = (lx_pid == -1) ? practive : pgfind(s_pid); 237 nfound = 0; 238 while (err == 0 && p != NULL) { 239 if ((p->p_zone == zone) && (p->p_stat != SIDL) && 240 (p->p_pid != initpid) && (lx_pid < -1 || p != curproc)) { 241 nfound++; 242 err = sigsendproc(p, &v); 243 } 244 245 p = (lx_pid == -1) ? p->p_next : p->p_pglink; 246 } 247 mutex_exit(&pidlock); 248 if (nfound == 0) 249 err = ESRCH; 250 else if (err == 0 && v.perm == 0) 251 err = EPERM; 252 return (err ? set_errno(err) : 0); 253 }