kern_prot.c (e409590d0e0e57c6ec37d95bcb9fa3728051ebb1) | kern_prot.c (eb725b4e6a54cc15a1490b3e1ffef5d7d8de9ef5) |
---|---|
1/* 2 * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993 3 * The Regents of the University of California. All rights reserved. | 1/* 2 * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993 3 * The Regents of the University of California. All rights reserved. |
4 * Copyright (c) 2000-2001 Robert N. M. Watson. All rights reserved. | |
5 * (c) UNIX System Laboratories, Inc. | 4 * (c) UNIX System Laboratories, Inc. |
6 * | |
7 * All or some portions of this file are derived from material licensed 8 * to the University of California by American Telephone and Telegraph 9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 10 * the permission of 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. |
|
11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the --- 33 unchanged lines hidden (view full) --- 52#include <sys/systm.h> 53#include <sys/acct.h> 54#include <sys/kernel.h> 55#include <sys/lock.h> 56#include <sys/mutex.h> 57#include <sys/proc.h> 58#include <sys/sx.h> 59#include <sys/sysproto.h> | 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 --- 33 unchanged lines hidden (view full) --- 51#include <sys/systm.h> 52#include <sys/acct.h> 53#include <sys/kernel.h> 54#include <sys/lock.h> 55#include <sys/mutex.h> 56#include <sys/proc.h> 57#include <sys/sx.h> 58#include <sys/sysproto.h> |
59#include <sys/jail.h> |
|
60#include <sys/malloc.h> 61#include <sys/pioctl.h> 62#include <sys/resourcevar.h> 63#include <sys/sysctl.h> | 60#include <sys/malloc.h> 61#include <sys/pioctl.h> 62#include <sys/resourcevar.h> 63#include <sys/sysctl.h> |
64#include <sys/jail.h> | |
65 66static MALLOC_DEFINE(M_CRED, "cred", "credentials"); 67 68SYSCTL_NODE(_kern, OID_AUTO, security, CTLFLAG_RW, 0, 69 "Kernel security policy"); | 64 65static MALLOC_DEFINE(M_CRED, "cred", "credentials"); 66 67SYSCTL_NODE(_kern, OID_AUTO, security, CTLFLAG_RW, 0, 68 "Kernel security policy"); |
70 | |
71SYSCTL_NODE(_kern_security, OID_AUTO, bsd, CTLFLAG_RW, 0, 72 "BSD security policy"); 73 74#ifndef _SYS_SYSPROTO_H_ 75struct getpid_args { 76 int dummy; 77}; 78#endif | 69SYSCTL_NODE(_kern_security, OID_AUTO, bsd, CTLFLAG_RW, 0, 70 "BSD security policy"); 71 72#ifndef _SYS_SYSPROTO_H_ 73struct getpid_args { 74 int dummy; 75}; 76#endif |
79 | |
80/* | 77/* |
81 * getpid 82 */ 83 84/* | |
85 * MPSAFE 86 */ 87/* ARGSUSED */ 88int 89getpid(td, uap) 90 struct thread *td; 91 struct getpid_args *uap; 92{ --- 6 unchanged lines hidden (view full) --- 99 PROC_LOCK(p); 100 td->td_retval[1] = p->p_pptr->p_pid; 101 PROC_UNLOCK(p); 102#endif 103 mtx_unlock_giant(s); 104 return (0); 105} 106 | 78 * MPSAFE 79 */ 80/* ARGSUSED */ 81int 82getpid(td, uap) 83 struct thread *td; 84 struct getpid_args *uap; 85{ --- 6 unchanged lines hidden (view full) --- 92 PROC_LOCK(p); 93 td->td_retval[1] = p->p_pptr->p_pid; 94 PROC_UNLOCK(p); 95#endif 96 mtx_unlock_giant(s); 97 return (0); 98} 99 |
107/* 108 * getppid 109 */ 110 | |
111#ifndef _SYS_SYSPROTO_H_ 112struct getppid_args { 113 int dummy; 114}; 115#endif 116/* 117 * MPSAFE 118 */ --- 10 unchanged lines hidden (view full) --- 129 PROC_LOCK(p); 130 td->td_retval[0] = p->p_pptr->p_pid; 131 PROC_UNLOCK(p); 132 mtx_unlock_giant(s); 133 return (0); 134} 135 136/* | 100#ifndef _SYS_SYSPROTO_H_ 101struct getppid_args { 102 int dummy; 103}; 104#endif 105/* 106 * MPSAFE 107 */ --- 10 unchanged lines hidden (view full) --- 118 PROC_LOCK(p); 119 td->td_retval[0] = p->p_pptr->p_pid; 120 PROC_UNLOCK(p); 121 mtx_unlock_giant(s); 122 return (0); 123} 124 125/* |
137 * Get process group ID; note that POSIX getpgrp takes no parameter 138 * 139 * MP SAFE | 126 * Get process group ID; note that POSIX getpgrp takes no parameter. |
140 */ 141#ifndef _SYS_SYSPROTO_H_ 142struct getpgrp_args { 143 int dummy; 144}; 145#endif 146/* 147 * MPSAFE --- 12 unchanged lines hidden (view full) --- 160} 161 162/* Get an arbitary pid's process group id */ 163#ifndef _SYS_SYSPROTO_H_ 164struct getpgid_args { 165 pid_t pid; 166}; 167#endif | 127 */ 128#ifndef _SYS_SYSPROTO_H_ 129struct getpgrp_args { 130 int dummy; 131}; 132#endif 133/* 134 * MPSAFE --- 12 unchanged lines hidden (view full) --- 147} 148 149/* Get an arbitary pid's process group id */ 150#ifndef _SYS_SYSPROTO_H_ 151struct getpgid_args { 152 pid_t pid; 153}; 154#endif |
168 | |
169/* 170 * MPSAFE 171 */ 172int 173getpgid(td, uap) 174 struct thread *td; 175 struct getpgid_args *uap; 176{ 177 struct proc *p = td->td_proc; 178 struct proc *pt; | 155/* 156 * MPSAFE 157 */ 158int 159getpgid(td, uap) 160 struct thread *td; 161 struct getpgid_args *uap; 162{ 163 struct proc *p = td->td_proc; 164 struct proc *pt; |
179 int error = 0; 180 int s; | 165 int error, s; |
181 182 s = mtx_lock_giant(kern_giant_proc); | 166 167 s = mtx_lock_giant(kern_giant_proc); |
168 error = 0; |
|
183 if (uap->pid == 0) 184 td->td_retval[0] = p->p_pgrp->pg_id; 185 else if ((pt = pfind(uap->pid)) == NULL) 186 error = ESRCH; 187 else { 188 error = p_cansee(p, pt); 189 if (error == 0) 190 td->td_retval[0] = pt->p_pgrp->pg_id; --- 6 unchanged lines hidden (view full) --- 197/* 198 * Get an arbitary pid's session id. 199 */ 200#ifndef _SYS_SYSPROTO_H_ 201struct getsid_args { 202 pid_t pid; 203}; 204#endif | 169 if (uap->pid == 0) 170 td->td_retval[0] = p->p_pgrp->pg_id; 171 else if ((pt = pfind(uap->pid)) == NULL) 172 error = ESRCH; 173 else { 174 error = p_cansee(p, pt); 175 if (error == 0) 176 td->td_retval[0] = pt->p_pgrp->pg_id; --- 6 unchanged lines hidden (view full) --- 183/* 184 * Get an arbitary pid's session id. 185 */ 186#ifndef _SYS_SYSPROTO_H_ 187struct getsid_args { 188 pid_t pid; 189}; 190#endif |
205 | |
206/* 207 * MPSAFE 208 */ 209int 210getsid(td, uap) 211 struct thread *td; 212 struct getsid_args *uap; 213{ 214 struct proc *p = td->td_proc; 215 struct proc *pt; | 191/* 192 * MPSAFE 193 */ 194int 195getsid(td, uap) 196 struct thread *td; 197 struct getsid_args *uap; 198{ 199 struct proc *p = td->td_proc; 200 struct proc *pt; |
216 int error = 0; | 201 int error; |
217 218 mtx_lock(&Giant); | 202 203 mtx_lock(&Giant); |
204 error = 0; |
|
219 if (uap->pid == 0) 220 td->td_retval[0] = p->p_session->s_sid; 221 else if ((pt = pfind(uap->pid)) == NULL) 222 error = ESRCH; 223 else { 224 error = p_cansee(p, pt); 225 if (error == 0) 226 td->td_retval[0] = pt->p_session->s_sid; 227 PROC_UNLOCK(pt); 228 } 229 mtx_unlock(&Giant); 230 return (error); 231} 232 | 205 if (uap->pid == 0) 206 td->td_retval[0] = p->p_session->s_sid; 207 else if ((pt = pfind(uap->pid)) == NULL) 208 error = ESRCH; 209 else { 210 error = p_cansee(p, pt); 211 if (error == 0) 212 td->td_retval[0] = pt->p_session->s_sid; 213 PROC_UNLOCK(pt); 214 } 215 mtx_unlock(&Giant); 216 return (error); 217} 218 |
233 234/* 235 * getuid() - MP SAFE 236 */ | |
237#ifndef _SYS_SYSPROTO_H_ 238struct getuid_args { 239 int dummy; 240}; 241#endif | 219#ifndef _SYS_SYSPROTO_H_ 220struct getuid_args { 221 int dummy; 222}; 223#endif |
242 | |
243/* 244 * MPSAFE 245 */ 246/* ARGSUSED */ 247int 248getuid(td, uap) 249 struct thread *td; 250 struct getuid_args *uap; --- 4 unchanged lines hidden (view full) --- 255 td->td_retval[0] = p->p_ucred->cr_ruid; 256#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 257 td->td_retval[1] = p->p_ucred->cr_uid; 258#endif 259 mtx_unlock(&Giant); 260 return (0); 261} 262 | 224/* 225 * MPSAFE 226 */ 227/* ARGSUSED */ 228int 229getuid(td, uap) 230 struct thread *td; 231 struct getuid_args *uap; --- 4 unchanged lines hidden (view full) --- 236 td->td_retval[0] = p->p_ucred->cr_ruid; 237#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 238 td->td_retval[1] = p->p_ucred->cr_uid; 239#endif 240 mtx_unlock(&Giant); 241 return (0); 242} 243 |
263/* 264 * geteuid() - MP SAFE 265 */ | |
266#ifndef _SYS_SYSPROTO_H_ 267struct geteuid_args { 268 int dummy; 269}; 270#endif | 244#ifndef _SYS_SYSPROTO_H_ 245struct geteuid_args { 246 int dummy; 247}; 248#endif |
271 | 249/* 250 * MPSAFE 251 */ |
272/* ARGSUSED */ 273int 274geteuid(td, uap) 275 struct thread *td; 276 struct geteuid_args *uap; 277{ 278 mtx_lock(&Giant); 279 td->td_retval[0] = td->td_proc->p_ucred->cr_uid; 280 mtx_unlock(&Giant); 281 return (0); 282} 283 | 252/* ARGSUSED */ 253int 254geteuid(td, uap) 255 struct thread *td; 256 struct geteuid_args *uap; 257{ 258 mtx_lock(&Giant); 259 td->td_retval[0] = td->td_proc->p_ucred->cr_uid; 260 mtx_unlock(&Giant); 261 return (0); 262} 263 |
284/* 285 * getgid() - MP SAFE 286 */ | |
287#ifndef _SYS_SYSPROTO_H_ 288struct getgid_args { 289 int dummy; 290}; 291#endif | 264#ifndef _SYS_SYSPROTO_H_ 265struct getgid_args { 266 int dummy; 267}; 268#endif |
292 | |
293/* 294 * MPSAFE 295 */ 296/* ARGSUSED */ 297int 298getgid(td, uap) 299 struct thread *td; 300 struct getgid_args *uap; --- 14 unchanged lines hidden (view full) --- 315 * via getgroups. This syscall exists because it is somewhat painful to do 316 * correctly in a library function. 317 */ 318#ifndef _SYS_SYSPROTO_H_ 319struct getegid_args { 320 int dummy; 321}; 322#endif | 269/* 270 * MPSAFE 271 */ 272/* ARGSUSED */ 273int 274getgid(td, uap) 275 struct thread *td; 276 struct getgid_args *uap; --- 14 unchanged lines hidden (view full) --- 291 * via getgroups. This syscall exists because it is somewhat painful to do 292 * correctly in a library function. 293 */ 294#ifndef _SYS_SYSPROTO_H_ 295struct getegid_args { 296 int dummy; 297}; 298#endif |
323 | |
324/* 325 * MPSAFE 326 */ 327/* ARGSUSED */ 328int 329getegid(td, uap) 330 struct thread *td; 331 struct getegid_args *uap; --- 13 unchanged lines hidden (view full) --- 345}; 346#endif 347/* 348 * MPSAFE 349 */ 350int 351getgroups(td, uap) 352 struct thread *td; | 299/* 300 * MPSAFE 301 */ 302/* ARGSUSED */ 303int 304getegid(td, uap) 305 struct thread *td; 306 struct getegid_args *uap; --- 13 unchanged lines hidden (view full) --- 320}; 321#endif 322/* 323 * MPSAFE 324 */ 325int 326getgroups(td, uap) 327 struct thread *td; |
353 register struct getgroups_args *uap; | 328 register struct getgroups_args *uap; |
354{ 355 struct ucred *cred; 356 struct proc *p = td->td_proc; 357 u_int ngrp; | 329{ 330 struct ucred *cred; 331 struct proc *p = td->td_proc; 332 u_int ngrp; |
358 int error = 0; | 333 int error; |
359 360 mtx_lock(&Giant); | 334 335 mtx_lock(&Giant); |
336 error = 0; |
|
361 cred = p->p_ucred; 362 if ((ngrp = uap->gidsetsize) == 0) { 363 td->td_retval[0] = cred->cr_ngroups; | 337 cred = p->p_ucred; 338 if ((ngrp = uap->gidsetsize) == 0) { 339 td->td_retval[0] = cred->cr_ngroups; |
364 error = 0; | |
365 goto done2; 366 } 367 if (ngrp < cred->cr_ngroups) { 368 error = EINVAL; 369 goto done2; 370 } 371 ngrp = cred->cr_ngroups; 372 if ((error = copyout((caddr_t)cred->cr_groups, | 340 goto done2; 341 } 342 if (ngrp < cred->cr_ngroups) { 343 error = EINVAL; 344 goto done2; 345 } 346 ngrp = cred->cr_ngroups; 347 if ((error = copyout((caddr_t)cred->cr_groups, |
373 (caddr_t)uap->gidset, ngrp * sizeof(gid_t)))) { | 348 (caddr_t)uap->gidset, ngrp * sizeof(gid_t)))) |
374 goto done2; | 349 goto done2; |
375 } | |
376 td->td_retval[0] = ngrp; 377done2: 378 mtx_unlock(&Giant); 379 return (error); 380} 381 382#ifndef _SYS_SYSPROTO_H_ 383struct setsid_args { 384 int dummy; 385}; 386#endif | 350 td->td_retval[0] = ngrp; 351done2: 352 mtx_unlock(&Giant); 353 return (error); 354} 355 356#ifndef _SYS_SYSPROTO_H_ 357struct setsid_args { 358 int dummy; 359}; 360#endif |
387 | |
388/* 389 * MPSAFE 390 */ 391/* ARGSUSED */ 392int 393setsid(td, uap) 394 register struct thread *td; 395 struct setsid_args *uap; 396{ 397 int error; 398 struct proc *p = td->td_proc; 399 400 mtx_lock(&Giant); | 361/* 362 * MPSAFE 363 */ 364/* ARGSUSED */ 365int 366setsid(td, uap) 367 register struct thread *td; 368 struct setsid_args *uap; 369{ 370 int error; 371 struct proc *p = td->td_proc; 372 373 mtx_lock(&Giant); |
401 if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) { | 374 if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) |
402 error = EPERM; | 375 error = EPERM; |
403 } else { | 376 else { |
404 (void)enterpgrp(p, p->p_pid, 1); 405 td->td_retval[0] = p->p_pid; 406 error = 0; 407 } 408 mtx_unlock(&Giant); 409 return (error); 410} 411 --- 7 unchanged lines hidden (view full) --- 419 * pid must be in same session (EPERM) 420 * pid can't have done an exec (EACCES) 421 * if pgid != pid 422 * there must exist some pid in same session having pgid (EPERM) 423 * pid must not be session leader (EPERM) 424 */ 425#ifndef _SYS_SYSPROTO_H_ 426struct setpgid_args { | 377 (void)enterpgrp(p, p->p_pid, 1); 378 td->td_retval[0] = p->p_pid; 379 error = 0; 380 } 381 mtx_unlock(&Giant); 382 return (error); 383} 384 --- 7 unchanged lines hidden (view full) --- 392 * pid must be in same session (EPERM) 393 * pid can't have done an exec (EACCES) 394 * if pgid != pid 395 * there must exist some pid in same session having pgid (EPERM) 396 * pid must not be session leader (EPERM) 397 */ 398#ifndef _SYS_SYSPROTO_H_ 399struct setpgid_args { |
427 int pid; /* target process id */ 428 int pgid; /* target pgrp id */ | 400 int pid; /* target process id */ 401 int pgid; /* target pgrp id */ |
429}; 430#endif 431/* 432 * MPSAFE 433 */ 434/* ARGSUSED */ 435int 436setpgid(td, uap) 437 struct thread *td; 438 register struct setpgid_args *uap; 439{ 440 struct proc *curp = td->td_proc; | 402}; 403#endif 404/* 405 * MPSAFE 406 */ 407/* ARGSUSED */ 408int 409setpgid(td, uap) 410 struct thread *td; 411 register struct setpgid_args *uap; 412{ 413 struct proc *curp = td->td_proc; |
441 register struct proc *targp; /* target process */ 442 register struct pgrp *pgrp; /* target pgrp */ | 414 register struct proc *targp; /* target process */ 415 register struct pgrp *pgrp; /* target pgrp */ |
443 int error; 444 445 if (uap->pgid < 0) 446 return (EINVAL); | 416 int error; 417 418 if (uap->pgid < 0) 419 return (EINVAL); |
447 | |
448 mtx_lock(&Giant); | 420 mtx_lock(&Giant); |
449 | |
450 sx_slock(&proctree_lock); 451 if (uap->pid != 0 && uap->pid != curp->p_pid) { 452 if ((targp = pfind(uap->pid)) == NULL || !inferior(targp)) { 453 if (targp) 454 PROC_UNLOCK(targp); 455 error = ESRCH; 456 goto done2; 457 } --- 16 unchanged lines hidden (view full) --- 474 targp = curp; 475 PROC_LOCK(curp); /* XXX: not needed */ 476 } 477 if (SESS_LEADER(targp)) { 478 PROC_UNLOCK(targp); 479 error = EPERM; 480 goto done2; 481 } | 421 sx_slock(&proctree_lock); 422 if (uap->pid != 0 && uap->pid != curp->p_pid) { 423 if ((targp = pfind(uap->pid)) == NULL || !inferior(targp)) { 424 if (targp) 425 PROC_UNLOCK(targp); 426 error = ESRCH; 427 goto done2; 428 } --- 16 unchanged lines hidden (view full) --- 445 targp = curp; 446 PROC_LOCK(curp); /* XXX: not needed */ 447 } 448 if (SESS_LEADER(targp)) { 449 PROC_UNLOCK(targp); 450 error = EPERM; 451 goto done2; 452 } |
482 if (uap->pgid == 0) { | 453 if (uap->pgid == 0) |
483 uap->pgid = targp->p_pid; | 454 uap->pgid = targp->p_pid; |
484 } else if (uap->pgid != targp->p_pid) { | 455 else if (uap->pgid != targp->p_pid) { |
485 if ((pgrp = pgfind(uap->pgid)) == 0 || | 456 if ((pgrp = pgfind(uap->pgid)) == 0 || |
486 pgrp->pg_session != curp->p_session) { | 457 pgrp->pg_session != curp->p_session) { |
487 PROC_UNLOCK(targp); 488 error = EPERM; 489 goto done2; 490 } 491 } 492 /* XXX: We should probably hold the lock across enterpgrp. */ 493 PROC_UNLOCK(targp); 494 error = enterpgrp(targp, uap->pgid, 0); --- 27 unchanged lines hidden (view full) --- 522int 523setuid(td, uap) 524 struct thread *td; 525 struct setuid_args *uap; 526{ 527 struct proc *p = td->td_proc; 528 struct ucred *newcred, *oldcred; 529 uid_t uid; | 458 PROC_UNLOCK(targp); 459 error = EPERM; 460 goto done2; 461 } 462 } 463 /* XXX: We should probably hold the lock across enterpgrp. */ 464 PROC_UNLOCK(targp); 465 error = enterpgrp(targp, uap->pgid, 0); --- 27 unchanged lines hidden (view full) --- 493int 494setuid(td, uap) 495 struct thread *td; 496 struct setuid_args *uap; 497{ 498 struct proc *p = td->td_proc; 499 struct ucred *newcred, *oldcred; 500 uid_t uid; |
530 int error = 0; | 501 int error; |
531 | 502 |
532 uid = uap->uid; | |
533 oldcred = p->p_ucred; | 503 oldcred = p->p_ucred; |
504 uid = uap->uid; |
|
534 mtx_lock(&Giant); | 505 mtx_lock(&Giant); |
535 | 506 error = 0; |
536 /* 537 * See if we have "permission" by POSIX 1003.1 rules. 538 * | 507 /* 508 * See if we have "permission" by POSIX 1003.1 rules. 509 * |
539 * Note that setuid(geteuid()) is a special case of | 510 * Note that setuid(geteuid()) is a special case of |
540 * "appropriate privileges" in appendix B.4.2.2. We need 541 * to use this clause to be compatible with traditional BSD 542 * semantics. Basically, it means that "setuid(xx)" sets all 543 * three id's (assuming you have privs). 544 * 545 * Notes on the logic. We do things in three steps. 546 * 1: We determine if the euid is going to change, and do EPERM 547 * right away. We unconditionally change the euid later if this 548 * test is satisfied, simplifying that part of the logic. | 511 * "appropriate privileges" in appendix B.4.2.2. We need 512 * to use this clause to be compatible with traditional BSD 513 * semantics. Basically, it means that "setuid(xx)" sets all 514 * three id's (assuming you have privs). 515 * 516 * Notes on the logic. We do things in three steps. 517 * 1: We determine if the euid is going to change, and do EPERM 518 * right away. We unconditionally change the euid later if this 519 * test is satisfied, simplifying that part of the logic. |
549 * 2: We determine if the real and/or saved uid's are going to | 520 * 2: We determine if the real and/or saved uids are going to |
550 * change. Determined by compile options. 551 * 3: Change euid last. (after tests in #2 for "appropriate privs") 552 */ 553 if (uid != oldcred->cr_ruid && /* allow setuid(getuid()) */ 554#ifdef _POSIX_SAVED_IDS 555 uid != oldcred->cr_svuid && /* allow setuid(saved gid) */ 556#endif 557#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 558 uid != oldcred->cr_uid && /* allow setuid(geteuid()) */ 559#endif | 521 * change. Determined by compile options. 522 * 3: Change euid last. (after tests in #2 for "appropriate privs") 523 */ 524 if (uid != oldcred->cr_ruid && /* allow setuid(getuid()) */ 525#ifdef _POSIX_SAVED_IDS 526 uid != oldcred->cr_svuid && /* allow setuid(saved gid) */ 527#endif 528#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 529 uid != oldcred->cr_uid && /* allow setuid(geteuid()) */ 530#endif |
560 (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) | 531 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) |
561 goto done2; 562 563 newcred = crdup(oldcred); 564#ifdef _POSIX_SAVED_IDS 565 /* 566 * Do we have "appropriate privileges" (are we root or uid == euid) 567 * If so, we are changing the real uid and/or saved uid. 568 */ --- 51 unchanged lines hidden (view full) --- 620int 621seteuid(td, uap) 622 struct thread *td; 623 struct seteuid_args *uap; 624{ 625 struct proc *p = td->td_proc; 626 struct ucred *newcred, *oldcred; 627 uid_t euid; | 532 goto done2; 533 534 newcred = crdup(oldcred); 535#ifdef _POSIX_SAVED_IDS 536 /* 537 * Do we have "appropriate privileges" (are we root or uid == euid) 538 * If so, we are changing the real uid and/or saved uid. 539 */ --- 51 unchanged lines hidden (view full) --- 591int 592seteuid(td, uap) 593 struct thread *td; 594 struct seteuid_args *uap; 595{ 596 struct proc *p = td->td_proc; 597 struct ucred *newcred, *oldcred; 598 uid_t euid; |
628 int error = 0; | 599 int error; |
629 630 euid = uap->euid; | 600 601 euid = uap->euid; |
631 | |
632 mtx_lock(&Giant); | 602 mtx_lock(&Giant); |
603 error = 0; |
|
633 oldcred = p->p_ucred; 634 if (euid != oldcred->cr_ruid && /* allow seteuid(getuid()) */ 635 euid != oldcred->cr_svuid && /* allow seteuid(saved uid) */ | 604 oldcred = p->p_ucred; 605 if (euid != oldcred->cr_ruid && /* allow seteuid(getuid()) */ 606 euid != oldcred->cr_svuid && /* allow seteuid(saved uid) */ |
636 (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) { | 607 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) |
637 goto done2; | 608 goto done2; |
638 } | |
639 /* 640 * Everything's okay, do it. Copy credentials so other references do 641 * not see our changes. 642 */ 643 newcred = crdup(oldcred); 644 if (oldcred->cr_uid != euid) { 645 change_euid(newcred, euid); 646 setsugid(p); --- 17 unchanged lines hidden (view full) --- 664int 665setgid(td, uap) 666 struct thread *td; 667 struct setgid_args *uap; 668{ 669 struct proc *p = td->td_proc; 670 struct ucred *newcred, *oldcred; 671 gid_t gid; | 609 /* 610 * Everything's okay, do it. Copy credentials so other references do 611 * not see our changes. 612 */ 613 newcred = crdup(oldcred); 614 if (oldcred->cr_uid != euid) { 615 change_euid(newcred, euid); 616 setsugid(p); --- 17 unchanged lines hidden (view full) --- 634int 635setgid(td, uap) 636 struct thread *td; 637 struct setgid_args *uap; 638{ 639 struct proc *p = td->td_proc; 640 struct ucred *newcred, *oldcred; 641 gid_t gid; |
672 int error = 0; | 642 int error; |
673 674 gid = uap->gid; 675 676 mtx_lock(&Giant); | 643 644 gid = uap->gid; 645 646 mtx_lock(&Giant); |
647 error = 0; |
|
677 oldcred = p->p_ucred; 678 /* 679 * See if we have "permission" by POSIX 1003.1 rules. 680 * 681 * Note that setgid(getegid()) is a special case of 682 * "appropriate privileges" in appendix B.4.2.2. We need 683 * to use this clause to be compatible with traditional BSD 684 * semantics. Basically, it means that "setgid(xx)" sets all 685 * three id's (assuming you have privs). 686 * 687 * For notes on the logic here, see setuid() above. 688 */ 689 if (gid != oldcred->cr_rgid && /* allow setgid(getgid()) */ 690#ifdef _POSIX_SAVED_IDS 691 gid != oldcred->cr_svgid && /* allow setgid(saved gid) */ 692#endif 693#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 694 gid != oldcred->cr_groups[0] && /* allow setgid(getegid()) */ 695#endif | 648 oldcred = p->p_ucred; 649 /* 650 * See if we have "permission" by POSIX 1003.1 rules. 651 * 652 * Note that setgid(getegid()) is a special case of 653 * "appropriate privileges" in appendix B.4.2.2. We need 654 * to use this clause to be compatible with traditional BSD 655 * semantics. Basically, it means that "setgid(xx)" sets all 656 * three id's (assuming you have privs). 657 * 658 * For notes on the logic here, see setuid() above. 659 */ 660 if (gid != oldcred->cr_rgid && /* allow setgid(getgid()) */ 661#ifdef _POSIX_SAVED_IDS 662 gid != oldcred->cr_svgid && /* allow setgid(saved gid) */ 663#endif 664#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 665 gid != oldcred->cr_groups[0] && /* allow setgid(getegid()) */ 666#endif |
696 (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) { | 667 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) |
697 goto done2; | 668 goto done2; |
698 } | |
699 700 newcred = crdup(oldcred); 701#ifdef _POSIX_SAVED_IDS 702 /* 703 * Do we have "appropriate privileges" (are we root or gid == egid) 704 * If so, we are changing the real uid and saved gid. 705 */ 706 if ( --- 49 unchanged lines hidden (view full) --- 756int 757setegid(td, uap) 758 struct thread *td; 759 struct setegid_args *uap; 760{ 761 struct proc *p = td->td_proc; 762 struct ucred *newcred, *oldcred; 763 gid_t egid; | 669 670 newcred = crdup(oldcred); 671#ifdef _POSIX_SAVED_IDS 672 /* 673 * Do we have "appropriate privileges" (are we root or gid == egid) 674 * If so, we are changing the real uid and saved gid. 675 */ 676 if ( --- 49 unchanged lines hidden (view full) --- 726int 727setegid(td, uap) 728 struct thread *td; 729 struct setegid_args *uap; 730{ 731 struct proc *p = td->td_proc; 732 struct ucred *newcred, *oldcred; 733 gid_t egid; |
764 int error = 0; | 734 int error; |
765 766 egid = uap->egid; | 735 736 egid = uap->egid; |
767 | |
768 mtx_lock(&Giant); | 737 mtx_lock(&Giant); |
738 error = 0; |
|
769 oldcred = p->p_ucred; 770 if (egid != oldcred->cr_rgid && /* allow setegid(getgid()) */ 771 egid != oldcred->cr_svgid && /* allow setegid(saved gid) */ | 739 oldcred = p->p_ucred; 740 if (egid != oldcred->cr_rgid && /* allow setegid(getgid()) */ 741 egid != oldcred->cr_svgid && /* allow setegid(saved gid) */ |
772 (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) { | 742 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) |
773 goto done2; | 743 goto done2; |
774 } | |
775 newcred = crdup(oldcred); 776 if (oldcred->cr_groups[0] != egid) { 777 change_egid(newcred, egid); 778 setsugid(p); 779 } 780 p->p_ucred = newcred; 781 crfree(oldcred); 782done2: --- 17 unchanged lines hidden (view full) --- 800 struct setgroups_args *uap; 801{ 802 struct proc *p = td->td_proc; 803 struct ucred *newcred, *oldcred; 804 u_int ngrp; 805 int error; 806 807 mtx_lock(&Giant); | 744 newcred = crdup(oldcred); 745 if (oldcred->cr_groups[0] != egid) { 746 change_egid(newcred, egid); 747 setsugid(p); 748 } 749 p->p_ucred = newcred; 750 crfree(oldcred); 751done2: --- 17 unchanged lines hidden (view full) --- 769 struct setgroups_args *uap; 770{ 771 struct proc *p = td->td_proc; 772 struct ucred *newcred, *oldcred; 773 u_int ngrp; 774 int error; 775 776 mtx_lock(&Giant); |
808 | |
809 ngrp = uap->gidsetsize; 810 oldcred = p->p_ucred; | 777 ngrp = uap->gidsetsize; 778 oldcred = p->p_ucred; |
811 if ((error = suser_xxx(oldcred, NULL, PRISON_ROOT))) | 779 if ((error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) |
812 goto done2; 813 if (ngrp > NGROUPS) { 814 error = EINVAL; 815 goto done2; 816 } 817 /* 818 * XXX A little bit lazy here. We could test if anything has 819 * changed before crcopy() and setting P_SUGID. --- 35 unchanged lines hidden (view full) --- 855/* ARGSUSED */ 856int 857setreuid(td, uap) 858 register struct thread *td; 859 struct setreuid_args *uap; 860{ 861 struct proc *p = td->td_proc; 862 struct ucred *newcred, *oldcred; | 780 goto done2; 781 if (ngrp > NGROUPS) { 782 error = EINVAL; 783 goto done2; 784 } 785 /* 786 * XXX A little bit lazy here. We could test if anything has 787 * changed before crcopy() and setting P_SUGID. --- 35 unchanged lines hidden (view full) --- 823/* ARGSUSED */ 824int 825setreuid(td, uap) 826 register struct thread *td; 827 struct setreuid_args *uap; 828{ 829 struct proc *p = td->td_proc; 830 struct ucred *newcred, *oldcred; |
863 uid_t ruid, euid; 864 int error = 0; | 831 uid_t euid, ruid; 832 int error; |
865 | 833 |
866 ruid = uap->ruid; | |
867 euid = uap->euid; | 834 euid = uap->euid; |
868 | 835 ruid = uap->ruid; |
869 mtx_lock(&Giant); | 836 mtx_lock(&Giant); |
870 | 837 error = 0; |
871 oldcred = p->p_ucred; 872 if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && 873 ruid != oldcred->cr_svuid) || 874 (euid != (uid_t)-1 && euid != oldcred->cr_uid && 875 euid != oldcred->cr_ruid && euid != oldcred->cr_svuid)) && | 838 oldcred = p->p_ucred; 839 if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && 840 ruid != oldcred->cr_svuid) || 841 (euid != (uid_t)-1 && euid != oldcred->cr_uid && 842 euid != oldcred->cr_ruid && euid != oldcred->cr_svuid)) && |
876 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) { | 843 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) |
877 goto done2; | 844 goto done2; |
878 } | |
879 newcred = crdup(oldcred); 880 if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { 881 change_euid(newcred, euid); 882 setsugid(p); 883 } 884 if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { 885 change_ruid(newcred, ruid); 886 setsugid(p); --- 22 unchanged lines hidden (view full) --- 909/* ARGSUSED */ 910int 911setregid(td, uap) 912 register struct thread *td; 913 struct setregid_args *uap; 914{ 915 struct proc *p = td->td_proc; 916 struct ucred *newcred, *oldcred; | 845 newcred = crdup(oldcred); 846 if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { 847 change_euid(newcred, euid); 848 setsugid(p); 849 } 850 if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { 851 change_ruid(newcred, ruid); 852 setsugid(p); --- 22 unchanged lines hidden (view full) --- 875/* ARGSUSED */ 876int 877setregid(td, uap) 878 register struct thread *td; 879 struct setregid_args *uap; 880{ 881 struct proc *p = td->td_proc; 882 struct ucred *newcred, *oldcred; |
917 gid_t rgid, egid; 918 int error = 0; | 883 gid_t egid, rgid; 884 int error; |
919 | 885 |
920 rgid = uap->rgid; | |
921 egid = uap->egid; | 886 egid = uap->egid; |
922 | 887 rgid = uap->rgid; |
923 mtx_lock(&Giant); | 888 mtx_lock(&Giant); |
924 | 889 error = 0; |
925 oldcred = p->p_ucred; 926 if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && 927 rgid != oldcred->cr_svgid) || 928 (egid != (gid_t)-1 && egid != oldcred->cr_groups[0] && 929 egid != oldcred->cr_rgid && egid != oldcred->cr_svgid)) && | 890 oldcred = p->p_ucred; 891 if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && 892 rgid != oldcred->cr_svgid) || 893 (egid != (gid_t)-1 && egid != oldcred->cr_groups[0] && 894 egid != oldcred->cr_rgid && egid != oldcred->cr_svgid)) && |
930 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) { | 895 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) |
931 goto done2; | 896 goto done2; |
932 } 933 | |
934 newcred = crdup(oldcred); 935 if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { 936 change_egid(newcred, egid); 937 setsugid(p); 938 } 939 if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { 940 change_rgid(newcred, rgid); 941 setsugid(p); --- 28 unchanged lines hidden (view full) --- 970/* ARGSUSED */ 971int 972setresuid(td, uap) 973 register struct thread *td; 974 struct setresuid_args *uap; 975{ 976 struct proc *p = td->td_proc; 977 struct ucred *newcred, *oldcred; | 897 newcred = crdup(oldcred); 898 if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { 899 change_egid(newcred, egid); 900 setsugid(p); 901 } 902 if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { 903 change_rgid(newcred, rgid); 904 setsugid(p); --- 28 unchanged lines hidden (view full) --- 933/* ARGSUSED */ 934int 935setresuid(td, uap) 936 register struct thread *td; 937 struct setresuid_args *uap; 938{ 939 struct proc *p = td->td_proc; 940 struct ucred *newcred, *oldcred; |
978 uid_t ruid, euid, suid; | 941 uid_t euid, ruid, suid; |
979 int error; 980 | 942 int error; 943 |
981 ruid = uap->ruid; | |
982 euid = uap->euid; | 944 euid = uap->euid; |
945 ruid = uap->ruid; |
|
983 suid = uap->suid; | 946 suid = uap->suid; |
984 | |
985 mtx_lock(&Giant); 986 oldcred = p->p_ucred; 987 if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && 988 ruid != oldcred->cr_svuid && 989 ruid != oldcred->cr_uid) || 990 (euid != (uid_t)-1 && euid != oldcred->cr_ruid && 991 euid != oldcred->cr_svuid && 992 euid != oldcred->cr_uid) || 993 (suid != (uid_t)-1 && suid != oldcred->cr_ruid && 994 suid != oldcred->cr_svuid && 995 suid != oldcred->cr_uid)) && | 947 mtx_lock(&Giant); 948 oldcred = p->p_ucred; 949 if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && 950 ruid != oldcred->cr_svuid && 951 ruid != oldcred->cr_uid) || 952 (euid != (uid_t)-1 && euid != oldcred->cr_ruid && 953 euid != oldcred->cr_svuid && 954 euid != oldcred->cr_uid) || 955 (suid != (uid_t)-1 && suid != oldcred->cr_ruid && 956 suid != oldcred->cr_svuid && 957 suid != oldcred->cr_uid)) && |
996 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) { | 958 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) |
997 goto done2; | 959 goto done2; |
998 } 999 | |
1000 newcred = crdup(oldcred); 1001 if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { 1002 change_euid(newcred, euid); 1003 setsugid(p); 1004 } 1005 if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { 1006 change_ruid(newcred, ruid); 1007 setsugid(p); --- 28 unchanged lines hidden (view full) --- 1036/* ARGSUSED */ 1037int 1038setresgid(td, uap) 1039 register struct thread *td; 1040 struct setresgid_args *uap; 1041{ 1042 struct proc *p = td->td_proc; 1043 struct ucred *newcred, *oldcred; | 960 newcred = crdup(oldcred); 961 if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { 962 change_euid(newcred, euid); 963 setsugid(p); 964 } 965 if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { 966 change_ruid(newcred, ruid); 967 setsugid(p); --- 28 unchanged lines hidden (view full) --- 996/* ARGSUSED */ 997int 998setresgid(td, uap) 999 register struct thread *td; 1000 struct setresgid_args *uap; 1001{ 1002 struct proc *p = td->td_proc; 1003 struct ucred *newcred, *oldcred; |
1044 gid_t rgid, egid, sgid; | 1004 gid_t egid, rgid, sgid; |
1045 int error; 1046 | 1005 int error; 1006 |
1047 rgid = uap->rgid; | |
1048 egid = uap->egid; | 1007 egid = uap->egid; |
1008 rgid = uap->rgid; |
|
1049 sgid = uap->sgid; 1050 1051 mtx_lock(&Giant); 1052 oldcred = p->p_ucred; 1053 if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && 1054 rgid != oldcred->cr_svgid && 1055 rgid != oldcred->cr_groups[0]) || 1056 (egid != (gid_t)-1 && egid != oldcred->cr_rgid && --- 43 unchanged lines hidden (view full) --- 1100 struct getresuid_args *uap; 1101{ 1102 struct ucred *cred; 1103 struct proc *p = td->td_proc; 1104 int error1 = 0, error2 = 0, error3 = 0; 1105 1106 mtx_lock(&Giant); 1107 cred = p->p_ucred; | 1009 sgid = uap->sgid; 1010 1011 mtx_lock(&Giant); 1012 oldcred = p->p_ucred; 1013 if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && 1014 rgid != oldcred->cr_svgid && 1015 rgid != oldcred->cr_groups[0]) || 1016 (egid != (gid_t)-1 && egid != oldcred->cr_rgid && --- 43 unchanged lines hidden (view full) --- 1060 struct getresuid_args *uap; 1061{ 1062 struct ucred *cred; 1063 struct proc *p = td->td_proc; 1064 int error1 = 0, error2 = 0, error3 = 0; 1065 1066 mtx_lock(&Giant); 1067 cred = p->p_ucred; |
1108 | |
1109 if (uap->ruid) 1110 error1 = copyout((caddr_t)&cred->cr_ruid, 1111 (caddr_t)uap->ruid, sizeof(cred->cr_ruid)); 1112 if (uap->euid) 1113 error2 = copyout((caddr_t)&cred->cr_uid, 1114 (caddr_t)uap->euid, sizeof(cred->cr_uid)); 1115 if (uap->suid) 1116 error3 = copyout((caddr_t)&cred->cr_svuid, 1117 (caddr_t)uap->suid, sizeof(cred->cr_svuid)); 1118 mtx_unlock(&Giant); | 1068 if (uap->ruid) 1069 error1 = copyout((caddr_t)&cred->cr_ruid, 1070 (caddr_t)uap->ruid, sizeof(cred->cr_ruid)); 1071 if (uap->euid) 1072 error2 = copyout((caddr_t)&cred->cr_uid, 1073 (caddr_t)uap->euid, sizeof(cred->cr_uid)); 1074 if (uap->suid) 1075 error3 = copyout((caddr_t)&cred->cr_svuid, 1076 (caddr_t)uap->suid, sizeof(cred->cr_svuid)); 1077 mtx_unlock(&Giant); |
1119 return error1 ? error1 : (error2 ? error2 : error3); | 1078 return (error1 ? error1 : error2 ? error2 : error3); |
1120} 1121 1122#ifndef _SYS_SYSPROTO_H_ 1123struct getresgid_args { 1124 gid_t *rgid; 1125 gid_t *egid; 1126 gid_t *sgid; 1127}; --- 8 unchanged lines hidden (view full) --- 1136 struct getresgid_args *uap; 1137{ 1138 struct ucred *cred; 1139 struct proc *p = td->td_proc; 1140 int error1 = 0, error2 = 0, error3 = 0; 1141 1142 mtx_lock(&Giant); 1143 cred = p->p_ucred; | 1079} 1080 1081#ifndef _SYS_SYSPROTO_H_ 1082struct getresgid_args { 1083 gid_t *rgid; 1084 gid_t *egid; 1085 gid_t *sgid; 1086}; --- 8 unchanged lines hidden (view full) --- 1095 struct getresgid_args *uap; 1096{ 1097 struct ucred *cred; 1098 struct proc *p = td->td_proc; 1099 int error1 = 0, error2 = 0, error3 = 0; 1100 1101 mtx_lock(&Giant); 1102 cred = p->p_ucred; |
1144 | |
1145 if (uap->rgid) 1146 error1 = copyout((caddr_t)&cred->cr_rgid, 1147 (caddr_t)uap->rgid, sizeof(cred->cr_rgid)); 1148 if (uap->egid) 1149 error2 = copyout((caddr_t)&cred->cr_groups[0], 1150 (caddr_t)uap->egid, sizeof(cred->cr_groups[0])); 1151 if (uap->sgid) 1152 error3 = copyout((caddr_t)&cred->cr_svgid, 1153 (caddr_t)uap->sgid, sizeof(cred->cr_svgid)); 1154 mtx_unlock(&Giant); | 1103 if (uap->rgid) 1104 error1 = copyout((caddr_t)&cred->cr_rgid, 1105 (caddr_t)uap->rgid, sizeof(cred->cr_rgid)); 1106 if (uap->egid) 1107 error2 = copyout((caddr_t)&cred->cr_groups[0], 1108 (caddr_t)uap->egid, sizeof(cred->cr_groups[0])); 1109 if (uap->sgid) 1110 error3 = copyout((caddr_t)&cred->cr_svgid, 1111 (caddr_t)uap->sgid, sizeof(cred->cr_svgid)); 1112 mtx_unlock(&Giant); |
1155 return error1 ? error1 : (error2 ? error2 : error3); | 1113 return (error1 ? error1 : error2 ? error2 : error3); |
1156} 1157 | 1114} 1115 |
1158 | |
1159#ifndef _SYS_SYSPROTO_H_ 1160struct issetugid_args { 1161 int dummy; 1162}; 1163#endif | 1116#ifndef _SYS_SYSPROTO_H_ 1117struct issetugid_args { 1118 int dummy; 1119}; 1120#endif |
1121/* 1122 * NOT MPSAFE? 1123 */ |
|
1164/* ARGSUSED */ 1165int 1166issetugid(td, uap) 1167 register struct thread *td; 1168 struct issetugid_args *uap; 1169{ 1170 struct proc *p = td->td_proc; 1171 --- 13 unchanged lines hidden (view full) --- 1185 * MPSAFE 1186 */ 1187int 1188__setugid(td, uap) 1189 struct thread *td; 1190 struct __setugid_args *uap; 1191{ 1192#ifdef REGRESSION | 1124/* ARGSUSED */ 1125int 1126issetugid(td, uap) 1127 register struct thread *td; 1128 struct issetugid_args *uap; 1129{ 1130 struct proc *p = td->td_proc; 1131 --- 13 unchanged lines hidden (view full) --- 1145 * MPSAFE 1146 */ 1147int 1148__setugid(td, uap) 1149 struct thread *td; 1150 struct __setugid_args *uap; 1151{ 1152#ifdef REGRESSION |
1193 int error = 0; | 1153 int error; |
1194 1195 mtx_lock(&Giant); | 1154 1155 mtx_lock(&Giant); |
1156 error = 0; |
|
1196 switch (uap->flag) { 1197 case 0: 1198 td->td_proc->p_flag &= ~P_SUGID; 1199 break; 1200 case 1: 1201 td->td_proc->p_flag |= P_SUGID; 1202 break; 1203 default: 1204 error = EINVAL; 1205 break; 1206 } 1207 mtx_unlock(&Giant); 1208 return (error); 1209#else /* !REGRESSION */ | 1157 switch (uap->flag) { 1158 case 0: 1159 td->td_proc->p_flag &= ~P_SUGID; 1160 break; 1161 case 1: 1162 td->td_proc->p_flag |= P_SUGID; 1163 break; 1164 default: 1165 error = EINVAL; 1166 break; 1167 } 1168 mtx_unlock(&Giant); 1169 return (error); 1170#else /* !REGRESSION */ |
1171 |
|
1210 return (ENOSYS); | 1172 return (ENOSYS); |
1211#endif /* !REGRESSION */ | 1173#endif /* REGRESSION */ |
1212} 1213 1214/* 1215 * Check if gid is a member of the group set. 1216 */ 1217int 1218groupmember(gid, cred) 1219 gid_t gid; --- 26 unchanged lines hidden (view full) --- 1246/* 1247 * Test whether the specified credentials imply "super-user" privilege. 1248 * Return 0 or EPERM. 1249 */ 1250int 1251suser(p) 1252 struct proc *p; 1253{ | 1174} 1175 1176/* 1177 * Check if gid is a member of the group set. 1178 */ 1179int 1180groupmember(gid, cred) 1181 gid_t gid; --- 26 unchanged lines hidden (view full) --- 1208/* 1209 * Test whether the specified credentials imply "super-user" privilege. 1210 * Return 0 or EPERM. 1211 */ 1212int 1213suser(p) 1214 struct proc *p; 1215{ |
1254 return suser_xxx(0, p, 0); | 1216 1217 return (suser_xxx(0, p, 0)); |
1255} 1256 1257/* 1258 * version for when the thread pointer is available and not the proc. 1259 * (saves having to include proc.h into every file that needs to do the change.) 1260 */ 1261int 1262suser_td(td) | 1218} 1219 1220/* 1221 * version for when the thread pointer is available and not the proc. 1222 * (saves having to include proc.h into every file that needs to do the change.) 1223 */ 1224int 1225suser_td(td) |
1263 | |
1264 struct thread *td; 1265{ 1266 return suser_xxx(0, td->td_proc, 0); 1267} 1268 1269/* 1270 * wrapper to use if you have the thread on hand but not the proc. 1271 */ --- 13 unchanged lines hidden (view full) --- 1285 int flag; 1286{ 1287 if (!suser_enabled) 1288 return (EPERM); 1289 if (!cred && !proc) { 1290 printf("suser_xxx(): THINK!\n"); 1291 return (EPERM); 1292 } | 1226 struct thread *td; 1227{ 1228 return suser_xxx(0, td->td_proc, 0); 1229} 1230 1231/* 1232 * wrapper to use if you have the thread on hand but not the proc. 1233 */ --- 13 unchanged lines hidden (view full) --- 1247 int flag; 1248{ 1249 if (!suser_enabled) 1250 return (EPERM); 1251 if (!cred && !proc) { 1252 printf("suser_xxx(): THINK!\n"); 1253 return (EPERM); 1254 } |
1293 if (!cred) | 1255 if (cred == NULL) |
1294 cred = proc->p_ucred; | 1256 cred = proc->p_ucred; |
1295 if (cred->cr_uid != 0) | 1257 if (cred->cr_uid != 0) |
1296 return (EPERM); 1297 if (jailed(cred) && !(flag & PRISON_ROOT)) 1298 return (EPERM); 1299 return (0); 1300} 1301 1302/* | 1258 return (EPERM); 1259 if (jailed(cred) && !(flag & PRISON_ROOT)) 1260 return (EPERM); 1261 return (0); 1262} 1263 1264/* |
1303 * Test (local, globale) securelevel values against passed required 1304 * securelevel. _gt implements (level > securelevel), and _ge implements 1305 * (level >= securelevel). Returns 0 oer EPERM. | 1265 * Test the active securelevel against a given level. securelevel_gt() 1266 * implements (securelevel > level). securelevel_ge() implements 1267 * (securelevel >= level). Note that the logic is inverted -- these 1268 * functions return EPERM on "success" and 0 on "failure". |
1306 * 1307 * cr is permitted to be NULL for the time being, as there were some 1308 * existing securelevel checks that occurred without a process/credential | 1269 * 1270 * cr is permitted to be NULL for the time being, as there were some 1271 * existing securelevel checks that occurred without a process/credential |
1309 * context. In the future this will be disallowed, so a kernel 1310 * message is displayed. | 1272 * context. In the future this will be disallowed, so a kernel message 1273 * is displayed. |
1311 */ 1312int 1313securelevel_gt(struct ucred *cr, int level) 1314{ | 1274 */ 1275int 1276securelevel_gt(struct ucred *cr, int level) 1277{ |
1278 int active_securelevel; |
|
1315 | 1279 |
1316 if (cr == NULL) { | 1280 active_securelevel = securelevel; 1281 if (cr == NULL) |
1317 printf("securelevel_gt: cr is NULL\n"); | 1282 printf("securelevel_gt: cr is NULL\n"); |
1318 if (level > securelevel) 1319 return (0); 1320 else 1321 return (EPERM); 1322 } else if (cr->cr_prison == NULL) { 1323 if (level > securelevel) 1324 return (0); 1325 else 1326 return (EPERM); 1327 } else { 1328 if (level > imax(cr->cr_prison->pr_securelevel, securelevel)) 1329 return (0); 1330 else 1331 return (EPERM); 1332 } 1333 | 1283 if (cr->cr_prison != NULL) 1284 active_securelevel = imax(cr->cr_prison->pr_securelevel, 1285 active_securelevel); 1286 return (active_securelevel > level ? EPERM : 0); |
1334} 1335 1336int 1337securelevel_ge(struct ucred *cr, int level) 1338{ | 1287} 1288 1289int 1290securelevel_ge(struct ucred *cr, int level) 1291{ |
1292 int active_securelevel; |
|
1339 | 1293 |
1340 if (cr == NULL) { 1341 printf("securelevel_ge: cr is NULL\n"); 1342 if (level >= securelevel) 1343 return (0); 1344 else 1345 return (EPERM); 1346 } if (cr->cr_prison == NULL) { 1347 if (level >= securelevel) 1348 return (0); 1349 else 1350 return (EPERM); 1351 } else { 1352 if (level >= imax(cr->cr_prison->pr_securelevel, securelevel)) 1353 return (0); 1354 else 1355 return (EPERM); 1356 } | 1294 active_securelevel = securelevel; 1295 if (cr == NULL) 1296 printf("securelevel_gt: cr is NULL\n"); 1297 if (cr->cr_prison != NULL) 1298 active_securelevel = imax(cr->cr_prison->pr_securelevel, 1299 active_securelevel); 1300 return (active_securelevel >= level ? EPERM : 0); |
1357} 1358 1359/* 1360 * 'see_other_uids' determines whether or not visibility of processes | 1301} 1302 1303/* 1304 * 'see_other_uids' determines whether or not visibility of processes |
1361 * and sockets with credentials holding different real uid's is possible | 1305 * and sockets with credentials holding different real uids is possible |
1362 * using a variety of system MIBs. | 1306 * using a variety of system MIBs. |
1307 * XXX: data declarations should be together near the beginning of the file. |
|
1363 */ 1364static int see_other_uids = 1; | 1308 */ 1309static int see_other_uids = 1; |
1365SYSCTL_INT(_kern_security_bsd, OID_AUTO, see_other_uids, 1366 CTLFLAG_RW, &see_other_uids, 0, | 1310SYSCTL_INT(_kern_security_bsd, OID_AUTO, see_other_uids, CTLFLAG_RW, 1311 &see_other_uids, 0, |
1367 "Unprivileged processes may see subjects/objects with different real uid"); 1368 1369/*- 1370 * Determine if u1 "can see" the subject specified by u2. 1371 * Returns: 0 for permitted, an errno value otherwise 1372 * Locks: none | 1312 "Unprivileged processes may see subjects/objects with different real uid"); 1313 1314/*- 1315 * Determine if u1 "can see" the subject specified by u2. 1316 * Returns: 0 for permitted, an errno value otherwise 1317 * Locks: none |
1373 * References: u1 and u2 must be immutable credentials 1374 * u1 and u2 must be valid for the lifetime of the call | 1318 * References: *u1 and *u2 must not change during the call |
1375 * u1 may equal u2, in which case only one reference is required 1376 */ 1377int 1378cr_cansee(struct ucred *u1, struct ucred *u2) 1379{ 1380 int error; 1381 1382 if ((error = prison_check(u1, u2))) --- 92 unchanged lines hidden (view full) --- 1475 p1->p_ucred->cr_uid != p2->p_ucred->cr_ruid && 1476 p1->p_ucred->cr_uid != p2->p_ucred->cr_svuid) { 1477 /* Not permitted, try privilege. */ 1478 error = suser_xxx(NULL, p1, PRISON_ROOT); 1479 if (error) 1480 return (error); 1481 } 1482 | 1319 * u1 may equal u2, in which case only one reference is required 1320 */ 1321int 1322cr_cansee(struct ucred *u1, struct ucred *u2) 1323{ 1324 int error; 1325 1326 if ((error = prison_check(u1, u2))) --- 92 unchanged lines hidden (view full) --- 1419 p1->p_ucred->cr_uid != p2->p_ucred->cr_ruid && 1420 p1->p_ucred->cr_uid != p2->p_ucred->cr_svuid) { 1421 /* Not permitted, try privilege. */ 1422 error = suser_xxx(NULL, p1, PRISON_ROOT); 1423 if (error) 1424 return (error); 1425 } 1426 |
1483 return (0); | 1427 return (0); |
1484} 1485 1486/*- | 1428} 1429 1430/*- |
1487 * Determine whether p1 may reschedule p2 | 1431 * Determine whether p1 may reschedule p2. |
1488 * Returns: 0 for permitted, an errno value otherwise 1489 * Locks: Sufficient locks to protect various components of p1 and p2 1490 * must be held. Normally, p1 will be curproc, and a lock must 1491 * be held for p2. 1492 * References: p1 and p2 must be valid for the lifetime of the call 1493 */ 1494int 1495p_cansched(struct proc *p1, struct proc *p2) --- 23 unchanged lines hidden (view full) --- 1519 * The 'unprivileged_procdebug_permitted' flag may be used to disable 1520 * a variety of unprivileged inter-process debugging services, including 1521 * some procfs functionality, ptrace(), and ktrace(). In the past, 1522 * inter-process debugging has been involved in a variety of security 1523 * problems, and sites not requiring the service might choose to disable it 1524 * when hardening systems. 1525 * 1526 * XXX: Should modifying and reading this variable require locking? | 1432 * Returns: 0 for permitted, an errno value otherwise 1433 * Locks: Sufficient locks to protect various components of p1 and p2 1434 * must be held. Normally, p1 will be curproc, and a lock must 1435 * be held for p2. 1436 * References: p1 and p2 must be valid for the lifetime of the call 1437 */ 1438int 1439p_cansched(struct proc *p1, struct proc *p2) --- 23 unchanged lines hidden (view full) --- 1463 * The 'unprivileged_procdebug_permitted' flag may be used to disable 1464 * a variety of unprivileged inter-process debugging services, including 1465 * some procfs functionality, ptrace(), and ktrace(). In the past, 1466 * inter-process debugging has been involved in a variety of security 1467 * problems, and sites not requiring the service might choose to disable it 1468 * when hardening systems. 1469 * 1470 * XXX: Should modifying and reading this variable require locking? |
1471 * XXX: data declarations should be together near the beginning of the file. |
|
1527 */ 1528static int unprivileged_proc_debug = 1; | 1472 */ 1473static int unprivileged_proc_debug = 1; |
1529SYSCTL_INT(_kern_security_bsd, OID_AUTO, unprivileged_proc_debug, 1530 CTLFLAG_RW, &unprivileged_proc_debug, 0, | 1474SYSCTL_INT(_kern_security_bsd, OID_AUTO, unprivileged_proc_debug, CTLFLAG_RW, 1475 &unprivileged_proc_debug, 0, |
1531 "Unprivileged processes may use process debugging facilities"); 1532 1533/*- 1534 * Determine whether p1 may debug p2. 1535 * Returns: 0 for permitted, an errno value otherwise 1536 * Locks: Sufficient locks to protect various components of p1 and p2 1537 * must be held. Normally, p1 will be curproc, and a lock must 1538 * be held for p2. 1539 * References: p1 and p2 must be valid for the lifetime of the call 1540 */ 1541int 1542p_candebug(struct proc *p1, struct proc *p2) 1543{ | 1476 "Unprivileged processes may use process debugging facilities"); 1477 1478/*- 1479 * Determine whether p1 may debug p2. 1480 * Returns: 0 for permitted, an errno value otherwise 1481 * Locks: Sufficient locks to protect various components of p1 and p2 1482 * must be held. Normally, p1 will be curproc, and a lock must 1483 * be held for p2. 1484 * References: p1 and p2 must be valid for the lifetime of the call 1485 */ 1486int 1487p_candebug(struct proc *p1, struct proc *p2) 1488{ |
1544 int error, i, grpsubset, uidsubset, credentialchanged; | 1489 int credentialchanged, error, grpsubset, i, uidsubset; |
1545 1546 if (!unprivileged_proc_debug) { 1547 error = suser_xxx(NULL, p1, PRISON_ROOT); 1548 if (error) 1549 return (error); 1550 } | 1490 1491 if (!unprivileged_proc_debug) { 1492 error = suser_xxx(NULL, p1, PRISON_ROOT); 1493 if (error) 1494 return (error); 1495 } |
1551 | |
1552 if (p1 == p2) 1553 return (0); | 1496 if (p1 == p2) 1497 return (0); |
1554 | |
1555 if ((error = prison_check(p1->p_ucred, p2->p_ucred))) 1556 return (error); 1557 1558 /* 1559 * Is p2's group set a subset of p1's effective group set? This 1560 * includes p2's egid, group access list, rgid, and svgid. 1561 */ 1562 grpsubset = 1; --- 27 unchanged lines hidden (view full) --- 1590 * require CAP_SYS_PTRACE. 1591 */ 1592 if (!grpsubset || !uidsubset || credentialchanged) { 1593 error = suser_xxx(NULL, p1, PRISON_ROOT); 1594 if (error) 1595 return (error); 1596 } 1597 | 1498 if ((error = prison_check(p1->p_ucred, p2->p_ucred))) 1499 return (error); 1500 1501 /* 1502 * Is p2's group set a subset of p1's effective group set? This 1503 * includes p2's egid, group access list, rgid, and svgid. 1504 */ 1505 grpsubset = 1; --- 27 unchanged lines hidden (view full) --- 1533 * require CAP_SYS_PTRACE. 1534 */ 1535 if (!grpsubset || !uidsubset || credentialchanged) { 1536 error = suser_xxx(NULL, p1, PRISON_ROOT); 1537 if (error) 1538 return (error); 1539 } 1540 |
1598 /* can't trace init when securelevel > 0 */ 1599 if (p2->p_pid == 1) { | 1541 /* Can't trace init when securelevel > 0. */ 1542 if (p2 == initproc) { |
1600 error = securelevel_gt(p1->p_ucred, 0); 1601 if (error) 1602 return (error); 1603 } 1604 1605 /* 1606 * Can't trace a process that's currently exec'ing. 1607 * XXX: Note, this is not a security policy decision, it's a --- 29 unchanged lines hidden (view full) --- 1637{ 1638 1639 mtx_lock(&cr->cr_mtx); 1640 cr->cr_ref++; 1641 mtx_unlock(&cr->cr_mtx); 1642 return (cr); 1643} 1644 | 1543 error = securelevel_gt(p1->p_ucred, 0); 1544 if (error) 1545 return (error); 1546 } 1547 1548 /* 1549 * Can't trace a process that's currently exec'ing. 1550 * XXX: Note, this is not a security policy decision, it's a --- 29 unchanged lines hidden (view full) --- 1580{ 1581 1582 mtx_lock(&cr->cr_mtx); 1583 cr->cr_ref++; 1584 mtx_unlock(&cr->cr_mtx); 1585 return (cr); 1586} 1587 |
1645 | |
1646/* 1647 * Free a cred structure. 1648 * Throws away space when ref count gets to 0. 1649 */ 1650void 1651crfree(cr) 1652 struct ucred *cr; 1653{ --- 12 unchanged lines hidden (view full) --- 1666 if (cr->cr_ruidinfo != NULL) 1667 uifree(cr->cr_ruidinfo); 1668 /* 1669 * Free a prison, if any. 1670 */ 1671 if (jailed(cr)) 1672 prison_free(cr->cr_prison); 1673 FREE((caddr_t)cr, M_CRED); | 1588/* 1589 * Free a cred structure. 1590 * Throws away space when ref count gets to 0. 1591 */ 1592void 1593crfree(cr) 1594 struct ucred *cr; 1595{ --- 12 unchanged lines hidden (view full) --- 1608 if (cr->cr_ruidinfo != NULL) 1609 uifree(cr->cr_ruidinfo); 1610 /* 1611 * Free a prison, if any. 1612 */ 1613 if (jailed(cr)) 1614 prison_free(cr->cr_prison); 1615 FREE((caddr_t)cr, M_CRED); |
1674 } else { | 1616 } else |
1675 mtx_unlock(&cr->cr_mtx); | 1617 mtx_unlock(&cr->cr_mtx); |
1676 } | |
1677} 1678 1679/* 1680 * Check to see if this ucred is shared. 1681 */ 1682int 1683crshared(cr) 1684 struct ucred *cr; --- 11 unchanged lines hidden (view full) --- 1696 */ 1697void 1698crcopy(dest, src) 1699 struct ucred *dest, *src; 1700{ 1701 1702 KASSERT(crshared(dest) == 0, ("crcopy of shared ucred")); 1703 bcopy(&src->cr_startcopy, &dest->cr_startcopy, | 1618} 1619 1620/* 1621 * Check to see if this ucred is shared. 1622 */ 1623int 1624crshared(cr) 1625 struct ucred *cr; --- 11 unchanged lines hidden (view full) --- 1637 */ 1638void 1639crcopy(dest, src) 1640 struct ucred *dest, *src; 1641{ 1642 1643 KASSERT(crshared(dest) == 0, ("crcopy of shared ucred")); 1644 bcopy(&src->cr_startcopy, &dest->cr_startcopy, |
1704 (unsigned)((caddr_t)&src->cr_endcopy - | 1645 (unsigned)((caddr_t)&src->cr_endcopy - |
1705 (caddr_t)&src->cr_startcopy)); 1706 uihold(dest->cr_uidinfo); 1707 uihold(dest->cr_ruidinfo); 1708 if (jailed(dest)) 1709 prison_hold(dest->cr_prison); 1710} 1711 1712/* --- 57 unchanged lines hidden (view full) --- 1770 struct thread *td; 1771 struct setlogin_args *uap; 1772{ 1773 struct proc *p = td->td_proc; 1774 int error; 1775 char logintmp[MAXLOGNAME]; 1776 1777 mtx_lock(&Giant); | 1646 (caddr_t)&src->cr_startcopy)); 1647 uihold(dest->cr_uidinfo); 1648 uihold(dest->cr_ruidinfo); 1649 if (jailed(dest)) 1650 prison_hold(dest->cr_prison); 1651} 1652 1653/* --- 57 unchanged lines hidden (view full) --- 1711 struct thread *td; 1712 struct setlogin_args *uap; 1713{ 1714 struct proc *p = td->td_proc; 1715 int error; 1716 char logintmp[MAXLOGNAME]; 1717 1718 mtx_lock(&Giant); |
1778 if ((error = suser_xxx(0, p, PRISON_ROOT))) | 1719 if ((error = suser_xxx(0, p, PRISON_ROOT)) != 0) |
1779 goto done2; 1780 error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp, 1781 sizeof(logintmp), (size_t *)0); | 1720 goto done2; 1721 error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp, 1722 sizeof(logintmp), (size_t *)0); |
1782 if (error == ENAMETOOLONG) { | 1723 if (error == ENAMETOOLONG) |
1783 error = EINVAL; | 1724 error = EINVAL; |
1784 } else if (!error) { 1785 (void) memcpy(p->p_pgrp->pg_session->s_login, logintmp, | 1725 else if (!error) 1726 (void)memcpy(p->p_pgrp->pg_session->s_login, logintmp, |
1786 sizeof(logintmp)); | 1727 sizeof(logintmp)); |
1787 } | |
1788done2: 1789 mtx_unlock(&Giant); 1790 return (error); 1791} 1792 1793void 1794setsugid(p) 1795 struct proc *p; --- 103 unchanged lines hidden --- | 1728done2: 1729 mtx_unlock(&Giant); 1730 return (error); 1731} 1732 1733void 1734setsugid(p) 1735 struct proc *p; --- 103 unchanged lines hidden --- |