1/* 2 * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. 9 * Copyright (c) 2000-2001 Robert N. M. Watson. All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * @(#)kern_prot.c 8.6 (Berkeley) 1/21/94
| 1/* 2 * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. 9 * Copyright (c) 2000-2001 Robert N. M. Watson. All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * @(#)kern_prot.c 8.6 (Berkeley) 1/21/94
|
40 * $FreeBSD: head/sys/kern/kern_prot.c 90756 2002-02-17 07:30:34Z dillon $
| 40 * $FreeBSD: head/sys/kern/kern_prot.c 91140 2002-02-23 11:12:57Z tanimura $
|
41 */ 42 43/* 44 * System calls related to processes and protection 45 */ 46 47#include "opt_compat.h" 48 49#include <sys/param.h> 50#include <sys/systm.h> 51#include <sys/acct.h> 52#include <sys/kernel.h> 53#include <sys/lock.h>
| 41 */ 42 43/* 44 * System calls related to processes and protection 45 */ 46 47#include "opt_compat.h" 48 49#include <sys/param.h> 50#include <sys/systm.h> 51#include <sys/acct.h> 52#include <sys/kernel.h> 53#include <sys/lock.h>
|
| 54#include <sys/malloc.h>
|
54#include <sys/mutex.h>
| 55#include <sys/mutex.h>
|
55#include <sys/proc.h>
| |
56#include <sys/sx.h>
| 56#include <sys/sx.h>
|
| 57#include <sys/proc.h>
|
57#include <sys/sysproto.h> 58#include <sys/jail.h>
| 58#include <sys/sysproto.h> 59#include <sys/jail.h>
|
59#include <sys/malloc.h>
| |
60#include <sys/pioctl.h> 61#include <sys/resourcevar.h> 62#include <sys/sysctl.h> 63 64static MALLOC_DEFINE(M_CRED, "cred", "credentials"); 65 66SYSCTL_DECL(_security); 67SYSCTL_NODE(_security, OID_AUTO, bsd, CTLFLAG_RW, 0, 68 "BSD security policy"); 69 70#ifndef _SYS_SYSPROTO_H_ 71struct getpid_args { 72 int dummy; 73}; 74#endif 75/* 76 * MPSAFE 77 */ 78/* ARGSUSED */ 79int 80getpid(td, uap) 81 struct thread *td; 82 struct getpid_args *uap; 83{ 84 struct proc *p = td->td_proc; 85 int s; 86 87 s = mtx_lock_giant(kern_giant_proc); 88 td->td_retval[0] = p->p_pid; 89#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 90 PROC_LOCK(p); 91 td->td_retval[1] = p->p_pptr->p_pid; 92 PROC_UNLOCK(p); 93#endif 94 mtx_unlock_giant(s); 95 return (0); 96} 97 98#ifndef _SYS_SYSPROTO_H_ 99struct getppid_args { 100 int dummy; 101}; 102#endif 103/* 104 * MPSAFE 105 */ 106/* ARGSUSED */ 107int 108getppid(td, uap) 109 struct thread *td; 110 struct getppid_args *uap; 111{ 112 struct proc *p = td->td_proc; 113 int s; 114 115 s = mtx_lock_giant(kern_giant_proc); 116 PROC_LOCK(p); 117 td->td_retval[0] = p->p_pptr->p_pid; 118 PROC_UNLOCK(p); 119 mtx_unlock_giant(s); 120 return (0); 121} 122 123/* 124 * Get process group ID; note that POSIX getpgrp takes no parameter. 125 */ 126#ifndef _SYS_SYSPROTO_H_ 127struct getpgrp_args { 128 int dummy; 129}; 130#endif 131/* 132 * MPSAFE 133 */ 134int 135getpgrp(td, uap) 136 struct thread *td; 137 struct getpgrp_args *uap; 138{ 139 struct proc *p = td->td_proc;
| 60#include <sys/pioctl.h> 61#include <sys/resourcevar.h> 62#include <sys/sysctl.h> 63 64static MALLOC_DEFINE(M_CRED, "cred", "credentials"); 65 66SYSCTL_DECL(_security); 67SYSCTL_NODE(_security, OID_AUTO, bsd, CTLFLAG_RW, 0, 68 "BSD security policy"); 69 70#ifndef _SYS_SYSPROTO_H_ 71struct getpid_args { 72 int dummy; 73}; 74#endif 75/* 76 * MPSAFE 77 */ 78/* ARGSUSED */ 79int 80getpid(td, uap) 81 struct thread *td; 82 struct getpid_args *uap; 83{ 84 struct proc *p = td->td_proc; 85 int s; 86 87 s = mtx_lock_giant(kern_giant_proc); 88 td->td_retval[0] = p->p_pid; 89#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 90 PROC_LOCK(p); 91 td->td_retval[1] = p->p_pptr->p_pid; 92 PROC_UNLOCK(p); 93#endif 94 mtx_unlock_giant(s); 95 return (0); 96} 97 98#ifndef _SYS_SYSPROTO_H_ 99struct getppid_args { 100 int dummy; 101}; 102#endif 103/* 104 * MPSAFE 105 */ 106/* ARGSUSED */ 107int 108getppid(td, uap) 109 struct thread *td; 110 struct getppid_args *uap; 111{ 112 struct proc *p = td->td_proc; 113 int s; 114 115 s = mtx_lock_giant(kern_giant_proc); 116 PROC_LOCK(p); 117 td->td_retval[0] = p->p_pptr->p_pid; 118 PROC_UNLOCK(p); 119 mtx_unlock_giant(s); 120 return (0); 121} 122 123/* 124 * Get process group ID; note that POSIX getpgrp takes no parameter. 125 */ 126#ifndef _SYS_SYSPROTO_H_ 127struct getpgrp_args { 128 int dummy; 129}; 130#endif 131/* 132 * MPSAFE 133 */ 134int 135getpgrp(td, uap) 136 struct thread *td; 137 struct getpgrp_args *uap; 138{ 139 struct proc *p = td->td_proc;
|
| 140 int s;
|
140
| 141
|
141 mtx_lock(&Giant);
| 142 s = mtx_lock_giant(kern_giant_proc); 143 PROC_LOCK(p);
|
142 td->td_retval[0] = p->p_pgrp->pg_id;
| 144 td->td_retval[0] = p->p_pgrp->pg_id;
|
143 mtx_unlock(&Giant);
| 145 PROC_UNLOCK(p); 146 mtx_unlock_giant(s);
|
144 return (0); 145} 146 147/* Get an arbitary pid's process group id */ 148#ifndef _SYS_SYSPROTO_H_ 149struct getpgid_args { 150 pid_t pid; 151}; 152#endif 153/* 154 * MPSAFE 155 */ 156int 157getpgid(td, uap) 158 struct thread *td; 159 struct getpgid_args *uap; 160{ 161 struct proc *p = td->td_proc; 162 struct proc *pt; 163 int error, s; 164 165 s = mtx_lock_giant(kern_giant_proc); 166 error = 0;
| 147 return (0); 148} 149 150/* Get an arbitary pid's process group id */ 151#ifndef _SYS_SYSPROTO_H_ 152struct getpgid_args { 153 pid_t pid; 154}; 155#endif 156/* 157 * MPSAFE 158 */ 159int 160getpgid(td, uap) 161 struct thread *td; 162 struct getpgid_args *uap; 163{ 164 struct proc *p = td->td_proc; 165 struct proc *pt; 166 int error, s; 167 168 s = mtx_lock_giant(kern_giant_proc); 169 error = 0;
|
167 if (uap->pid == 0)
| 170 if (uap->pid == 0) { 171 PROC_LOCK(p);
|
168 td->td_retval[0] = p->p_pgrp->pg_id;
| 172 td->td_retval[0] = p->p_pgrp->pg_id;
|
169 else if ((pt = pfind(uap->pid)) == NULL)
| 173 PROC_UNLOCK(p); 174 } else if ((pt = pfind(uap->pid)) == NULL)
|
170 error = ESRCH; 171 else { 172 error = p_cansee(p, pt); 173 if (error == 0) 174 td->td_retval[0] = pt->p_pgrp->pg_id; 175 PROC_UNLOCK(pt); 176 } 177 mtx_unlock_giant(s); 178 return (error); 179} 180 181/* 182 * Get an arbitary pid's session id. 183 */ 184#ifndef _SYS_SYSPROTO_H_ 185struct getsid_args { 186 pid_t pid; 187}; 188#endif 189/* 190 * MPSAFE 191 */ 192int 193getsid(td, uap) 194 struct thread *td; 195 struct getsid_args *uap; 196{ 197 struct proc *p = td->td_proc; 198 struct proc *pt; 199 int error;
| 175 error = ESRCH; 176 else { 177 error = p_cansee(p, pt); 178 if (error == 0) 179 td->td_retval[0] = pt->p_pgrp->pg_id; 180 PROC_UNLOCK(pt); 181 } 182 mtx_unlock_giant(s); 183 return (error); 184} 185 186/* 187 * Get an arbitary pid's session id. 188 */ 189#ifndef _SYS_SYSPROTO_H_ 190struct getsid_args { 191 pid_t pid; 192}; 193#endif 194/* 195 * MPSAFE 196 */ 197int 198getsid(td, uap) 199 struct thread *td; 200 struct getsid_args *uap; 201{ 202 struct proc *p = td->td_proc; 203 struct proc *pt; 204 int error;
|
| 205 int s;
|
200
| 206
|
201 mtx_lock(&Giant);
| 207 s = mtx_lock_giant(kern_giant_proc);
|
202 error = 0;
| 208 error = 0;
|
203 if (uap->pid == 0)
| 209 if (uap->pid == 0) { 210 PROC_LOCK(p);
|
204 td->td_retval[0] = p->p_session->s_sid;
| 211 td->td_retval[0] = p->p_session->s_sid;
|
205 else if ((pt = pfind(uap->pid)) == NULL)
| 212 PROC_UNLOCK(p); 213 } else if ((pt = pfind(uap->pid)) == NULL)
|
206 error = ESRCH; 207 else { 208 error = p_cansee(p, pt); 209 if (error == 0) 210 td->td_retval[0] = pt->p_session->s_sid; 211 PROC_UNLOCK(pt); 212 }
| 214 error = ESRCH; 215 else { 216 error = p_cansee(p, pt); 217 if (error == 0) 218 td->td_retval[0] = pt->p_session->s_sid; 219 PROC_UNLOCK(pt); 220 }
|
213 mtx_unlock(&Giant);
| 221 mtx_unlock_giant(s);
|
214 return (error); 215} 216 217#ifndef _SYS_SYSPROTO_H_ 218struct getuid_args { 219 int dummy; 220}; 221#endif 222/* 223 * MPSAFE 224 */ 225/* ARGSUSED */ 226int 227getuid(td, uap) 228 struct thread *td; 229 struct getuid_args *uap; 230{ 231 struct proc *p = td->td_proc; 232 233 mtx_lock(&Giant); 234 td->td_retval[0] = p->p_ucred->cr_ruid; 235#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 236 td->td_retval[1] = p->p_ucred->cr_uid; 237#endif 238 mtx_unlock(&Giant); 239 return (0); 240} 241 242#ifndef _SYS_SYSPROTO_H_ 243struct geteuid_args { 244 int dummy; 245}; 246#endif 247/* 248 * MPSAFE 249 */ 250/* ARGSUSED */ 251int 252geteuid(td, uap) 253 struct thread *td; 254 struct geteuid_args *uap; 255{ 256 mtx_lock(&Giant); 257 td->td_retval[0] = td->td_proc->p_ucred->cr_uid; 258 mtx_unlock(&Giant); 259 return (0); 260} 261 262#ifndef _SYS_SYSPROTO_H_ 263struct getgid_args { 264 int dummy; 265}; 266#endif 267/* 268 * MPSAFE 269 */ 270/* ARGSUSED */ 271int 272getgid(td, uap) 273 struct thread *td; 274 struct getgid_args *uap; 275{ 276 struct proc *p = td->td_proc; 277 278 mtx_lock(&Giant); 279 td->td_retval[0] = p->p_ucred->cr_rgid; 280#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 281 td->td_retval[1] = p->p_ucred->cr_groups[0]; 282#endif 283 mtx_unlock(&Giant); 284 return (0); 285} 286 287/* 288 * Get effective group ID. The "egid" is groups[0], and could be obtained 289 * via getgroups. This syscall exists because it is somewhat painful to do 290 * correctly in a library function. 291 */ 292#ifndef _SYS_SYSPROTO_H_ 293struct getegid_args { 294 int dummy; 295}; 296#endif 297/* 298 * MPSAFE 299 */ 300/* ARGSUSED */ 301int 302getegid(td, uap) 303 struct thread *td; 304 struct getegid_args *uap; 305{ 306 struct proc *p = td->td_proc; 307 308 mtx_lock(&Giant); 309 td->td_retval[0] = p->p_ucred->cr_groups[0]; 310 mtx_unlock(&Giant); 311 return (0); 312} 313 314#ifndef _SYS_SYSPROTO_H_ 315struct getgroups_args { 316 u_int gidsetsize; 317 gid_t *gidset; 318}; 319#endif 320/* 321 * MPSAFE 322 */ 323int 324getgroups(td, uap) 325 struct thread *td; 326 register struct getgroups_args *uap; 327{ 328 struct ucred *cred; 329 struct proc *p = td->td_proc; 330 u_int ngrp; 331 int error; 332 333 mtx_lock(&Giant); 334 error = 0; 335 cred = p->p_ucred; 336 if ((ngrp = uap->gidsetsize) == 0) { 337 td->td_retval[0] = cred->cr_ngroups; 338 goto done2; 339 } 340 if (ngrp < cred->cr_ngroups) { 341 error = EINVAL; 342 goto done2; 343 } 344 ngrp = cred->cr_ngroups; 345 if ((error = copyout((caddr_t)cred->cr_groups, 346 (caddr_t)uap->gidset, ngrp * sizeof(gid_t)))) 347 goto done2; 348 td->td_retval[0] = ngrp; 349done2: 350 mtx_unlock(&Giant); 351 return (error); 352} 353 354#ifndef _SYS_SYSPROTO_H_ 355struct setsid_args { 356 int dummy; 357}; 358#endif 359/* 360 * MPSAFE 361 */ 362/* ARGSUSED */ 363int 364setsid(td, uap) 365 register struct thread *td; 366 struct setsid_args *uap; 367{
| 222 return (error); 223} 224 225#ifndef _SYS_SYSPROTO_H_ 226struct getuid_args { 227 int dummy; 228}; 229#endif 230/* 231 * MPSAFE 232 */ 233/* ARGSUSED */ 234int 235getuid(td, uap) 236 struct thread *td; 237 struct getuid_args *uap; 238{ 239 struct proc *p = td->td_proc; 240 241 mtx_lock(&Giant); 242 td->td_retval[0] = p->p_ucred->cr_ruid; 243#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 244 td->td_retval[1] = p->p_ucred->cr_uid; 245#endif 246 mtx_unlock(&Giant); 247 return (0); 248} 249 250#ifndef _SYS_SYSPROTO_H_ 251struct geteuid_args { 252 int dummy; 253}; 254#endif 255/* 256 * MPSAFE 257 */ 258/* ARGSUSED */ 259int 260geteuid(td, uap) 261 struct thread *td; 262 struct geteuid_args *uap; 263{ 264 mtx_lock(&Giant); 265 td->td_retval[0] = td->td_proc->p_ucred->cr_uid; 266 mtx_unlock(&Giant); 267 return (0); 268} 269 270#ifndef _SYS_SYSPROTO_H_ 271struct getgid_args { 272 int dummy; 273}; 274#endif 275/* 276 * MPSAFE 277 */ 278/* ARGSUSED */ 279int 280getgid(td, uap) 281 struct thread *td; 282 struct getgid_args *uap; 283{ 284 struct proc *p = td->td_proc; 285 286 mtx_lock(&Giant); 287 td->td_retval[0] = p->p_ucred->cr_rgid; 288#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 289 td->td_retval[1] = p->p_ucred->cr_groups[0]; 290#endif 291 mtx_unlock(&Giant); 292 return (0); 293} 294 295/* 296 * Get effective group ID. The "egid" is groups[0], and could be obtained 297 * via getgroups. This syscall exists because it is somewhat painful to do 298 * correctly in a library function. 299 */ 300#ifndef _SYS_SYSPROTO_H_ 301struct getegid_args { 302 int dummy; 303}; 304#endif 305/* 306 * MPSAFE 307 */ 308/* ARGSUSED */ 309int 310getegid(td, uap) 311 struct thread *td; 312 struct getegid_args *uap; 313{ 314 struct proc *p = td->td_proc; 315 316 mtx_lock(&Giant); 317 td->td_retval[0] = p->p_ucred->cr_groups[0]; 318 mtx_unlock(&Giant); 319 return (0); 320} 321 322#ifndef _SYS_SYSPROTO_H_ 323struct getgroups_args { 324 u_int gidsetsize; 325 gid_t *gidset; 326}; 327#endif 328/* 329 * MPSAFE 330 */ 331int 332getgroups(td, uap) 333 struct thread *td; 334 register struct getgroups_args *uap; 335{ 336 struct ucred *cred; 337 struct proc *p = td->td_proc; 338 u_int ngrp; 339 int error; 340 341 mtx_lock(&Giant); 342 error = 0; 343 cred = p->p_ucred; 344 if ((ngrp = uap->gidsetsize) == 0) { 345 td->td_retval[0] = cred->cr_ngroups; 346 goto done2; 347 } 348 if (ngrp < cred->cr_ngroups) { 349 error = EINVAL; 350 goto done2; 351 } 352 ngrp = cred->cr_ngroups; 353 if ((error = copyout((caddr_t)cred->cr_groups, 354 (caddr_t)uap->gidset, ngrp * sizeof(gid_t)))) 355 goto done2; 356 td->td_retval[0] = ngrp; 357done2: 358 mtx_unlock(&Giant); 359 return (error); 360} 361 362#ifndef _SYS_SYSPROTO_H_ 363struct setsid_args { 364 int dummy; 365}; 366#endif 367/* 368 * MPSAFE 369 */ 370/* ARGSUSED */ 371int 372setsid(td, uap) 373 register struct thread *td; 374 struct setsid_args *uap; 375{
|
| 376 struct pgrp *pgrp;
|
368 int error; 369 struct proc *p = td->td_proc;
| 377 int error; 378 struct proc *p = td->td_proc;
|
| 379 struct pgrp *newpgrp; 380 struct session *newsess;
|
370
| 381
|
| 382 error = 0; 383 pgrp = NULL; 384
|
371 mtx_lock(&Giant);
| 385 mtx_lock(&Giant);
|
372 if (p->p_pgid == p->p_pid || pgfind(p->p_pid))
| 386 387 MALLOC(newpgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, M_WAITOK | M_ZERO); 388 MALLOC(newsess, struct session *, sizeof(struct session), M_SESSION, M_WAITOK | M_ZERO); 389 390 PGRPSESS_XLOCK(); 391 392 if (p->p_pgid == p->p_pid || (pgrp = pgfind(p->p_pid)) != NULL) { 393 if (pgrp != NULL) 394 PGRP_UNLOCK(pgrp);
|
373 error = EPERM;
| 395 error = EPERM;
|
374 else { 375 (void)enterpgrp(p, p->p_pid, 1);
| 396 goto fail; 397 } else { 398 (void)enterpgrp(p, p->p_pid, newpgrp, newsess);
|
376 td->td_retval[0] = p->p_pid; 377 error = 0; 378 }
| 399 td->td_retval[0] = p->p_pid; 400 error = 0; 401 }
|
| 402 PGRPSESS_XUNLOCK();
|
379 mtx_unlock(&Giant);
| 403 mtx_unlock(&Giant);
|
380 return (error);
| 404 return (0); 405 406fail: 407 PGRPSESS_XUNLOCK(); 408 409 FREE(newpgrp, M_PGRP); 410 FREE(newsess, M_SESSION); 411 412 mtx_unlock(&Giant); 413 return (0);
|
381} 382 383/* 384 * set process group (setpgid/old setpgrp) 385 * 386 * caller does setpgid(targpid, targpgid) 387 * 388 * pid must be caller or child of caller (ESRCH) 389 * if a child 390 * pid must be in same session (EPERM) 391 * pid can't have done an exec (EACCES) 392 * if pgid != pid 393 * there must exist some pid in same session having pgid (EPERM) 394 * pid must not be session leader (EPERM) 395 */ 396#ifndef _SYS_SYSPROTO_H_ 397struct setpgid_args { 398 int pid; /* target process id */ 399 int pgid; /* target pgrp id */ 400}; 401#endif 402/* 403 * MPSAFE 404 */ 405/* ARGSUSED */ 406int 407setpgid(td, uap) 408 struct thread *td; 409 register struct setpgid_args *uap; 410{ 411 struct proc *curp = td->td_proc; 412 register struct proc *targp; /* target process */ 413 register struct pgrp *pgrp; /* target pgrp */ 414 int error;
| 414} 415 416/* 417 * set process group (setpgid/old setpgrp) 418 * 419 * caller does setpgid(targpid, targpgid) 420 * 421 * pid must be caller or child of caller (ESRCH) 422 * if a child 423 * pid must be in same session (EPERM) 424 * pid can't have done an exec (EACCES) 425 * if pgid != pid 426 * there must exist some pid in same session having pgid (EPERM) 427 * pid must not be session leader (EPERM) 428 */ 429#ifndef _SYS_SYSPROTO_H_ 430struct setpgid_args { 431 int pid; /* target process id */ 432 int pgid; /* target pgrp id */ 433}; 434#endif 435/* 436 * MPSAFE 437 */ 438/* ARGSUSED */ 439int 440setpgid(td, uap) 441 struct thread *td; 442 register struct setpgid_args *uap; 443{ 444 struct proc *curp = td->td_proc; 445 register struct proc *targp; /* target process */ 446 register struct pgrp *pgrp; /* target pgrp */ 447 int error;
|
| 448 struct pgrp *newpgrp;
|
415 416 if (uap->pgid < 0) 417 return (EINVAL);
| 449 450 if (uap->pgid < 0) 451 return (EINVAL);
|
| 452 453 error = 0; 454
|
418 mtx_lock(&Giant);
| 455 mtx_lock(&Giant);
|
419 sx_slock(&proctree_lock);
| 456 457 MALLOC(newpgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP, M_WAITOK | M_ZERO); 458 459 PGRPSESS_XLOCK(); 460
|
420 if (uap->pid != 0 && uap->pid != curp->p_pid) {
| 461 if (uap->pid != 0 && uap->pid != curp->p_pid) {
|
421 if ((targp = pfind(uap->pid)) == NULL || !inferior(targp)) {
| 462 sx_slock(&proctree_lock); 463 if ((targp = pfind(uap->pid)) == NULL) {
|
422 if (targp) 423 PROC_UNLOCK(targp);
| 464 if (targp) 465 PROC_UNLOCK(targp);
|
| 466 sx_sunlock(&proctree_lock);
|
424 error = ESRCH;
| 467 error = ESRCH;
|
425 goto done2;
| 468 goto fail;
|
426 }
| 469 }
|
| 470 if (!inferior(targp)) { 471 PROC_UNLOCK(targp); 472 sx_sunlock(&proctree_lock); 473 goto fail; 474 } 475 sx_sunlock(&proctree_lock);
|
427 if ((error = p_cansee(curproc, targp))) { 428 PROC_UNLOCK(targp);
| 476 if ((error = p_cansee(curproc, targp))) { 477 PROC_UNLOCK(targp);
|
429 goto done2;
| 478 goto fail;
|
430 } 431 if (targp->p_pgrp == NULL || 432 targp->p_session != curp->p_session) { 433 PROC_UNLOCK(targp); 434 error = EPERM;
| 479 } 480 if (targp->p_pgrp == NULL || 481 targp->p_session != curp->p_session) { 482 PROC_UNLOCK(targp); 483 error = EPERM;
|
435 goto done2;
| 484 goto fail;
|
436 } 437 if (targp->p_flag & P_EXEC) { 438 PROC_UNLOCK(targp); 439 error = EACCES;
| 485 } 486 if (targp->p_flag & P_EXEC) { 487 PROC_UNLOCK(targp); 488 error = EACCES;
|
440 goto done2;
| 489 goto fail;
|
441 }
| 490 }
|
442 } else {
| 491 PROC_UNLOCK(targp); 492 } else
|
443 targp = curp;
| 493 targp = curp;
|
444 PROC_LOCK(curp); /* XXX: not needed */ 445 }
| |
446 if (SESS_LEADER(targp)) {
| 494 if (SESS_LEADER(targp)) {
|
447 PROC_UNLOCK(targp);
| |
448 error = EPERM;
| 495 error = EPERM;
|
449 goto done2;
| 496 goto fail;
|
450 } 451 if (uap->pgid == 0) 452 uap->pgid = targp->p_pid;
| 497 } 498 if (uap->pgid == 0) 499 uap->pgid = targp->p_pid;
|
453 else if (uap->pgid != targp->p_pid) { 454 if ((pgrp = pgfind(uap->pgid)) == 0 ||
| 500 if (uap->pgid == targp->p_pid) { 501 if (targp->p_pgid == uap->pgid) 502 goto done; 503 error = enterpgrp(targp, uap->pgid, newpgrp, NULL); 504 if (error == 0) 505 newpgrp = NULL; 506 } else { 507 if ((pgrp = pgfind(uap->pgid)) == NULL ||
|
455 pgrp->pg_session != curp->p_session) {
| 508 pgrp->pg_session != curp->p_session) {
|
456 PROC_UNLOCK(targp);
| 509 if (pgrp != NULL) 510 PGRP_UNLOCK(pgrp);
|
457 error = EPERM;
| 511 error = EPERM;
|
458 goto done2;
| 512 goto fail;
|
459 }
| 513 }
|
| 514 if (pgrp == targp->p_pgrp) { 515 PGRP_UNLOCK(pgrp); 516 goto done; 517 } 518 PGRP_UNLOCK(pgrp); 519 error = enterthispgrp(targp, pgrp);
|
460 }
| 520 }
|
461 /* XXX: We should probably hold the lock across enterpgrp. */ 462 PROC_UNLOCK(targp); 463 error = enterpgrp(targp, uap->pgid, 0); 464done2: 465 sx_sunlock(&proctree_lock);
| 521done: 522 PGRPSESS_XUNLOCK(); 523 if (newpgrp != NULL) 524 FREE(newpgrp, M_PGRP);
|
466 mtx_unlock(&Giant);
| 525 mtx_unlock(&Giant);
|
| 526 return (0); 527 528fail: 529 PGRPSESS_XUNLOCK(); 530 531 KASSERT(newpgrp != NULL, ("setpgid failed and newpgrp is null.")); 532 FREE(newpgrp, M_PGRP); 533 534 mtx_unlock(&Giant);
|
467 return (error); 468} 469 470/* 471 * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD 472 * compatible. It says that setting the uid/gid to euid/egid is a special 473 * case of "appropriate privilege". Once the rules are expanded out, this 474 * basically means that setuid(nnn) sets all three id's, in all permitted 475 * cases unless _POSIX_SAVED_IDS is enabled. In that case, setuid(getuid()) 476 * does not set the saved id - this is dangerous for traditional BSD 477 * programs. For this reason, we *really* do not want to set 478 * _POSIX_SAVED_IDS and do not want to clear POSIX_APPENDIX_B_4_2_2. 479 */ 480#define POSIX_APPENDIX_B_4_2_2 481 482#ifndef _SYS_SYSPROTO_H_ 483struct setuid_args { 484 uid_t uid; 485}; 486#endif 487/* 488 * MPSAFE 489 */ 490/* ARGSUSED */ 491int 492setuid(td, uap) 493 struct thread *td; 494 struct setuid_args *uap; 495{ 496 struct proc *p = td->td_proc; 497 struct ucred *newcred, *oldcred; 498 uid_t uid; 499 int error; 500 501 uid = uap->uid; 502 mtx_lock(&Giant); 503 error = 0; 504 oldcred = p->p_ucred; 505 506 /* 507 * See if we have "permission" by POSIX 1003.1 rules. 508 * 509 * Note that setuid(geteuid()) is a special case of 510 * "appropriate privileges" in appendix B.4.2.2. We need 511 * to use this clause to be compatible with traditional BSD 512 * semantics. Basically, it means that "setuid(xx)" sets all 513 * three id's (assuming you have privs). 514 * 515 * Notes on the logic. We do things in three steps. 516 * 1: We determine if the euid is going to change, and do EPERM 517 * right away. We unconditionally change the euid later if this 518 * test is satisfied, simplifying that part of the logic. 519 * 2: We determine if the real and/or saved uids are going to 520 * change. Determined by compile options. 521 * 3: Change euid last. (after tests in #2 for "appropriate privs") 522 */ 523 if (uid != oldcred->cr_ruid && /* allow setuid(getuid()) */ 524#ifdef _POSIX_SAVED_IDS 525 uid != oldcred->cr_svuid && /* allow setuid(saved gid) */ 526#endif 527#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 528 uid != oldcred->cr_uid && /* allow setuid(geteuid()) */ 529#endif 530 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 531 goto done2; 532 533 newcred = crdup(oldcred); 534#ifdef _POSIX_SAVED_IDS 535 /* 536 * Do we have "appropriate privileges" (are we root or uid == euid) 537 * If so, we are changing the real uid and/or saved uid. 538 */ 539 if ( 540#ifdef POSIX_APPENDIX_B_4_2_2 /* Use the clause from B.4.2.2 */ 541 uid == oldcred->cr_uid || 542#endif 543 suser_xxx(oldcred, NULL, PRISON_ROOT) == 0) /* we are using privs */ 544#endif 545 { 546 /* 547 * Set the real uid and transfer proc count to new user. 548 */ 549 if (uid != oldcred->cr_ruid) { 550 change_ruid(newcred, uid); 551 setsugid(p); 552 } 553 /* 554 * Set saved uid 555 * 556 * XXX always set saved uid even if not _POSIX_SAVED_IDS, as 557 * the security of seteuid() depends on it. B.4.2.2 says it 558 * is important that we should do this. 559 */ 560 if (uid != oldcred->cr_svuid) { 561 change_svuid(newcred, uid); 562 setsugid(p); 563 } 564 } 565 566 /* 567 * In all permitted cases, we are changing the euid. 568 * Copy credentials so other references do not see our changes. 569 */ 570 if (uid != oldcred->cr_uid) { 571 change_euid(newcred, uid); 572 setsugid(p); 573 } 574 p->p_ucred = newcred; 575 crfree(oldcred); 576done2: 577 mtx_unlock(&Giant); 578 return (error); 579} 580 581#ifndef _SYS_SYSPROTO_H_ 582struct seteuid_args { 583 uid_t euid; 584}; 585#endif 586/* 587 * MPSAFE 588 */ 589/* ARGSUSED */ 590int 591seteuid(td, uap) 592 struct thread *td; 593 struct seteuid_args *uap; 594{ 595 struct proc *p = td->td_proc; 596 struct ucred *newcred, *oldcred; 597 uid_t euid; 598 int error; 599 600 euid = uap->euid; 601 mtx_lock(&Giant); 602 error = 0; 603 oldcred = p->p_ucred; 604 if (euid != oldcred->cr_ruid && /* allow seteuid(getuid()) */ 605 euid != oldcred->cr_svuid && /* allow seteuid(saved uid) */ 606 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 607 goto done2; 608 /* 609 * Everything's okay, do it. Copy credentials so other references do 610 * not see our changes. 611 */ 612 newcred = crdup(oldcred); 613 if (oldcred->cr_uid != euid) { 614 change_euid(newcred, euid); 615 setsugid(p); 616 } 617 p->p_ucred = newcred; 618 crfree(oldcred); 619done2: 620 mtx_unlock(&Giant); 621 return (error); 622} 623 624#ifndef _SYS_SYSPROTO_H_ 625struct setgid_args { 626 gid_t gid; 627}; 628#endif 629/* 630 * MPSAFE 631 */ 632/* ARGSUSED */ 633int 634setgid(td, uap) 635 struct thread *td; 636 struct setgid_args *uap; 637{ 638 struct proc *p = td->td_proc; 639 struct ucred *newcred, *oldcred; 640 gid_t gid; 641 int error; 642 643 gid = uap->gid; 644 mtx_lock(&Giant); 645 error = 0; 646 oldcred = p->p_ucred; 647 648 /* 649 * See if we have "permission" by POSIX 1003.1 rules. 650 * 651 * Note that setgid(getegid()) is a special case of 652 * "appropriate privileges" in appendix B.4.2.2. We need 653 * to use this clause to be compatible with traditional BSD 654 * semantics. Basically, it means that "setgid(xx)" sets all 655 * three id's (assuming you have privs). 656 * 657 * For notes on the logic here, see setuid() above. 658 */ 659 if (gid != oldcred->cr_rgid && /* allow setgid(getgid()) */ 660#ifdef _POSIX_SAVED_IDS 661 gid != oldcred->cr_svgid && /* allow setgid(saved gid) */ 662#endif 663#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 664 gid != oldcred->cr_groups[0] && /* allow setgid(getegid()) */ 665#endif 666 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 667 goto done2; 668 669 newcred = crdup(oldcred); 670#ifdef _POSIX_SAVED_IDS 671 /* 672 * Do we have "appropriate privileges" (are we root or gid == egid) 673 * If so, we are changing the real uid and saved gid. 674 */ 675 if ( 676#ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */ 677 gid == oldcred->cr_groups[0] || 678#endif 679 suser_xxx(oldcred, NULL, PRISON_ROOT) == 0) /* we are using privs */ 680#endif 681 { 682 /* 683 * Set real gid 684 */ 685 if (oldcred->cr_rgid != gid) { 686 change_rgid(newcred, gid); 687 setsugid(p); 688 } 689 /* 690 * Set saved gid 691 * 692 * XXX always set saved gid even if not _POSIX_SAVED_IDS, as 693 * the security of setegid() depends on it. B.4.2.2 says it 694 * is important that we should do this. 695 */ 696 if (oldcred->cr_svgid != gid) { 697 change_svgid(newcred, gid); 698 setsugid(p); 699 } 700 } 701 /* 702 * In all cases permitted cases, we are changing the egid. 703 * Copy credentials so other references do not see our changes. 704 */ 705 if (oldcred->cr_groups[0] != gid) { 706 change_egid(newcred, gid); 707 setsugid(p); 708 } 709 p->p_ucred = newcred; 710 crfree(oldcred); 711done2: 712 mtx_unlock(&Giant); 713 return (error); 714} 715 716#ifndef _SYS_SYSPROTO_H_ 717struct setegid_args { 718 gid_t egid; 719}; 720#endif 721/* 722 * MPSAFE 723 */ 724/* ARGSUSED */ 725int 726setegid(td, uap) 727 struct thread *td; 728 struct setegid_args *uap; 729{ 730 struct proc *p = td->td_proc; 731 struct ucred *newcred, *oldcred; 732 gid_t egid; 733 int error; 734 735 egid = uap->egid; 736 mtx_lock(&Giant); 737 error = 0; 738 oldcred = p->p_ucred; 739 if (egid != oldcred->cr_rgid && /* allow setegid(getgid()) */ 740 egid != oldcred->cr_svgid && /* allow setegid(saved gid) */ 741 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 742 goto done2; 743 newcred = crdup(oldcred); 744 if (oldcred->cr_groups[0] != egid) { 745 change_egid(newcred, egid); 746 setsugid(p); 747 } 748 p->p_ucred = newcred; 749 crfree(oldcred); 750done2: 751 mtx_unlock(&Giant); 752 return (error); 753} 754 755#ifndef _SYS_SYSPROTO_H_ 756struct setgroups_args { 757 u_int gidsetsize; 758 gid_t *gidset; 759}; 760#endif 761/* 762 * MPSAFE 763 */ 764/* ARGSUSED */ 765int 766setgroups(td, uap) 767 struct thread *td; 768 struct setgroups_args *uap; 769{ 770 struct proc *p = td->td_proc; 771 struct ucred *newcred, *oldcred; 772 u_int ngrp; 773 int error; 774 775 ngrp = uap->gidsetsize; 776 mtx_lock(&Giant); 777 oldcred = p->p_ucred; 778 if ((error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 779 goto done2; 780 if (ngrp > NGROUPS) { 781 error = EINVAL; 782 goto done2; 783 } 784 /* 785 * XXX A little bit lazy here. We could test if anything has 786 * changed before crcopy() and setting P_SUGID. 787 */ 788 newcred = crdup(oldcred); 789 if (ngrp < 1) { 790 /* 791 * setgroups(0, NULL) is a legitimate way of clearing the 792 * groups vector on non-BSD systems (which generally do not 793 * have the egid in the groups[0]). We risk security holes 794 * when running non-BSD software if we do not do the same. 795 */ 796 newcred->cr_ngroups = 1; 797 } else { 798 if ((error = copyin((caddr_t)uap->gidset, 799 (caddr_t)newcred->cr_groups, ngrp * sizeof(gid_t)))) { 800 crfree(newcred); 801 goto done2; 802 } 803 newcred->cr_ngroups = ngrp; 804 } 805 setsugid(p); 806 p->p_ucred = newcred; 807 crfree(oldcred); 808done2: 809 mtx_unlock(&Giant); 810 return (error); 811} 812 813#ifndef _SYS_SYSPROTO_H_ 814struct setreuid_args { 815 uid_t ruid; 816 uid_t euid; 817}; 818#endif 819/* 820 * MPSAFE 821 */ 822/* ARGSUSED */ 823int 824setreuid(td, uap) 825 register struct thread *td; 826 struct setreuid_args *uap; 827{ 828 struct proc *p = td->td_proc; 829 struct ucred *newcred, *oldcred; 830 uid_t euid, ruid; 831 int error; 832 833 euid = uap->euid; 834 ruid = uap->ruid; 835 mtx_lock(&Giant); 836 error = 0; 837 oldcred = p->p_ucred; 838 if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && 839 ruid != oldcred->cr_svuid) || 840 (euid != (uid_t)-1 && euid != oldcred->cr_uid && 841 euid != oldcred->cr_ruid && euid != oldcred->cr_svuid)) && 842 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 843 goto done2; 844 newcred = crdup(oldcred); 845 if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { 846 change_euid(newcred, euid); 847 setsugid(p); 848 } 849 if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { 850 change_ruid(newcred, ruid); 851 setsugid(p); 852 } 853 if ((ruid != (uid_t)-1 || newcred->cr_uid != newcred->cr_ruid) && 854 newcred->cr_svuid != newcred->cr_uid) { 855 change_svuid(newcred, newcred->cr_uid); 856 setsugid(p); 857 } 858 p->p_ucred = newcred; 859 crfree(oldcred); 860done2: 861 mtx_unlock(&Giant); 862 return (error); 863} 864 865#ifndef _SYS_SYSPROTO_H_ 866struct setregid_args { 867 gid_t rgid; 868 gid_t egid; 869}; 870#endif 871/* 872 * MPSAFE 873 */ 874/* ARGSUSED */ 875int 876setregid(td, uap) 877 register struct thread *td; 878 struct setregid_args *uap; 879{ 880 struct proc *p = td->td_proc; 881 struct ucred *newcred, *oldcred; 882 gid_t egid, rgid; 883 int error; 884 885 egid = uap->egid; 886 rgid = uap->rgid; 887 mtx_lock(&Giant); 888 error = 0; 889 oldcred = p->p_ucred; 890 if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && 891 rgid != oldcred->cr_svgid) || 892 (egid != (gid_t)-1 && egid != oldcred->cr_groups[0] && 893 egid != oldcred->cr_rgid && egid != oldcred->cr_svgid)) && 894 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 895 goto done2; 896 newcred = crdup(oldcred); 897 if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { 898 change_egid(newcred, egid); 899 setsugid(p); 900 } 901 if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { 902 change_rgid(newcred, rgid); 903 setsugid(p); 904 } 905 if ((rgid != (gid_t)-1 || newcred->cr_groups[0] != newcred->cr_rgid) && 906 newcred->cr_svgid != newcred->cr_groups[0]) { 907 change_svgid(newcred, newcred->cr_groups[0]); 908 setsugid(p); 909 } 910 p->p_ucred = newcred; 911 crfree(oldcred); 912done2: 913 mtx_unlock(&Giant); 914 return (error); 915} 916 917/* 918 * setresuid(ruid, euid, suid) is like setreuid except control over the 919 * saved uid is explicit. 920 */ 921 922#ifndef _SYS_SYSPROTO_H_ 923struct setresuid_args { 924 uid_t ruid; 925 uid_t euid; 926 uid_t suid; 927}; 928#endif 929/* 930 * MPSAFE 931 */ 932/* ARGSUSED */ 933int 934setresuid(td, uap) 935 register struct thread *td; 936 struct setresuid_args *uap; 937{ 938 struct proc *p = td->td_proc; 939 struct ucred *newcred, *oldcred; 940 uid_t euid, ruid, suid; 941 int error; 942 943 euid = uap->euid; 944 ruid = uap->ruid; 945 suid = uap->suid; 946 mtx_lock(&Giant); 947 oldcred = p->p_ucred; 948 if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && 949 ruid != oldcred->cr_svuid && 950 ruid != oldcred->cr_uid) || 951 (euid != (uid_t)-1 && euid != oldcred->cr_ruid && 952 euid != oldcred->cr_svuid && 953 euid != oldcred->cr_uid) || 954 (suid != (uid_t)-1 && suid != oldcred->cr_ruid && 955 suid != oldcred->cr_svuid && 956 suid != oldcred->cr_uid)) && 957 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 958 goto done2; 959 newcred = crdup(oldcred); 960 if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { 961 change_euid(newcred, euid); 962 setsugid(p); 963 } 964 if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { 965 change_ruid(newcred, ruid); 966 setsugid(p); 967 } 968 if (suid != (uid_t)-1 && oldcred->cr_svuid != suid) { 969 change_svuid(newcred, suid); 970 setsugid(p); 971 } 972 p->p_ucred = newcred; 973 crfree(oldcred); 974 error = 0; 975done2: 976 mtx_unlock(&Giant); 977 return (error); 978} 979 980/* 981 * setresgid(rgid, egid, sgid) is like setregid except control over the 982 * saved gid is explicit. 983 */ 984 985#ifndef _SYS_SYSPROTO_H_ 986struct setresgid_args { 987 gid_t rgid; 988 gid_t egid; 989 gid_t sgid; 990}; 991#endif 992/* 993 * MPSAFE 994 */ 995/* ARGSUSED */ 996int 997setresgid(td, uap) 998 register struct thread *td; 999 struct setresgid_args *uap; 1000{ 1001 struct proc *p = td->td_proc; 1002 struct ucred *newcred, *oldcred; 1003 gid_t egid, rgid, sgid; 1004 int error; 1005 1006 egid = uap->egid; 1007 rgid = uap->rgid; 1008 sgid = uap->sgid; 1009 mtx_lock(&Giant); 1010 oldcred = p->p_ucred; 1011 if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && 1012 rgid != oldcred->cr_svgid && 1013 rgid != oldcred->cr_groups[0]) || 1014 (egid != (gid_t)-1 && egid != oldcred->cr_rgid && 1015 egid != oldcred->cr_svgid && 1016 egid != oldcred->cr_groups[0]) || 1017 (sgid != (gid_t)-1 && sgid != oldcred->cr_rgid && 1018 sgid != oldcred->cr_svgid && 1019 sgid != oldcred->cr_groups[0])) && 1020 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 1021 goto done2; 1022 newcred = crdup(oldcred); 1023 if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { 1024 change_egid(newcred, egid); 1025 setsugid(p); 1026 } 1027 if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { 1028 change_rgid(newcred, rgid); 1029 setsugid(p); 1030 } 1031 if (sgid != (gid_t)-1 && oldcred->cr_svgid != sgid) { 1032 change_svgid(newcred, sgid); 1033 setsugid(p); 1034 } 1035 p->p_ucred = newcred; 1036 crfree(oldcred); 1037 error = 0; 1038done2: 1039 mtx_unlock(&Giant); 1040 return (error); 1041} 1042 1043#ifndef _SYS_SYSPROTO_H_ 1044struct getresuid_args { 1045 uid_t *ruid; 1046 uid_t *euid; 1047 uid_t *suid; 1048}; 1049#endif 1050/* 1051 * MPSAFE 1052 */ 1053/* ARGSUSED */ 1054int 1055getresuid(td, uap) 1056 register struct thread *td; 1057 struct getresuid_args *uap; 1058{ 1059 struct ucred *cred; 1060 struct proc *p = td->td_proc; 1061 int error1 = 0, error2 = 0, error3 = 0; 1062 1063 mtx_lock(&Giant); 1064 cred = p->p_ucred; 1065 if (uap->ruid) 1066 error1 = copyout((caddr_t)&cred->cr_ruid, 1067 (caddr_t)uap->ruid, sizeof(cred->cr_ruid)); 1068 if (uap->euid) 1069 error2 = copyout((caddr_t)&cred->cr_uid, 1070 (caddr_t)uap->euid, sizeof(cred->cr_uid)); 1071 if (uap->suid) 1072 error3 = copyout((caddr_t)&cred->cr_svuid, 1073 (caddr_t)uap->suid, sizeof(cred->cr_svuid)); 1074 mtx_unlock(&Giant); 1075 return (error1 ? error1 : error2 ? error2 : error3); 1076} 1077 1078#ifndef _SYS_SYSPROTO_H_ 1079struct getresgid_args { 1080 gid_t *rgid; 1081 gid_t *egid; 1082 gid_t *sgid; 1083}; 1084#endif 1085/* 1086 * MPSAFE 1087 */ 1088/* ARGSUSED */ 1089int 1090getresgid(td, uap) 1091 register struct thread *td; 1092 struct getresgid_args *uap; 1093{ 1094 struct ucred *cred; 1095 struct proc *p = td->td_proc; 1096 int error1 = 0, error2 = 0, error3 = 0; 1097 1098 mtx_lock(&Giant); 1099 cred = p->p_ucred; 1100 if (uap->rgid) 1101 error1 = copyout((caddr_t)&cred->cr_rgid, 1102 (caddr_t)uap->rgid, sizeof(cred->cr_rgid)); 1103 if (uap->egid) 1104 error2 = copyout((caddr_t)&cred->cr_groups[0], 1105 (caddr_t)uap->egid, sizeof(cred->cr_groups[0])); 1106 if (uap->sgid) 1107 error3 = copyout((caddr_t)&cred->cr_svgid, 1108 (caddr_t)uap->sgid, sizeof(cred->cr_svgid)); 1109 mtx_unlock(&Giant); 1110 return (error1 ? error1 : error2 ? error2 : error3); 1111} 1112 1113#ifndef _SYS_SYSPROTO_H_ 1114struct issetugid_args { 1115 int dummy; 1116}; 1117#endif 1118/* 1119 * NOT MPSAFE? 1120 */ 1121/* ARGSUSED */ 1122int 1123issetugid(td, uap) 1124 register struct thread *td; 1125 struct issetugid_args *uap; 1126{ 1127 struct proc *p = td->td_proc; 1128 1129 /* 1130 * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time, 1131 * we use P_SUGID because we consider changing the owners as 1132 * "tainting" as well. 1133 * This is significant for procs that start as root and "become" 1134 * a user without an exec - programs cannot know *everything* 1135 * that libc *might* have put in their data segment. 1136 */
| 535 return (error); 536} 537 538/* 539 * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD 540 * compatible. It says that setting the uid/gid to euid/egid is a special 541 * case of "appropriate privilege". Once the rules are expanded out, this 542 * basically means that setuid(nnn) sets all three id's, in all permitted 543 * cases unless _POSIX_SAVED_IDS is enabled. In that case, setuid(getuid()) 544 * does not set the saved id - this is dangerous for traditional BSD 545 * programs. For this reason, we *really* do not want to set 546 * _POSIX_SAVED_IDS and do not want to clear POSIX_APPENDIX_B_4_2_2. 547 */ 548#define POSIX_APPENDIX_B_4_2_2 549 550#ifndef _SYS_SYSPROTO_H_ 551struct setuid_args { 552 uid_t uid; 553}; 554#endif 555/* 556 * MPSAFE 557 */ 558/* ARGSUSED */ 559int 560setuid(td, uap) 561 struct thread *td; 562 struct setuid_args *uap; 563{ 564 struct proc *p = td->td_proc; 565 struct ucred *newcred, *oldcred; 566 uid_t uid; 567 int error; 568 569 uid = uap->uid; 570 mtx_lock(&Giant); 571 error = 0; 572 oldcred = p->p_ucred; 573 574 /* 575 * See if we have "permission" by POSIX 1003.1 rules. 576 * 577 * Note that setuid(geteuid()) is a special case of 578 * "appropriate privileges" in appendix B.4.2.2. We need 579 * to use this clause to be compatible with traditional BSD 580 * semantics. Basically, it means that "setuid(xx)" sets all 581 * three id's (assuming you have privs). 582 * 583 * Notes on the logic. We do things in three steps. 584 * 1: We determine if the euid is going to change, and do EPERM 585 * right away. We unconditionally change the euid later if this 586 * test is satisfied, simplifying that part of the logic. 587 * 2: We determine if the real and/or saved uids are going to 588 * change. Determined by compile options. 589 * 3: Change euid last. (after tests in #2 for "appropriate privs") 590 */ 591 if (uid != oldcred->cr_ruid && /* allow setuid(getuid()) */ 592#ifdef _POSIX_SAVED_IDS 593 uid != oldcred->cr_svuid && /* allow setuid(saved gid) */ 594#endif 595#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 596 uid != oldcred->cr_uid && /* allow setuid(geteuid()) */ 597#endif 598 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 599 goto done2; 600 601 newcred = crdup(oldcred); 602#ifdef _POSIX_SAVED_IDS 603 /* 604 * Do we have "appropriate privileges" (are we root or uid == euid) 605 * If so, we are changing the real uid and/or saved uid. 606 */ 607 if ( 608#ifdef POSIX_APPENDIX_B_4_2_2 /* Use the clause from B.4.2.2 */ 609 uid == oldcred->cr_uid || 610#endif 611 suser_xxx(oldcred, NULL, PRISON_ROOT) == 0) /* we are using privs */ 612#endif 613 { 614 /* 615 * Set the real uid and transfer proc count to new user. 616 */ 617 if (uid != oldcred->cr_ruid) { 618 change_ruid(newcred, uid); 619 setsugid(p); 620 } 621 /* 622 * Set saved uid 623 * 624 * XXX always set saved uid even if not _POSIX_SAVED_IDS, as 625 * the security of seteuid() depends on it. B.4.2.2 says it 626 * is important that we should do this. 627 */ 628 if (uid != oldcred->cr_svuid) { 629 change_svuid(newcred, uid); 630 setsugid(p); 631 } 632 } 633 634 /* 635 * In all permitted cases, we are changing the euid. 636 * Copy credentials so other references do not see our changes. 637 */ 638 if (uid != oldcred->cr_uid) { 639 change_euid(newcred, uid); 640 setsugid(p); 641 } 642 p->p_ucred = newcred; 643 crfree(oldcred); 644done2: 645 mtx_unlock(&Giant); 646 return (error); 647} 648 649#ifndef _SYS_SYSPROTO_H_ 650struct seteuid_args { 651 uid_t euid; 652}; 653#endif 654/* 655 * MPSAFE 656 */ 657/* ARGSUSED */ 658int 659seteuid(td, uap) 660 struct thread *td; 661 struct seteuid_args *uap; 662{ 663 struct proc *p = td->td_proc; 664 struct ucred *newcred, *oldcred; 665 uid_t euid; 666 int error; 667 668 euid = uap->euid; 669 mtx_lock(&Giant); 670 error = 0; 671 oldcred = p->p_ucred; 672 if (euid != oldcred->cr_ruid && /* allow seteuid(getuid()) */ 673 euid != oldcred->cr_svuid && /* allow seteuid(saved uid) */ 674 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 675 goto done2; 676 /* 677 * Everything's okay, do it. Copy credentials so other references do 678 * not see our changes. 679 */ 680 newcred = crdup(oldcred); 681 if (oldcred->cr_uid != euid) { 682 change_euid(newcred, euid); 683 setsugid(p); 684 } 685 p->p_ucred = newcred; 686 crfree(oldcred); 687done2: 688 mtx_unlock(&Giant); 689 return (error); 690} 691 692#ifndef _SYS_SYSPROTO_H_ 693struct setgid_args { 694 gid_t gid; 695}; 696#endif 697/* 698 * MPSAFE 699 */ 700/* ARGSUSED */ 701int 702setgid(td, uap) 703 struct thread *td; 704 struct setgid_args *uap; 705{ 706 struct proc *p = td->td_proc; 707 struct ucred *newcred, *oldcred; 708 gid_t gid; 709 int error; 710 711 gid = uap->gid; 712 mtx_lock(&Giant); 713 error = 0; 714 oldcred = p->p_ucred; 715 716 /* 717 * See if we have "permission" by POSIX 1003.1 rules. 718 * 719 * Note that setgid(getegid()) is a special case of 720 * "appropriate privileges" in appendix B.4.2.2. We need 721 * to use this clause to be compatible with traditional BSD 722 * semantics. Basically, it means that "setgid(xx)" sets all 723 * three id's (assuming you have privs). 724 * 725 * For notes on the logic here, see setuid() above. 726 */ 727 if (gid != oldcred->cr_rgid && /* allow setgid(getgid()) */ 728#ifdef _POSIX_SAVED_IDS 729 gid != oldcred->cr_svgid && /* allow setgid(saved gid) */ 730#endif 731#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 732 gid != oldcred->cr_groups[0] && /* allow setgid(getegid()) */ 733#endif 734 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 735 goto done2; 736 737 newcred = crdup(oldcred); 738#ifdef _POSIX_SAVED_IDS 739 /* 740 * Do we have "appropriate privileges" (are we root or gid == egid) 741 * If so, we are changing the real uid and saved gid. 742 */ 743 if ( 744#ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */ 745 gid == oldcred->cr_groups[0] || 746#endif 747 suser_xxx(oldcred, NULL, PRISON_ROOT) == 0) /* we are using privs */ 748#endif 749 { 750 /* 751 * Set real gid 752 */ 753 if (oldcred->cr_rgid != gid) { 754 change_rgid(newcred, gid); 755 setsugid(p); 756 } 757 /* 758 * Set saved gid 759 * 760 * XXX always set saved gid even if not _POSIX_SAVED_IDS, as 761 * the security of setegid() depends on it. B.4.2.2 says it 762 * is important that we should do this. 763 */ 764 if (oldcred->cr_svgid != gid) { 765 change_svgid(newcred, gid); 766 setsugid(p); 767 } 768 } 769 /* 770 * In all cases permitted cases, we are changing the egid. 771 * Copy credentials so other references do not see our changes. 772 */ 773 if (oldcred->cr_groups[0] != gid) { 774 change_egid(newcred, gid); 775 setsugid(p); 776 } 777 p->p_ucred = newcred; 778 crfree(oldcred); 779done2: 780 mtx_unlock(&Giant); 781 return (error); 782} 783 784#ifndef _SYS_SYSPROTO_H_ 785struct setegid_args { 786 gid_t egid; 787}; 788#endif 789/* 790 * MPSAFE 791 */ 792/* ARGSUSED */ 793int 794setegid(td, uap) 795 struct thread *td; 796 struct setegid_args *uap; 797{ 798 struct proc *p = td->td_proc; 799 struct ucred *newcred, *oldcred; 800 gid_t egid; 801 int error; 802 803 egid = uap->egid; 804 mtx_lock(&Giant); 805 error = 0; 806 oldcred = p->p_ucred; 807 if (egid != oldcred->cr_rgid && /* allow setegid(getgid()) */ 808 egid != oldcred->cr_svgid && /* allow setegid(saved gid) */ 809 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 810 goto done2; 811 newcred = crdup(oldcred); 812 if (oldcred->cr_groups[0] != egid) { 813 change_egid(newcred, egid); 814 setsugid(p); 815 } 816 p->p_ucred = newcred; 817 crfree(oldcred); 818done2: 819 mtx_unlock(&Giant); 820 return (error); 821} 822 823#ifndef _SYS_SYSPROTO_H_ 824struct setgroups_args { 825 u_int gidsetsize; 826 gid_t *gidset; 827}; 828#endif 829/* 830 * MPSAFE 831 */ 832/* ARGSUSED */ 833int 834setgroups(td, uap) 835 struct thread *td; 836 struct setgroups_args *uap; 837{ 838 struct proc *p = td->td_proc; 839 struct ucred *newcred, *oldcred; 840 u_int ngrp; 841 int error; 842 843 ngrp = uap->gidsetsize; 844 mtx_lock(&Giant); 845 oldcred = p->p_ucred; 846 if ((error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 847 goto done2; 848 if (ngrp > NGROUPS) { 849 error = EINVAL; 850 goto done2; 851 } 852 /* 853 * XXX A little bit lazy here. We could test if anything has 854 * changed before crcopy() and setting P_SUGID. 855 */ 856 newcred = crdup(oldcred); 857 if (ngrp < 1) { 858 /* 859 * setgroups(0, NULL) is a legitimate way of clearing the 860 * groups vector on non-BSD systems (which generally do not 861 * have the egid in the groups[0]). We risk security holes 862 * when running non-BSD software if we do not do the same. 863 */ 864 newcred->cr_ngroups = 1; 865 } else { 866 if ((error = copyin((caddr_t)uap->gidset, 867 (caddr_t)newcred->cr_groups, ngrp * sizeof(gid_t)))) { 868 crfree(newcred); 869 goto done2; 870 } 871 newcred->cr_ngroups = ngrp; 872 } 873 setsugid(p); 874 p->p_ucred = newcred; 875 crfree(oldcred); 876done2: 877 mtx_unlock(&Giant); 878 return (error); 879} 880 881#ifndef _SYS_SYSPROTO_H_ 882struct setreuid_args { 883 uid_t ruid; 884 uid_t euid; 885}; 886#endif 887/* 888 * MPSAFE 889 */ 890/* ARGSUSED */ 891int 892setreuid(td, uap) 893 register struct thread *td; 894 struct setreuid_args *uap; 895{ 896 struct proc *p = td->td_proc; 897 struct ucred *newcred, *oldcred; 898 uid_t euid, ruid; 899 int error; 900 901 euid = uap->euid; 902 ruid = uap->ruid; 903 mtx_lock(&Giant); 904 error = 0; 905 oldcred = p->p_ucred; 906 if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && 907 ruid != oldcred->cr_svuid) || 908 (euid != (uid_t)-1 && euid != oldcred->cr_uid && 909 euid != oldcred->cr_ruid && euid != oldcred->cr_svuid)) && 910 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 911 goto done2; 912 newcred = crdup(oldcred); 913 if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { 914 change_euid(newcred, euid); 915 setsugid(p); 916 } 917 if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { 918 change_ruid(newcred, ruid); 919 setsugid(p); 920 } 921 if ((ruid != (uid_t)-1 || newcred->cr_uid != newcred->cr_ruid) && 922 newcred->cr_svuid != newcred->cr_uid) { 923 change_svuid(newcred, newcred->cr_uid); 924 setsugid(p); 925 } 926 p->p_ucred = newcred; 927 crfree(oldcred); 928done2: 929 mtx_unlock(&Giant); 930 return (error); 931} 932 933#ifndef _SYS_SYSPROTO_H_ 934struct setregid_args { 935 gid_t rgid; 936 gid_t egid; 937}; 938#endif 939/* 940 * MPSAFE 941 */ 942/* ARGSUSED */ 943int 944setregid(td, uap) 945 register struct thread *td; 946 struct setregid_args *uap; 947{ 948 struct proc *p = td->td_proc; 949 struct ucred *newcred, *oldcred; 950 gid_t egid, rgid; 951 int error; 952 953 egid = uap->egid; 954 rgid = uap->rgid; 955 mtx_lock(&Giant); 956 error = 0; 957 oldcred = p->p_ucred; 958 if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && 959 rgid != oldcred->cr_svgid) || 960 (egid != (gid_t)-1 && egid != oldcred->cr_groups[0] && 961 egid != oldcred->cr_rgid && egid != oldcred->cr_svgid)) && 962 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 963 goto done2; 964 newcred = crdup(oldcred); 965 if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { 966 change_egid(newcred, egid); 967 setsugid(p); 968 } 969 if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { 970 change_rgid(newcred, rgid); 971 setsugid(p); 972 } 973 if ((rgid != (gid_t)-1 || newcred->cr_groups[0] != newcred->cr_rgid) && 974 newcred->cr_svgid != newcred->cr_groups[0]) { 975 change_svgid(newcred, newcred->cr_groups[0]); 976 setsugid(p); 977 } 978 p->p_ucred = newcred; 979 crfree(oldcred); 980done2: 981 mtx_unlock(&Giant); 982 return (error); 983} 984 985/* 986 * setresuid(ruid, euid, suid) is like setreuid except control over the 987 * saved uid is explicit. 988 */ 989 990#ifndef _SYS_SYSPROTO_H_ 991struct setresuid_args { 992 uid_t ruid; 993 uid_t euid; 994 uid_t suid; 995}; 996#endif 997/* 998 * MPSAFE 999 */ 1000/* ARGSUSED */ 1001int 1002setresuid(td, uap) 1003 register struct thread *td; 1004 struct setresuid_args *uap; 1005{ 1006 struct proc *p = td->td_proc; 1007 struct ucred *newcred, *oldcred; 1008 uid_t euid, ruid, suid; 1009 int error; 1010 1011 euid = uap->euid; 1012 ruid = uap->ruid; 1013 suid = uap->suid; 1014 mtx_lock(&Giant); 1015 oldcred = p->p_ucred; 1016 if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && 1017 ruid != oldcred->cr_svuid && 1018 ruid != oldcred->cr_uid) || 1019 (euid != (uid_t)-1 && euid != oldcred->cr_ruid && 1020 euid != oldcred->cr_svuid && 1021 euid != oldcred->cr_uid) || 1022 (suid != (uid_t)-1 && suid != oldcred->cr_ruid && 1023 suid != oldcred->cr_svuid && 1024 suid != oldcred->cr_uid)) && 1025 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 1026 goto done2; 1027 newcred = crdup(oldcred); 1028 if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { 1029 change_euid(newcred, euid); 1030 setsugid(p); 1031 } 1032 if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { 1033 change_ruid(newcred, ruid); 1034 setsugid(p); 1035 } 1036 if (suid != (uid_t)-1 && oldcred->cr_svuid != suid) { 1037 change_svuid(newcred, suid); 1038 setsugid(p); 1039 } 1040 p->p_ucred = newcred; 1041 crfree(oldcred); 1042 error = 0; 1043done2: 1044 mtx_unlock(&Giant); 1045 return (error); 1046} 1047 1048/* 1049 * setresgid(rgid, egid, sgid) is like setregid except control over the 1050 * saved gid is explicit. 1051 */ 1052 1053#ifndef _SYS_SYSPROTO_H_ 1054struct setresgid_args { 1055 gid_t rgid; 1056 gid_t egid; 1057 gid_t sgid; 1058}; 1059#endif 1060/* 1061 * MPSAFE 1062 */ 1063/* ARGSUSED */ 1064int 1065setresgid(td, uap) 1066 register struct thread *td; 1067 struct setresgid_args *uap; 1068{ 1069 struct proc *p = td->td_proc; 1070 struct ucred *newcred, *oldcred; 1071 gid_t egid, rgid, sgid; 1072 int error; 1073 1074 egid = uap->egid; 1075 rgid = uap->rgid; 1076 sgid = uap->sgid; 1077 mtx_lock(&Giant); 1078 oldcred = p->p_ucred; 1079 if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && 1080 rgid != oldcred->cr_svgid && 1081 rgid != oldcred->cr_groups[0]) || 1082 (egid != (gid_t)-1 && egid != oldcred->cr_rgid && 1083 egid != oldcred->cr_svgid && 1084 egid != oldcred->cr_groups[0]) || 1085 (sgid != (gid_t)-1 && sgid != oldcred->cr_rgid && 1086 sgid != oldcred->cr_svgid && 1087 sgid != oldcred->cr_groups[0])) && 1088 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 1089 goto done2; 1090 newcred = crdup(oldcred); 1091 if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { 1092 change_egid(newcred, egid); 1093 setsugid(p); 1094 } 1095 if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { 1096 change_rgid(newcred, rgid); 1097 setsugid(p); 1098 } 1099 if (sgid != (gid_t)-1 && oldcred->cr_svgid != sgid) { 1100 change_svgid(newcred, sgid); 1101 setsugid(p); 1102 } 1103 p->p_ucred = newcred; 1104 crfree(oldcred); 1105 error = 0; 1106done2: 1107 mtx_unlock(&Giant); 1108 return (error); 1109} 1110 1111#ifndef _SYS_SYSPROTO_H_ 1112struct getresuid_args { 1113 uid_t *ruid; 1114 uid_t *euid; 1115 uid_t *suid; 1116}; 1117#endif 1118/* 1119 * MPSAFE 1120 */ 1121/* ARGSUSED */ 1122int 1123getresuid(td, uap) 1124 register struct thread *td; 1125 struct getresuid_args *uap; 1126{ 1127 struct ucred *cred; 1128 struct proc *p = td->td_proc; 1129 int error1 = 0, error2 = 0, error3 = 0; 1130 1131 mtx_lock(&Giant); 1132 cred = p->p_ucred; 1133 if (uap->ruid) 1134 error1 = copyout((caddr_t)&cred->cr_ruid, 1135 (caddr_t)uap->ruid, sizeof(cred->cr_ruid)); 1136 if (uap->euid) 1137 error2 = copyout((caddr_t)&cred->cr_uid, 1138 (caddr_t)uap->euid, sizeof(cred->cr_uid)); 1139 if (uap->suid) 1140 error3 = copyout((caddr_t)&cred->cr_svuid, 1141 (caddr_t)uap->suid, sizeof(cred->cr_svuid)); 1142 mtx_unlock(&Giant); 1143 return (error1 ? error1 : error2 ? error2 : error3); 1144} 1145 1146#ifndef _SYS_SYSPROTO_H_ 1147struct getresgid_args { 1148 gid_t *rgid; 1149 gid_t *egid; 1150 gid_t *sgid; 1151}; 1152#endif 1153/* 1154 * MPSAFE 1155 */ 1156/* ARGSUSED */ 1157int 1158getresgid(td, uap) 1159 register struct thread *td; 1160 struct getresgid_args *uap; 1161{ 1162 struct ucred *cred; 1163 struct proc *p = td->td_proc; 1164 int error1 = 0, error2 = 0, error3 = 0; 1165 1166 mtx_lock(&Giant); 1167 cred = p->p_ucred; 1168 if (uap->rgid) 1169 error1 = copyout((caddr_t)&cred->cr_rgid, 1170 (caddr_t)uap->rgid, sizeof(cred->cr_rgid)); 1171 if (uap->egid) 1172 error2 = copyout((caddr_t)&cred->cr_groups[0], 1173 (caddr_t)uap->egid, sizeof(cred->cr_groups[0])); 1174 if (uap->sgid) 1175 error3 = copyout((caddr_t)&cred->cr_svgid, 1176 (caddr_t)uap->sgid, sizeof(cred->cr_svgid)); 1177 mtx_unlock(&Giant); 1178 return (error1 ? error1 : error2 ? error2 : error3); 1179} 1180 1181#ifndef _SYS_SYSPROTO_H_ 1182struct issetugid_args { 1183 int dummy; 1184}; 1185#endif 1186/* 1187 * NOT MPSAFE? 1188 */ 1189/* ARGSUSED */ 1190int 1191issetugid(td, uap) 1192 register struct thread *td; 1193 struct issetugid_args *uap; 1194{ 1195 struct proc *p = td->td_proc; 1196 1197 /* 1198 * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time, 1199 * we use P_SUGID because we consider changing the owners as 1200 * "tainting" as well. 1201 * This is significant for procs that start as root and "become" 1202 * a user without an exec - programs cannot know *everything* 1203 * that libc *might* have put in their data segment. 1204 */
|
| 1205 PROC_LOCK(p);
|
1137 td->td_retval[0] = (p->p_flag & P_SUGID) ? 1 : 0;
| 1206 td->td_retval[0] = (p->p_flag & P_SUGID) ? 1 : 0;
|
| 1207 PROC_UNLOCK(p);
|
1138 return (0); 1139} 1140 1141/* 1142 * MPSAFE 1143 */ 1144int 1145__setugid(td, uap) 1146 struct thread *td; 1147 struct __setugid_args *uap; 1148{ 1149#ifdef REGRESSION 1150 int error; 1151 1152 mtx_lock(&Giant); 1153 error = 0; 1154 switch (uap->flag) { 1155 case 0:
| 1208 return (0); 1209} 1210 1211/* 1212 * MPSAFE 1213 */ 1214int 1215__setugid(td, uap) 1216 struct thread *td; 1217 struct __setugid_args *uap; 1218{ 1219#ifdef REGRESSION 1220 int error; 1221 1222 mtx_lock(&Giant); 1223 error = 0; 1224 switch (uap->flag) { 1225 case 0:
|
| 1226 PROC_LOCK(td->td_proc);
|
1156 td->td_proc->p_flag &= ~P_SUGID;
| 1227 td->td_proc->p_flag &= ~P_SUGID;
|
| 1228 PROC_UNLOCK(td->td_proc);
|
1157 break; 1158 case 1:
| 1229 break; 1230 case 1:
|
| 1231 PROC_LOCK(td->td_proc);
|
1159 td->td_proc->p_flag |= P_SUGID;
| 1232 td->td_proc->p_flag |= P_SUGID;
|
| 1233 PROC_UNLOCK(td->td_proc);
|
1160 break; 1161 default: 1162 error = EINVAL; 1163 break; 1164 } 1165 mtx_unlock(&Giant); 1166 return (error); 1167#else /* !REGRESSION */ 1168 1169 return (ENOSYS); 1170#endif /* REGRESSION */ 1171} 1172 1173/* 1174 * Check if gid is a member of the group set. 1175 */ 1176int 1177groupmember(gid, cred) 1178 gid_t gid; 1179 struct ucred *cred; 1180{ 1181 register gid_t *gp; 1182 gid_t *egp; 1183 1184 egp = &(cred->cr_groups[cred->cr_ngroups]); 1185 for (gp = cred->cr_groups; gp < egp; gp++) 1186 if (*gp == gid) 1187 return (1); 1188 return (0); 1189} 1190 1191/* 1192 * `suser_enabled' (which can be set by the security.suser_enabled 1193 * sysctl) determines whether the system 'super-user' policy is in effect. 1194 * If it is nonzero, an effective uid of 0 connotes special privilege, 1195 * overriding many mandatory and discretionary protections. If it is zero, 1196 * uid 0 is offered no special privilege in the kernel security policy. 1197 * Setting it to zero may seriously impact the functionality of many 1198 * existing userland programs, and should not be done without careful 1199 * consideration of the consequences. 1200 */ 1201int suser_enabled = 1; 1202SYSCTL_INT(_security_bsd, OID_AUTO, suser_enabled, CTLFLAG_RW, 1203 &suser_enabled, 0, "processes with uid 0 have privilege"); 1204TUNABLE_INT("security.bsd.suser_enabled", &suser_enabled); 1205 1206/* 1207 * Test whether the specified credentials imply "super-user" privilege. 1208 * Return 0 or EPERM. 1209 */ 1210int 1211suser(p) 1212 struct proc *p; 1213{ 1214 1215 return (suser_xxx(0, p, 0)); 1216} 1217 1218/* 1219 * version for when the thread pointer is available and not the proc. 1220 * (saves having to include proc.h into every file that needs to do the change.) 1221 */ 1222int 1223suser_td(td) 1224 struct thread *td; 1225{ 1226 return (suser_xxx(0, td->td_proc, 0)); 1227} 1228 1229/* 1230 * wrapper to use if you have the thread on hand but not the proc. 1231 */ 1232int 1233suser_xxx_td(cred, td, flag) 1234 struct ucred *cred; 1235 struct thread *td; 1236 int flag; 1237{ 1238 return(suser_xxx(cred, td->td_proc, flag)); 1239} 1240 1241int 1242suser_xxx(cred, proc, flag) 1243 struct ucred *cred; 1244 struct proc *proc; 1245 int flag; 1246{ 1247 if (!suser_enabled) 1248 return (EPERM); 1249 if (!cred && !proc) { 1250 printf("suser_xxx(): THINK!\n"); 1251 return (EPERM); 1252 } 1253 if (cred == NULL) 1254 cred = proc->p_ucred; 1255 if (cred->cr_uid != 0) 1256 return (EPERM); 1257 if (jailed(cred) && !(flag & PRISON_ROOT)) 1258 return (EPERM); 1259 return (0); 1260} 1261 1262/* 1263 * Test the active securelevel against a given level. securelevel_gt() 1264 * implements (securelevel > level). securelevel_ge() implements 1265 * (securelevel >= level). Note that the logic is inverted -- these 1266 * functions return EPERM on "success" and 0 on "failure". 1267 * 1268 * cr is permitted to be NULL for the time being, as there were some 1269 * existing securelevel checks that occurred without a process/credential 1270 * context. In the future this will be disallowed, so a kernel message 1271 * is displayed. 1272 */ 1273int 1274securelevel_gt(struct ucred *cr, int level) 1275{ 1276 int active_securelevel; 1277 1278 active_securelevel = securelevel; 1279 if (cr == NULL) 1280 printf("securelevel_gt: cr is NULL\n"); 1281 if (cr->cr_prison != NULL) { 1282 mtx_lock(&cr->cr_prison->pr_mtx); 1283 active_securelevel = imax(cr->cr_prison->pr_securelevel, 1284 active_securelevel); 1285 mtx_unlock(&cr->cr_prison->pr_mtx); 1286 } 1287 return (active_securelevel > level ? EPERM : 0); 1288} 1289 1290int 1291securelevel_ge(struct ucred *cr, int level) 1292{ 1293 int active_securelevel; 1294 1295 active_securelevel = securelevel; 1296 if (cr == NULL) 1297 printf("securelevel_gt: cr is NULL\n"); 1298 if (cr->cr_prison != NULL) { 1299 mtx_lock(&cr->cr_prison->pr_mtx); 1300 active_securelevel = imax(cr->cr_prison->pr_securelevel, 1301 active_securelevel); 1302 mtx_unlock(&cr->cr_prison->pr_mtx); 1303 } 1304 return (active_securelevel >= level ? EPERM : 0); 1305} 1306 1307/* 1308 * 'see_other_uids' determines whether or not visibility of processes 1309 * and sockets with credentials holding different real uids is possible 1310 * using a variety of system MIBs. 1311 * XXX: data declarations should be together near the beginning of the file. 1312 */ 1313static int see_other_uids = 1; 1314SYSCTL_INT(_security_bsd, OID_AUTO, see_other_uids, CTLFLAG_RW, 1315 &see_other_uids, 0, 1316 "Unprivileged processes may see subjects/objects with different real uid"); 1317 1318/*- 1319 * Determine if u1 "can see" the subject specified by u2. 1320 * Returns: 0 for permitted, an errno value otherwise 1321 * Locks: none 1322 * References: *u1 and *u2 must not change during the call 1323 * u1 may equal u2, in which case only one reference is required 1324 */ 1325int 1326cr_cansee(struct ucred *u1, struct ucred *u2) 1327{ 1328 int error; 1329 1330 if ((error = prison_check(u1, u2))) 1331 return (error); 1332 if (!see_other_uids && u1->cr_ruid != u2->cr_ruid) { 1333 if (suser_xxx(u1, NULL, PRISON_ROOT) != 0) 1334 return (ESRCH); 1335 } 1336 return (0); 1337} 1338 1339/*- 1340 * Determine if p1 "can see" the subject specified by p2. 1341 * Returns: 0 for permitted, an errno value otherwise 1342 * Locks: Sufficient locks to protect p1->p_ucred and p2->p_ucred must 1343 * be held. Normally, p1 will be curproc, and a lock must be held 1344 * for p2. 1345 * References: p1 and p2 must be valid for the lifetime of the call 1346 */ 1347int 1348p_cansee(struct proc *p1, struct proc *p2) 1349{ 1350 1351 /* Wrap cr_cansee() for all functionality. */ 1352 return (cr_cansee(p1->p_ucred, p2->p_ucred)); 1353} 1354 1355/*- 1356 * Determine whether cred may deliver the specified signal to proc. 1357 * Returns: 0 for permitted, an errno value otherwise. 1358 * Locks: A lock must be held for proc. 1359 * References: cred and proc must be valid for the lifetime of the call. 1360 */ 1361int 1362cr_cansignal(struct ucred *cred, struct proc *proc, int signum) 1363{ 1364 int error; 1365 1366 /* 1367 * Jail semantics limit the scope of signalling to proc in the 1368 * same jail as cred, if cred is in jail. 1369 */ 1370 error = prison_check(cred, proc->p_ucred); 1371 if (error) 1372 return (error); 1373 1374 /* 1375 * UNIX signal semantics depend on the status of the P_SUGID 1376 * bit on the target process. If the bit is set, then additional 1377 * restrictions are placed on the set of available signals. 1378 */ 1379 if (proc->p_flag & P_SUGID) { 1380 switch (signum) { 1381 case 0: 1382 case SIGKILL: 1383 case SIGINT: 1384 case SIGTERM: 1385 case SIGSTOP: 1386 case SIGTTIN: 1387 case SIGTTOU: 1388 case SIGTSTP: 1389 case SIGHUP: 1390 case SIGUSR1: 1391 case SIGUSR2: 1392 /* 1393 * Generally, permit job and terminal control 1394 * signals. 1395 */ 1396 break; 1397 default: 1398 /* Not permitted without privilege. */ 1399 error = suser_xxx(cred, NULL, PRISON_ROOT); 1400 if (error) 1401 return (error); 1402 } 1403 } 1404 1405 /* 1406 * Generally, the target credential's ruid or svuid must match the 1407 * subject credential's ruid or euid. 1408 */ 1409 if (cred->cr_ruid != proc->p_ucred->cr_ruid && 1410 cred->cr_ruid != proc->p_ucred->cr_svuid && 1411 cred->cr_uid != proc->p_ucred->cr_ruid && 1412 cred->cr_uid != proc->p_ucred->cr_svuid) { 1413 /* Not permitted without privilege. */ 1414 error = suser_xxx(cred, NULL, PRISON_ROOT); 1415 if (error) 1416 return (error); 1417 } 1418 1419 return (0); 1420} 1421 1422 1423/*- 1424 * Determine whether p1 may deliver the specified signal to p2. 1425 * Returns: 0 for permitted, an errno value otherwise 1426 * Locks: Sufficient locks to protect various components of p1 and p2 1427 * must be held. Normally, p1 will be curproc, and a lock must 1428 * be held for p2. 1429 * References: p1 and p2 must be valid for the lifetime of the call 1430 */ 1431int 1432p_cansignal(struct proc *p1, struct proc *p2, int signum) 1433{ 1434 1435 if (p1 == p2) 1436 return (0); 1437 1438 /* 1439 * UNIX signalling semantics require that processes in the same 1440 * session always be able to deliver SIGCONT to one another, 1441 * overriding the remaining protections. 1442 */ 1443 if (signum == SIGCONT && p1->p_session == p2->p_session) 1444 return (0); 1445 1446 return (cr_cansignal(p1->p_ucred, p2, signum)); 1447} 1448 1449/*- 1450 * Determine whether p1 may reschedule p2. 1451 * Returns: 0 for permitted, an errno value otherwise 1452 * Locks: Sufficient locks to protect various components of p1 and p2 1453 * must be held. Normally, p1 will be curproc, and a lock must 1454 * be held for p2. 1455 * References: p1 and p2 must be valid for the lifetime of the call 1456 */ 1457int 1458p_cansched(struct proc *p1, struct proc *p2) 1459{ 1460 int error; 1461 1462 if (p1 == p2) 1463 return (0); 1464 if ((error = prison_check(p1->p_ucred, p2->p_ucred))) 1465 return (error); 1466 if (p1->p_ucred->cr_ruid == p2->p_ucred->cr_ruid) 1467 return (0); 1468 if (p1->p_ucred->cr_uid == p2->p_ucred->cr_ruid) 1469 return (0); 1470 if (suser_xxx(0, p1, PRISON_ROOT) == 0) 1471 return (0); 1472 1473#ifdef CAPABILITIES 1474 if (!cap_check(NULL, p1, CAP_SYS_NICE, PRISON_ROOT)) 1475 return (0); 1476#endif 1477 1478 return (EPERM); 1479} 1480 1481/* 1482 * The 'unprivileged_proc_debug' flag may be used to disable a variety of 1483 * unprivileged inter-process debugging services, including some procfs 1484 * functionality, ptrace(), and ktrace(). In the past, inter-process 1485 * debugging has been involved in a variety of security problems, and sites 1486 * not requiring the service might choose to disable it when hardening 1487 * systems. 1488 * 1489 * XXX: Should modifying and reading this variable require locking? 1490 * XXX: data declarations should be together near the beginning of the file. 1491 */ 1492static int unprivileged_proc_debug = 1; 1493SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_proc_debug, CTLFLAG_RW, 1494 &unprivileged_proc_debug, 0, 1495 "Unprivileged processes may use process debugging facilities"); 1496 1497/*- 1498 * Determine whether p1 may debug p2. 1499 * Returns: 0 for permitted, an errno value otherwise 1500 * Locks: Sufficient locks to protect various components of p1 and p2 1501 * must be held. Normally, p1 will be curproc, and a lock must 1502 * be held for p2. 1503 * References: p1 and p2 must be valid for the lifetime of the call 1504 */ 1505int 1506p_candebug(struct proc *p1, struct proc *p2) 1507{ 1508 int credentialchanged, error, grpsubset, i, uidsubset; 1509 1510 if (!unprivileged_proc_debug) { 1511 error = suser_xxx(NULL, p1, PRISON_ROOT); 1512 if (error) 1513 return (error); 1514 } 1515 if (p1 == p2) 1516 return (0); 1517 if ((error = prison_check(p1->p_ucred, p2->p_ucred))) 1518 return (error); 1519 1520 /* 1521 * Is p2's group set a subset of p1's effective group set? This 1522 * includes p2's egid, group access list, rgid, and svgid. 1523 */ 1524 grpsubset = 1; 1525 for (i = 0; i < p2->p_ucred->cr_ngroups; i++) { 1526 if (!groupmember(p2->p_ucred->cr_groups[i], p1->p_ucred)) { 1527 grpsubset = 0; 1528 break; 1529 } 1530 } 1531 grpsubset = grpsubset && 1532 groupmember(p2->p_ucred->cr_rgid, p1->p_ucred) && 1533 groupmember(p2->p_ucred->cr_svgid, p1->p_ucred); 1534 1535 /* 1536 * Are the uids present in p2's credential equal to p1's 1537 * effective uid? This includes p2's euid, svuid, and ruid. 1538 */ 1539 uidsubset = (p1->p_ucred->cr_uid == p2->p_ucred->cr_uid && 1540 p1->p_ucred->cr_uid == p2->p_ucred->cr_svuid && 1541 p1->p_ucred->cr_uid == p2->p_ucred->cr_ruid); 1542 1543 /* 1544 * Has the credential of the process changed since the last exec()? 1545 */ 1546 credentialchanged = (p2->p_flag & P_SUGID); 1547 1548 /* 1549 * If p2's gids aren't a subset, or the uids aren't a subset, 1550 * or the credential has changed, require appropriate privilege 1551 * for p1 to debug p2. For POSIX.1e capabilities, this will 1552 * require CAP_SYS_PTRACE. 1553 */ 1554 if (!grpsubset || !uidsubset || credentialchanged) { 1555 error = suser_xxx(NULL, p1, PRISON_ROOT); 1556 if (error) 1557 return (error); 1558 } 1559 1560 /* Can't trace init when securelevel > 0. */ 1561 if (p2 == initproc) { 1562 error = securelevel_gt(p1->p_ucred, 0); 1563 if (error) 1564 return (error); 1565 } 1566 1567 /* 1568 * Can't trace a process that's currently exec'ing. 1569 * XXX: Note, this is not a security policy decision, it's a 1570 * basic correctness/functionality decision. Therefore, this check 1571 * should be moved to the caller's of p_candebug(). 1572 */ 1573 if ((p2->p_flag & P_INEXEC) != 0) 1574 return (EAGAIN); 1575 1576 return (0); 1577} 1578 1579/* 1580 * Allocate a zeroed cred structure. 1581 */ 1582struct ucred * 1583crget() 1584{ 1585 register struct ucred *cr; 1586 1587 MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK | M_ZERO); 1588 cr->cr_ref = 1; 1589 cr->cr_mtxp = mtx_pool_find(cr); 1590 return (cr); 1591} 1592 1593/* 1594 * Claim another reference to a ucred structure. 1595 */ 1596struct ucred * 1597crhold(cr) 1598 struct ucred *cr; 1599{ 1600 1601 mtx_lock(cr->cr_mtxp); 1602 cr->cr_ref++; 1603 mtx_unlock(cr->cr_mtxp); 1604 return (cr); 1605} 1606 1607/* 1608 * Free a cred structure. 1609 * Throws away space when ref count gets to 0. 1610 */ 1611void 1612crfree(cr) 1613 struct ucred *cr; 1614{ 1615 struct mtx *mtxp = cr->cr_mtxp; 1616 1617 mtx_lock(mtxp); 1618 KASSERT(cr->cr_ref > 0, ("bad ucred refcount: %d", cr->cr_ref)); 1619 if (--cr->cr_ref == 0) { 1620 /* 1621 * Some callers of crget(), such as nfs_statfs(), 1622 * allocate a temporary credential, but don't 1623 * allocate a uidinfo structure. 1624 */ 1625 mtx_unlock(mtxp); 1626 if (cr->cr_uidinfo != NULL) 1627 uifree(cr->cr_uidinfo); 1628 if (cr->cr_ruidinfo != NULL) 1629 uifree(cr->cr_ruidinfo); 1630 /* 1631 * Free a prison, if any. 1632 */ 1633 if (jailed(cr)) 1634 prison_free(cr->cr_prison); 1635 FREE((caddr_t)cr, M_CRED); 1636 } else { 1637 mtx_unlock(mtxp); 1638 } 1639} 1640 1641/* 1642 * Check to see if this ucred is shared. 1643 */ 1644int 1645crshared(cr) 1646 struct ucred *cr; 1647{ 1648 int shared; 1649 1650 mtx_lock(cr->cr_mtxp); 1651 shared = (cr->cr_ref > 1); 1652 mtx_unlock(cr->cr_mtxp); 1653 return (shared); 1654} 1655 1656/* 1657 * Copy a ucred's contents from a template. Does not block. 1658 */ 1659void 1660crcopy(dest, src) 1661 struct ucred *dest, *src; 1662{ 1663 1664 KASSERT(crshared(dest) == 0, ("crcopy of shared ucred")); 1665 bcopy(&src->cr_startcopy, &dest->cr_startcopy, 1666 (unsigned)((caddr_t)&src->cr_endcopy - 1667 (caddr_t)&src->cr_startcopy)); 1668 uihold(dest->cr_uidinfo); 1669 uihold(dest->cr_ruidinfo); 1670 if (jailed(dest)) 1671 prison_hold(dest->cr_prison); 1672} 1673 1674/* 1675 * Dup cred struct to a new held one. 1676 */ 1677struct ucred * 1678crdup(cr) 1679 struct ucred *cr; 1680{ 1681 struct ucred *newcr; 1682 1683 newcr = crget(); 1684 crcopy(newcr, cr); 1685 return (newcr); 1686} 1687 1688/* 1689 * small routine to swap a thread's current ucred for the correct one 1690 * taken from the process. 1691 */ 1692void 1693cred_update_thread(struct thread *td) 1694{ 1695 struct proc *p; 1696 1697 p = td->td_proc; 1698 if (td->td_ucred != NULL) { 1699 mtx_lock(&Giant); 1700 crfree(td->td_ucred); 1701 mtx_unlock(&Giant); 1702 td->td_ucred = NULL; 1703 } 1704 PROC_LOCK(p); 1705 td->td_ucred = crhold(p->p_ucred); 1706 PROC_UNLOCK(p); 1707} 1708 1709/* 1710 * Get login name, if available. 1711 */ 1712#ifndef _SYS_SYSPROTO_H_ 1713struct getlogin_args { 1714 char *namebuf; 1715 u_int namelen; 1716}; 1717#endif 1718/* 1719 * MPSAFE 1720 */ 1721/* ARGSUSED */ 1722int 1723getlogin(td, uap) 1724 struct thread *td; 1725 struct getlogin_args *uap; 1726{ 1727 int error;
| 1234 break; 1235 default: 1236 error = EINVAL; 1237 break; 1238 } 1239 mtx_unlock(&Giant); 1240 return (error); 1241#else /* !REGRESSION */ 1242 1243 return (ENOSYS); 1244#endif /* REGRESSION */ 1245} 1246 1247/* 1248 * Check if gid is a member of the group set. 1249 */ 1250int 1251groupmember(gid, cred) 1252 gid_t gid; 1253 struct ucred *cred; 1254{ 1255 register gid_t *gp; 1256 gid_t *egp; 1257 1258 egp = &(cred->cr_groups[cred->cr_ngroups]); 1259 for (gp = cred->cr_groups; gp < egp; gp++) 1260 if (*gp == gid) 1261 return (1); 1262 return (0); 1263} 1264 1265/* 1266 * `suser_enabled' (which can be set by the security.suser_enabled 1267 * sysctl) determines whether the system 'super-user' policy is in effect. 1268 * If it is nonzero, an effective uid of 0 connotes special privilege, 1269 * overriding many mandatory and discretionary protections. If it is zero, 1270 * uid 0 is offered no special privilege in the kernel security policy. 1271 * Setting it to zero may seriously impact the functionality of many 1272 * existing userland programs, and should not be done without careful 1273 * consideration of the consequences. 1274 */ 1275int suser_enabled = 1; 1276SYSCTL_INT(_security_bsd, OID_AUTO, suser_enabled, CTLFLAG_RW, 1277 &suser_enabled, 0, "processes with uid 0 have privilege"); 1278TUNABLE_INT("security.bsd.suser_enabled", &suser_enabled); 1279 1280/* 1281 * Test whether the specified credentials imply "super-user" privilege. 1282 * Return 0 or EPERM. 1283 */ 1284int 1285suser(p) 1286 struct proc *p; 1287{ 1288 1289 return (suser_xxx(0, p, 0)); 1290} 1291 1292/* 1293 * version for when the thread pointer is available and not the proc. 1294 * (saves having to include proc.h into every file that needs to do the change.) 1295 */ 1296int 1297suser_td(td) 1298 struct thread *td; 1299{ 1300 return (suser_xxx(0, td->td_proc, 0)); 1301} 1302 1303/* 1304 * wrapper to use if you have the thread on hand but not the proc. 1305 */ 1306int 1307suser_xxx_td(cred, td, flag) 1308 struct ucred *cred; 1309 struct thread *td; 1310 int flag; 1311{ 1312 return(suser_xxx(cred, td->td_proc, flag)); 1313} 1314 1315int 1316suser_xxx(cred, proc, flag) 1317 struct ucred *cred; 1318 struct proc *proc; 1319 int flag; 1320{ 1321 if (!suser_enabled) 1322 return (EPERM); 1323 if (!cred && !proc) { 1324 printf("suser_xxx(): THINK!\n"); 1325 return (EPERM); 1326 } 1327 if (cred == NULL) 1328 cred = proc->p_ucred; 1329 if (cred->cr_uid != 0) 1330 return (EPERM); 1331 if (jailed(cred) && !(flag & PRISON_ROOT)) 1332 return (EPERM); 1333 return (0); 1334} 1335 1336/* 1337 * Test the active securelevel against a given level. securelevel_gt() 1338 * implements (securelevel > level). securelevel_ge() implements 1339 * (securelevel >= level). Note that the logic is inverted -- these 1340 * functions return EPERM on "success" and 0 on "failure". 1341 * 1342 * cr is permitted to be NULL for the time being, as there were some 1343 * existing securelevel checks that occurred without a process/credential 1344 * context. In the future this will be disallowed, so a kernel message 1345 * is displayed. 1346 */ 1347int 1348securelevel_gt(struct ucred *cr, int level) 1349{ 1350 int active_securelevel; 1351 1352 active_securelevel = securelevel; 1353 if (cr == NULL) 1354 printf("securelevel_gt: cr is NULL\n"); 1355 if (cr->cr_prison != NULL) { 1356 mtx_lock(&cr->cr_prison->pr_mtx); 1357 active_securelevel = imax(cr->cr_prison->pr_securelevel, 1358 active_securelevel); 1359 mtx_unlock(&cr->cr_prison->pr_mtx); 1360 } 1361 return (active_securelevel > level ? EPERM : 0); 1362} 1363 1364int 1365securelevel_ge(struct ucred *cr, int level) 1366{ 1367 int active_securelevel; 1368 1369 active_securelevel = securelevel; 1370 if (cr == NULL) 1371 printf("securelevel_gt: cr is NULL\n"); 1372 if (cr->cr_prison != NULL) { 1373 mtx_lock(&cr->cr_prison->pr_mtx); 1374 active_securelevel = imax(cr->cr_prison->pr_securelevel, 1375 active_securelevel); 1376 mtx_unlock(&cr->cr_prison->pr_mtx); 1377 } 1378 return (active_securelevel >= level ? EPERM : 0); 1379} 1380 1381/* 1382 * 'see_other_uids' determines whether or not visibility of processes 1383 * and sockets with credentials holding different real uids is possible 1384 * using a variety of system MIBs. 1385 * XXX: data declarations should be together near the beginning of the file. 1386 */ 1387static int see_other_uids = 1; 1388SYSCTL_INT(_security_bsd, OID_AUTO, see_other_uids, CTLFLAG_RW, 1389 &see_other_uids, 0, 1390 "Unprivileged processes may see subjects/objects with different real uid"); 1391 1392/*- 1393 * Determine if u1 "can see" the subject specified by u2. 1394 * Returns: 0 for permitted, an errno value otherwise 1395 * Locks: none 1396 * References: *u1 and *u2 must not change during the call 1397 * u1 may equal u2, in which case only one reference is required 1398 */ 1399int 1400cr_cansee(struct ucred *u1, struct ucred *u2) 1401{ 1402 int error; 1403 1404 if ((error = prison_check(u1, u2))) 1405 return (error); 1406 if (!see_other_uids && u1->cr_ruid != u2->cr_ruid) { 1407 if (suser_xxx(u1, NULL, PRISON_ROOT) != 0) 1408 return (ESRCH); 1409 } 1410 return (0); 1411} 1412 1413/*- 1414 * Determine if p1 "can see" the subject specified by p2. 1415 * Returns: 0 for permitted, an errno value otherwise 1416 * Locks: Sufficient locks to protect p1->p_ucred and p2->p_ucred must 1417 * be held. Normally, p1 will be curproc, and a lock must be held 1418 * for p2. 1419 * References: p1 and p2 must be valid for the lifetime of the call 1420 */ 1421int 1422p_cansee(struct proc *p1, struct proc *p2) 1423{ 1424 1425 /* Wrap cr_cansee() for all functionality. */ 1426 return (cr_cansee(p1->p_ucred, p2->p_ucred)); 1427} 1428 1429/*- 1430 * Determine whether cred may deliver the specified signal to proc. 1431 * Returns: 0 for permitted, an errno value otherwise. 1432 * Locks: A lock must be held for proc. 1433 * References: cred and proc must be valid for the lifetime of the call. 1434 */ 1435int 1436cr_cansignal(struct ucred *cred, struct proc *proc, int signum) 1437{ 1438 int error; 1439 1440 /* 1441 * Jail semantics limit the scope of signalling to proc in the 1442 * same jail as cred, if cred is in jail. 1443 */ 1444 error = prison_check(cred, proc->p_ucred); 1445 if (error) 1446 return (error); 1447 1448 /* 1449 * UNIX signal semantics depend on the status of the P_SUGID 1450 * bit on the target process. If the bit is set, then additional 1451 * restrictions are placed on the set of available signals. 1452 */ 1453 if (proc->p_flag & P_SUGID) { 1454 switch (signum) { 1455 case 0: 1456 case SIGKILL: 1457 case SIGINT: 1458 case SIGTERM: 1459 case SIGSTOP: 1460 case SIGTTIN: 1461 case SIGTTOU: 1462 case SIGTSTP: 1463 case SIGHUP: 1464 case SIGUSR1: 1465 case SIGUSR2: 1466 /* 1467 * Generally, permit job and terminal control 1468 * signals. 1469 */ 1470 break; 1471 default: 1472 /* Not permitted without privilege. */ 1473 error = suser_xxx(cred, NULL, PRISON_ROOT); 1474 if (error) 1475 return (error); 1476 } 1477 } 1478 1479 /* 1480 * Generally, the target credential's ruid or svuid must match the 1481 * subject credential's ruid or euid. 1482 */ 1483 if (cred->cr_ruid != proc->p_ucred->cr_ruid && 1484 cred->cr_ruid != proc->p_ucred->cr_svuid && 1485 cred->cr_uid != proc->p_ucred->cr_ruid && 1486 cred->cr_uid != proc->p_ucred->cr_svuid) { 1487 /* Not permitted without privilege. */ 1488 error = suser_xxx(cred, NULL, PRISON_ROOT); 1489 if (error) 1490 return (error); 1491 } 1492 1493 return (0); 1494} 1495 1496 1497/*- 1498 * Determine whether p1 may deliver the specified signal to p2. 1499 * Returns: 0 for permitted, an errno value otherwise 1500 * Locks: Sufficient locks to protect various components of p1 and p2 1501 * must be held. Normally, p1 will be curproc, and a lock must 1502 * be held for p2. 1503 * References: p1 and p2 must be valid for the lifetime of the call 1504 */ 1505int 1506p_cansignal(struct proc *p1, struct proc *p2, int signum) 1507{ 1508 1509 if (p1 == p2) 1510 return (0); 1511 1512 /* 1513 * UNIX signalling semantics require that processes in the same 1514 * session always be able to deliver SIGCONT to one another, 1515 * overriding the remaining protections. 1516 */ 1517 if (signum == SIGCONT && p1->p_session == p2->p_session) 1518 return (0); 1519 1520 return (cr_cansignal(p1->p_ucred, p2, signum)); 1521} 1522 1523/*- 1524 * Determine whether p1 may reschedule p2. 1525 * Returns: 0 for permitted, an errno value otherwise 1526 * Locks: Sufficient locks to protect various components of p1 and p2 1527 * must be held. Normally, p1 will be curproc, and a lock must 1528 * be held for p2. 1529 * References: p1 and p2 must be valid for the lifetime of the call 1530 */ 1531int 1532p_cansched(struct proc *p1, struct proc *p2) 1533{ 1534 int error; 1535 1536 if (p1 == p2) 1537 return (0); 1538 if ((error = prison_check(p1->p_ucred, p2->p_ucred))) 1539 return (error); 1540 if (p1->p_ucred->cr_ruid == p2->p_ucred->cr_ruid) 1541 return (0); 1542 if (p1->p_ucred->cr_uid == p2->p_ucred->cr_ruid) 1543 return (0); 1544 if (suser_xxx(0, p1, PRISON_ROOT) == 0) 1545 return (0); 1546 1547#ifdef CAPABILITIES 1548 if (!cap_check(NULL, p1, CAP_SYS_NICE, PRISON_ROOT)) 1549 return (0); 1550#endif 1551 1552 return (EPERM); 1553} 1554 1555/* 1556 * The 'unprivileged_proc_debug' flag may be used to disable a variety of 1557 * unprivileged inter-process debugging services, including some procfs 1558 * functionality, ptrace(), and ktrace(). In the past, inter-process 1559 * debugging has been involved in a variety of security problems, and sites 1560 * not requiring the service might choose to disable it when hardening 1561 * systems. 1562 * 1563 * XXX: Should modifying and reading this variable require locking? 1564 * XXX: data declarations should be together near the beginning of the file. 1565 */ 1566static int unprivileged_proc_debug = 1; 1567SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_proc_debug, CTLFLAG_RW, 1568 &unprivileged_proc_debug, 0, 1569 "Unprivileged processes may use process debugging facilities"); 1570 1571/*- 1572 * Determine whether p1 may debug p2. 1573 * Returns: 0 for permitted, an errno value otherwise 1574 * Locks: Sufficient locks to protect various components of p1 and p2 1575 * must be held. Normally, p1 will be curproc, and a lock must 1576 * be held for p2. 1577 * References: p1 and p2 must be valid for the lifetime of the call 1578 */ 1579int 1580p_candebug(struct proc *p1, struct proc *p2) 1581{ 1582 int credentialchanged, error, grpsubset, i, uidsubset; 1583 1584 if (!unprivileged_proc_debug) { 1585 error = suser_xxx(NULL, p1, PRISON_ROOT); 1586 if (error) 1587 return (error); 1588 } 1589 if (p1 == p2) 1590 return (0); 1591 if ((error = prison_check(p1->p_ucred, p2->p_ucred))) 1592 return (error); 1593 1594 /* 1595 * Is p2's group set a subset of p1's effective group set? This 1596 * includes p2's egid, group access list, rgid, and svgid. 1597 */ 1598 grpsubset = 1; 1599 for (i = 0; i < p2->p_ucred->cr_ngroups; i++) { 1600 if (!groupmember(p2->p_ucred->cr_groups[i], p1->p_ucred)) { 1601 grpsubset = 0; 1602 break; 1603 } 1604 } 1605 grpsubset = grpsubset && 1606 groupmember(p2->p_ucred->cr_rgid, p1->p_ucred) && 1607 groupmember(p2->p_ucred->cr_svgid, p1->p_ucred); 1608 1609 /* 1610 * Are the uids present in p2's credential equal to p1's 1611 * effective uid? This includes p2's euid, svuid, and ruid. 1612 */ 1613 uidsubset = (p1->p_ucred->cr_uid == p2->p_ucred->cr_uid && 1614 p1->p_ucred->cr_uid == p2->p_ucred->cr_svuid && 1615 p1->p_ucred->cr_uid == p2->p_ucred->cr_ruid); 1616 1617 /* 1618 * Has the credential of the process changed since the last exec()? 1619 */ 1620 credentialchanged = (p2->p_flag & P_SUGID); 1621 1622 /* 1623 * If p2's gids aren't a subset, or the uids aren't a subset, 1624 * or the credential has changed, require appropriate privilege 1625 * for p1 to debug p2. For POSIX.1e capabilities, this will 1626 * require CAP_SYS_PTRACE. 1627 */ 1628 if (!grpsubset || !uidsubset || credentialchanged) { 1629 error = suser_xxx(NULL, p1, PRISON_ROOT); 1630 if (error) 1631 return (error); 1632 } 1633 1634 /* Can't trace init when securelevel > 0. */ 1635 if (p2 == initproc) { 1636 error = securelevel_gt(p1->p_ucred, 0); 1637 if (error) 1638 return (error); 1639 } 1640 1641 /* 1642 * Can't trace a process that's currently exec'ing. 1643 * XXX: Note, this is not a security policy decision, it's a 1644 * basic correctness/functionality decision. Therefore, this check 1645 * should be moved to the caller's of p_candebug(). 1646 */ 1647 if ((p2->p_flag & P_INEXEC) != 0) 1648 return (EAGAIN); 1649 1650 return (0); 1651} 1652 1653/* 1654 * Allocate a zeroed cred structure. 1655 */ 1656struct ucred * 1657crget() 1658{ 1659 register struct ucred *cr; 1660 1661 MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK | M_ZERO); 1662 cr->cr_ref = 1; 1663 cr->cr_mtxp = mtx_pool_find(cr); 1664 return (cr); 1665} 1666 1667/* 1668 * Claim another reference to a ucred structure. 1669 */ 1670struct ucred * 1671crhold(cr) 1672 struct ucred *cr; 1673{ 1674 1675 mtx_lock(cr->cr_mtxp); 1676 cr->cr_ref++; 1677 mtx_unlock(cr->cr_mtxp); 1678 return (cr); 1679} 1680 1681/* 1682 * Free a cred structure. 1683 * Throws away space when ref count gets to 0. 1684 */ 1685void 1686crfree(cr) 1687 struct ucred *cr; 1688{ 1689 struct mtx *mtxp = cr->cr_mtxp; 1690 1691 mtx_lock(mtxp); 1692 KASSERT(cr->cr_ref > 0, ("bad ucred refcount: %d", cr->cr_ref)); 1693 if (--cr->cr_ref == 0) { 1694 /* 1695 * Some callers of crget(), such as nfs_statfs(), 1696 * allocate a temporary credential, but don't 1697 * allocate a uidinfo structure. 1698 */ 1699 mtx_unlock(mtxp); 1700 if (cr->cr_uidinfo != NULL) 1701 uifree(cr->cr_uidinfo); 1702 if (cr->cr_ruidinfo != NULL) 1703 uifree(cr->cr_ruidinfo); 1704 /* 1705 * Free a prison, if any. 1706 */ 1707 if (jailed(cr)) 1708 prison_free(cr->cr_prison); 1709 FREE((caddr_t)cr, M_CRED); 1710 } else { 1711 mtx_unlock(mtxp); 1712 } 1713} 1714 1715/* 1716 * Check to see if this ucred is shared. 1717 */ 1718int 1719crshared(cr) 1720 struct ucred *cr; 1721{ 1722 int shared; 1723 1724 mtx_lock(cr->cr_mtxp); 1725 shared = (cr->cr_ref > 1); 1726 mtx_unlock(cr->cr_mtxp); 1727 return (shared); 1728} 1729 1730/* 1731 * Copy a ucred's contents from a template. Does not block. 1732 */ 1733void 1734crcopy(dest, src) 1735 struct ucred *dest, *src; 1736{ 1737 1738 KASSERT(crshared(dest) == 0, ("crcopy of shared ucred")); 1739 bcopy(&src->cr_startcopy, &dest->cr_startcopy, 1740 (unsigned)((caddr_t)&src->cr_endcopy - 1741 (caddr_t)&src->cr_startcopy)); 1742 uihold(dest->cr_uidinfo); 1743 uihold(dest->cr_ruidinfo); 1744 if (jailed(dest)) 1745 prison_hold(dest->cr_prison); 1746} 1747 1748/* 1749 * Dup cred struct to a new held one. 1750 */ 1751struct ucred * 1752crdup(cr) 1753 struct ucred *cr; 1754{ 1755 struct ucred *newcr; 1756 1757 newcr = crget(); 1758 crcopy(newcr, cr); 1759 return (newcr); 1760} 1761 1762/* 1763 * small routine to swap a thread's current ucred for the correct one 1764 * taken from the process. 1765 */ 1766void 1767cred_update_thread(struct thread *td) 1768{ 1769 struct proc *p; 1770 1771 p = td->td_proc; 1772 if (td->td_ucred != NULL) { 1773 mtx_lock(&Giant); 1774 crfree(td->td_ucred); 1775 mtx_unlock(&Giant); 1776 td->td_ucred = NULL; 1777 } 1778 PROC_LOCK(p); 1779 td->td_ucred = crhold(p->p_ucred); 1780 PROC_UNLOCK(p); 1781} 1782 1783/* 1784 * Get login name, if available. 1785 */ 1786#ifndef _SYS_SYSPROTO_H_ 1787struct getlogin_args { 1788 char *namebuf; 1789 u_int namelen; 1790}; 1791#endif 1792/* 1793 * MPSAFE 1794 */ 1795/* ARGSUSED */ 1796int 1797getlogin(td, uap) 1798 struct thread *td; 1799 struct getlogin_args *uap; 1800{ 1801 int error;
|
| 1802 char login[MAXLOGNAME];
|
1728 struct proc *p = td->td_proc; 1729 1730 mtx_lock(&Giant); 1731 if (uap->namelen > MAXLOGNAME) 1732 uap->namelen = MAXLOGNAME;
| 1803 struct proc *p = td->td_proc; 1804 1805 mtx_lock(&Giant); 1806 if (uap->namelen > MAXLOGNAME) 1807 uap->namelen = MAXLOGNAME;
|
1733 error = copyout((caddr_t) p->p_pgrp->pg_session->s_login, 1734 (caddr_t) uap->namebuf, uap->namelen);
| 1808 PROC_LOCK(p); 1809 SESS_LOCK(p->p_session); 1810 bcopy(p->p_session->s_login, login, uap->namelen); 1811 SESS_UNLOCK(p->p_session); 1812 PROC_UNLOCK(p); 1813 error = copyout((caddr_t) login, (caddr_t) uap->namebuf, uap->namelen);
|
1735 mtx_unlock(&Giant); 1736 return(error); 1737} 1738 1739/* 1740 * Set login name. 1741 */ 1742#ifndef _SYS_SYSPROTO_H_ 1743struct setlogin_args { 1744 char *namebuf; 1745}; 1746#endif 1747/* 1748 * MPSAFE 1749 */ 1750/* ARGSUSED */ 1751int 1752setlogin(td, uap) 1753 struct thread *td; 1754 struct setlogin_args *uap; 1755{ 1756 struct proc *p = td->td_proc; 1757 int error; 1758 char logintmp[MAXLOGNAME]; 1759 1760 mtx_lock(&Giant); 1761 if ((error = suser_xxx(0, p, PRISON_ROOT)) != 0) 1762 goto done2; 1763 error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp, 1764 sizeof(logintmp), (size_t *)0); 1765 if (error == ENAMETOOLONG) 1766 error = EINVAL;
| 1814 mtx_unlock(&Giant); 1815 return(error); 1816} 1817 1818/* 1819 * Set login name. 1820 */ 1821#ifndef _SYS_SYSPROTO_H_ 1822struct setlogin_args { 1823 char *namebuf; 1824}; 1825#endif 1826/* 1827 * MPSAFE 1828 */ 1829/* ARGSUSED */ 1830int 1831setlogin(td, uap) 1832 struct thread *td; 1833 struct setlogin_args *uap; 1834{ 1835 struct proc *p = td->td_proc; 1836 int error; 1837 char logintmp[MAXLOGNAME]; 1838 1839 mtx_lock(&Giant); 1840 if ((error = suser_xxx(0, p, PRISON_ROOT)) != 0) 1841 goto done2; 1842 error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp, 1843 sizeof(logintmp), (size_t *)0); 1844 if (error == ENAMETOOLONG) 1845 error = EINVAL;
|
1767 else if (!error) 1768 (void)memcpy(p->p_pgrp->pg_session->s_login, logintmp,
| 1846 else if (!error) { 1847 PGRPSESS_XLOCK(); 1848 PROC_LOCK(p); 1849 SESS_LOCK(p->p_session); 1850 (void) memcpy(p->p_session->s_login, logintmp,
|
1769 sizeof(logintmp));
| 1851 sizeof(logintmp));
|
| 1852 SESS_UNLOCK(p->p_session); 1853 PROC_UNLOCK(p); 1854 PGRPSESS_XUNLOCK(); 1855 }
|
1770done2: 1771 mtx_unlock(&Giant); 1772 return (error); 1773} 1774 1775void 1776setsugid(p) 1777 struct proc *p; 1778{ 1779 p->p_flag |= P_SUGID; 1780 if (!(p->p_pfsflags & PF_ISUGID)) 1781 p->p_stops = 0; 1782} 1783 1784/*- 1785 * Change a process's effective uid. 1786 * Side effects: newcred->cr_uid and newcred->cr_uidinfo will be modified. 1787 * References: newcred must be an exclusive credential reference for the 1788 * duration of the call. 1789 */ 1790void 1791change_euid(newcred, euid) 1792 struct ucred *newcred; 1793 uid_t euid; 1794{ 1795 1796 newcred->cr_uid = euid; 1797 uifree(newcred->cr_uidinfo); 1798 newcred->cr_uidinfo = uifind(euid); 1799} 1800 1801/*- 1802 * Change a process's effective gid. 1803 * Side effects: newcred->cr_gid will be modified. 1804 * References: newcred must be an exclusive credential reference for the 1805 * duration of the call. 1806 */ 1807void 1808change_egid(newcred, egid) 1809 struct ucred *newcred; 1810 gid_t egid; 1811{ 1812 1813 newcred->cr_groups[0] = egid; 1814} 1815 1816/*- 1817 * Change a process's real uid. 1818 * Side effects: newcred->cr_ruid will be updated, newcred->cr_ruidinfo 1819 * will be updated, and the old and new cr_ruidinfo proc 1820 * counts will be updated. 1821 * References: newcred must be an exclusive credential reference for the 1822 * duration of the call. 1823 */ 1824void 1825change_ruid(newcred, ruid) 1826 struct ucred *newcred; 1827 uid_t ruid; 1828{ 1829 1830 (void)chgproccnt(newcred->cr_ruidinfo, -1, 0); 1831 newcred->cr_ruid = ruid; 1832 uifree(newcred->cr_ruidinfo); 1833 newcred->cr_ruidinfo = uifind(ruid); 1834 (void)chgproccnt(newcred->cr_ruidinfo, 1, 0); 1835} 1836 1837/*- 1838 * Change a process's real gid. 1839 * Side effects: newcred->cr_rgid will be updated. 1840 * References: newcred must be an exclusive credential reference for the 1841 * duration of the call. 1842 */ 1843void 1844change_rgid(newcred, rgid) 1845 struct ucred *newcred; 1846 gid_t rgid; 1847{ 1848 1849 newcred->cr_rgid = rgid; 1850} 1851 1852/*- 1853 * Change a process's saved uid. 1854 * Side effects: newcred->cr_svuid will be updated. 1855 * References: newcred must be an exclusive credential reference for the 1856 * duration of the call. 1857 */ 1858void 1859change_svuid(newcred, svuid) 1860 struct ucred *newcred; 1861 uid_t svuid; 1862{ 1863 1864 newcred->cr_svuid = svuid; 1865} 1866 1867/*- 1868 * Change a process's saved gid. 1869 * Side effects: newcred->cr_svgid will be updated. 1870 * References: newcred must be an exclusive credential reference for the 1871 * duration of the call. 1872 */ 1873void 1874change_svgid(newcred, svgid) 1875 struct ucred *newcred; 1876 gid_t svgid; 1877{ 1878 1879 newcred->cr_svgid = svgid; 1880}
| 1856done2: 1857 mtx_unlock(&Giant); 1858 return (error); 1859} 1860 1861void 1862setsugid(p) 1863 struct proc *p; 1864{ 1865 p->p_flag |= P_SUGID; 1866 if (!(p->p_pfsflags & PF_ISUGID)) 1867 p->p_stops = 0; 1868} 1869 1870/*- 1871 * Change a process's effective uid. 1872 * Side effects: newcred->cr_uid and newcred->cr_uidinfo will be modified. 1873 * References: newcred must be an exclusive credential reference for the 1874 * duration of the call. 1875 */ 1876void 1877change_euid(newcred, euid) 1878 struct ucred *newcred; 1879 uid_t euid; 1880{ 1881 1882 newcred->cr_uid = euid; 1883 uifree(newcred->cr_uidinfo); 1884 newcred->cr_uidinfo = uifind(euid); 1885} 1886 1887/*- 1888 * Change a process's effective gid. 1889 * Side effects: newcred->cr_gid will be modified. 1890 * References: newcred must be an exclusive credential reference for the 1891 * duration of the call. 1892 */ 1893void 1894change_egid(newcred, egid) 1895 struct ucred *newcred; 1896 gid_t egid; 1897{ 1898 1899 newcred->cr_groups[0] = egid; 1900} 1901 1902/*- 1903 * Change a process's real uid. 1904 * Side effects: newcred->cr_ruid will be updated, newcred->cr_ruidinfo 1905 * will be updated, and the old and new cr_ruidinfo proc 1906 * counts will be updated. 1907 * References: newcred must be an exclusive credential reference for the 1908 * duration of the call. 1909 */ 1910void 1911change_ruid(newcred, ruid) 1912 struct ucred *newcred; 1913 uid_t ruid; 1914{ 1915 1916 (void)chgproccnt(newcred->cr_ruidinfo, -1, 0); 1917 newcred->cr_ruid = ruid; 1918 uifree(newcred->cr_ruidinfo); 1919 newcred->cr_ruidinfo = uifind(ruid); 1920 (void)chgproccnt(newcred->cr_ruidinfo, 1, 0); 1921} 1922 1923/*- 1924 * Change a process's real gid. 1925 * Side effects: newcred->cr_rgid will be updated. 1926 * References: newcred must be an exclusive credential reference for the 1927 * duration of the call. 1928 */ 1929void 1930change_rgid(newcred, rgid) 1931 struct ucred *newcred; 1932 gid_t rgid; 1933{ 1934 1935 newcred->cr_rgid = rgid; 1936} 1937 1938/*- 1939 * Change a process's saved uid. 1940 * Side effects: newcred->cr_svuid will be updated. 1941 * References: newcred must be an exclusive credential reference for the 1942 * duration of the call. 1943 */ 1944void 1945change_svuid(newcred, svuid) 1946 struct ucred *newcred; 1947 uid_t svuid; 1948{ 1949 1950 newcred->cr_svuid = svuid; 1951} 1952 1953/*- 1954 * Change a process's saved gid. 1955 * Side effects: newcred->cr_svgid will be updated. 1956 * References: newcred must be an exclusive credential reference for the 1957 * duration of the call. 1958 */ 1959void 1960change_svgid(newcred, svgid) 1961 struct ucred *newcred; 1962 gid_t svgid; 1963{ 1964 1965 newcred->cr_svgid = svgid; 1966}
|