kern_prot.c (82693) | kern_prot.c (82749) |
---|---|
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. 6 * All or some portions of this file are derived from material licensed 7 * to the University of California by American Telephone and Telegraph 8 * Co. or Unix System Laboratories, Inc. and are reproduced herein with --- 23 unchanged lines hidden (view full) --- 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 * Copyright (c) 2000, 2001 Robert N. M. Watson. All rights reserved. 5 * (c) UNIX System Laboratories, Inc. 6 * All or some portions of this file are derived from material licensed 7 * to the University of California by American Telephone and Telegraph 8 * Co. or Unix System Laboratories, Inc. and are reproduced herein with --- 23 unchanged lines hidden (view full) --- 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 82693 2001-08-31 21:44:12Z rwatson $ | 40 * $FreeBSD: head/sys/kern/kern_prot.c 82749 2001-09-01 19:04:37Z dillon $ |
41 */ 42 43/* 44 * System calls related to processes and protection 45 */ 46 47#include "opt_compat.h" 48#include "opt_global.h" --- 19 unchanged lines hidden (view full) --- 68 69#ifndef _SYS_SYSPROTO_H_ 70struct getpid_args { 71 int dummy; 72}; 73#endif 74 75/* | 41 */ 42 43/* 44 * System calls related to processes and protection 45 */ 46 47#include "opt_compat.h" 48#include "opt_global.h" --- 19 unchanged lines hidden (view full) --- 68 69#ifndef _SYS_SYSPROTO_H_ 70struct getpid_args { 71 int dummy; 72}; 73#endif 74 75/* |
76 * getpid - MP SAFE | 76 * getpid |
77 */ 78 | 77 */ 78 |
79/* 80 * MPSAFE 81 */ |
|
79/* ARGSUSED */ 80int 81getpid(p, uap) 82 struct proc *p; 83 struct getpid_args *uap; 84{ 85 | 82/* ARGSUSED */ 83int 84getpid(p, uap) 85 struct proc *p; 86 struct getpid_args *uap; 87{ 88 |
89 mtx_lock(&Giant); |
|
86 p->p_retval[0] = p->p_pid; 87#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 88 PROC_LOCK(p); 89 p->p_retval[1] = p->p_pptr->p_pid; 90 PROC_UNLOCK(p); 91#endif | 90 p->p_retval[0] = p->p_pid; 91#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 92 PROC_LOCK(p); 93 p->p_retval[1] = p->p_pptr->p_pid; 94 PROC_UNLOCK(p); 95#endif |
96 mtx_unlock(&Giant); |
|
92 return (0); 93} 94 95/* | 97 return (0); 98} 99 100/* |
96 * getppid - MP SAFE | 101 * getppid |
97 */ 98 99#ifndef _SYS_SYSPROTO_H_ 100struct getppid_args { 101 int dummy; 102}; 103#endif | 102 */ 103 104#ifndef _SYS_SYSPROTO_H_ 105struct getppid_args { 106 int dummy; 107}; 108#endif |
109/* 110 * MPSAFE 111 */ |
|
104/* ARGSUSED */ 105int 106getppid(p, uap) 107 struct proc *p; 108 struct getppid_args *uap; 109{ 110 | 112/* ARGSUSED */ 113int 114getppid(p, uap) 115 struct proc *p; 116 struct getppid_args *uap; 117{ 118 |
119 mtx_lock(&Giant); |
|
111 PROC_LOCK(p); 112 p->p_retval[0] = p->p_pptr->p_pid; 113 PROC_UNLOCK(p); | 120 PROC_LOCK(p); 121 p->p_retval[0] = p->p_pptr->p_pid; 122 PROC_UNLOCK(p); |
123 mtx_unlock(&Giant); |
|
114 return (0); 115} 116 117/* 118 * Get process group ID; note that POSIX getpgrp takes no parameter 119 * 120 * MP SAFE 121 */ 122#ifndef _SYS_SYSPROTO_H_ 123struct getpgrp_args { 124 int dummy; 125}; 126#endif | 124 return (0); 125} 126 127/* 128 * Get process group ID; note that POSIX getpgrp takes no parameter 129 * 130 * MP SAFE 131 */ 132#ifndef _SYS_SYSPROTO_H_ 133struct getpgrp_args { 134 int dummy; 135}; 136#endif |
127 | 137/* 138 * MPSAFE 139 */ |
128int 129getpgrp(p, uap) 130 struct proc *p; 131 struct getpgrp_args *uap; 132{ 133 | 140int 141getpgrp(p, uap) 142 struct proc *p; 143 struct getpgrp_args *uap; 144{ 145 |
146 mtx_lock(&Giant); |
|
134 p->p_retval[0] = p->p_pgrp->pg_id; | 147 p->p_retval[0] = p->p_pgrp->pg_id; |
148 mtx_unlock(&Giant); |
|
135 return (0); 136} 137 138/* Get an arbitary pid's process group id */ 139#ifndef _SYS_SYSPROTO_H_ 140struct getpgid_args { 141 pid_t pid; 142}; 143#endif 144 | 149 return (0); 150} 151 152/* Get an arbitary pid's process group id */ 153#ifndef _SYS_SYSPROTO_H_ 154struct getpgid_args { 155 pid_t pid; 156}; 157#endif 158 |
159/* 160 * MPSAFE 161 */ |
|
145int 146getpgid(p, uap) 147 struct proc *p; 148 struct getpgid_args *uap; 149{ 150 struct proc *pt; | 162int 163getpgid(p, uap) 164 struct proc *p; 165 struct getpgid_args *uap; 166{ 167 struct proc *pt; |
151 int error; | 168 int error = 0; |
152 | 169 |
170 mtx_lock(&Giant); |
|
153 if (uap->pid == 0) 154 p->p_retval[0] = p->p_pgrp->pg_id; 155 else { | 171 if (uap->pid == 0) 172 p->p_retval[0] = p->p_pgrp->pg_id; 173 else { |
156 if ((pt = pfind(uap->pid)) == NULL) 157 return ESRCH; | 174 if ((pt = pfind(uap->pid)) == NULL) { 175 error = ESRCH; 176 goto done2; 177 } |
158 if ((error = p_cansee(p, pt))) { 159 PROC_UNLOCK(pt); | 178 if ((error = p_cansee(p, pt))) { 179 PROC_UNLOCK(pt); |
160 return (error); | 180 goto done2; |
161 } 162 p->p_retval[0] = pt->p_pgrp->pg_id; 163 PROC_UNLOCK(pt); 164 } | 181 } 182 p->p_retval[0] = pt->p_pgrp->pg_id; 183 PROC_UNLOCK(pt); 184 } |
165 return 0; | 185done2: 186 mtx_unlock(&Giant); 187 return (error); |
166} 167 168/* 169 * Get an arbitary pid's session id. 170 */ 171#ifndef _SYS_SYSPROTO_H_ 172struct getsid_args { 173 pid_t pid; 174}; 175#endif 176 | 188} 189 190/* 191 * Get an arbitary pid's session id. 192 */ 193#ifndef _SYS_SYSPROTO_H_ 194struct getsid_args { 195 pid_t pid; 196}; 197#endif 198 |
199/* 200 * MPSAFE 201 */ |
|
177int 178getsid(p, uap) 179 struct proc *p; 180 struct getsid_args *uap; 181{ 182 struct proc *pt; | 202int 203getsid(p, uap) 204 struct proc *p; 205 struct getsid_args *uap; 206{ 207 struct proc *pt; |
183 int error; | 208 int error = 0; |
184 | 209 |
185 if (uap->pid == 0) | 210 mtx_lock(&Giant); 211 if (uap->pid == 0) { |
186 p->p_retval[0] = p->p_session->s_sid; | 212 p->p_retval[0] = p->p_session->s_sid; |
187 else { 188 if ((pt = pfind(uap->pid)) == NULL) 189 return ESRCH; | 213 } else { 214 if ((pt = pfind(uap->pid)) == NULL) { 215 error = ESRCH; 216 goto done2; 217 } |
190 if ((error = p_cansee(p, pt))) { 191 PROC_UNLOCK(pt); | 218 if ((error = p_cansee(p, pt))) { 219 PROC_UNLOCK(pt); |
192 return (error); | 220 goto done2; |
193 } 194 p->p_retval[0] = pt->p_session->s_sid; 195 PROC_UNLOCK(pt); 196 } | 221 } 222 p->p_retval[0] = pt->p_session->s_sid; 223 PROC_UNLOCK(pt); 224 } |
197 return 0; | 225done2: 226 mtx_unlock(&Giant); 227 return (error); |
198} 199 200 201/* 202 * getuid() - MP SAFE 203 */ 204#ifndef _SYS_SYSPROTO_H_ 205struct getuid_args { 206 int dummy; 207}; 208#endif 209 | 228} 229 230 231/* 232 * getuid() - MP SAFE 233 */ 234#ifndef _SYS_SYSPROTO_H_ 235struct getuid_args { 236 int dummy; 237}; 238#endif 239 |
240/* 241 * MPSAFE 242 */ |
|
210/* ARGSUSED */ 211int 212getuid(p, uap) 213 struct proc *p; 214 struct getuid_args *uap; 215{ 216 | 243/* ARGSUSED */ 244int 245getuid(p, uap) 246 struct proc *p; 247 struct getuid_args *uap; 248{ 249 |
250 mtx_lock(&Giant); |
|
217 p->p_retval[0] = p->p_ucred->cr_ruid; 218#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 219 p->p_retval[1] = p->p_ucred->cr_uid; 220#endif | 251 p->p_retval[0] = p->p_ucred->cr_ruid; 252#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 253 p->p_retval[1] = p->p_ucred->cr_uid; 254#endif |
255 mtx_unlock(&Giant); |
|
221 return (0); 222} 223 224/* 225 * geteuid() - MP SAFE 226 */ 227#ifndef _SYS_SYSPROTO_H_ 228struct geteuid_args { 229 int dummy; 230}; 231#endif 232 233/* ARGSUSED */ 234int 235geteuid(p, uap) 236 struct proc *p; 237 struct geteuid_args *uap; 238{ 239 | 256 return (0); 257} 258 259/* 260 * geteuid() - MP SAFE 261 */ 262#ifndef _SYS_SYSPROTO_H_ 263struct geteuid_args { 264 int dummy; 265}; 266#endif 267 268/* ARGSUSED */ 269int 270geteuid(p, uap) 271 struct proc *p; 272 struct geteuid_args *uap; 273{ 274 |
275 mtx_lock(&Giant); |
|
240 p->p_retval[0] = p->p_ucred->cr_uid; | 276 p->p_retval[0] = p->p_ucred->cr_uid; |
277 mtx_unlock(&Giant); |
|
241 return (0); 242} 243 244/* 245 * getgid() - MP SAFE 246 */ 247#ifndef _SYS_SYSPROTO_H_ 248struct getgid_args { 249 int dummy; 250}; 251#endif 252 | 278 return (0); 279} 280 281/* 282 * getgid() - MP SAFE 283 */ 284#ifndef _SYS_SYSPROTO_H_ 285struct getgid_args { 286 int dummy; 287}; 288#endif 289 |
290/* 291 * MPSAFE 292 */ |
|
253/* ARGSUSED */ 254int 255getgid(p, uap) 256 struct proc *p; 257 struct getgid_args *uap; 258{ 259 | 293/* ARGSUSED */ 294int 295getgid(p, uap) 296 struct proc *p; 297 struct getgid_args *uap; 298{ 299 |
300 mtx_lock(&Giant); |
|
260 p->p_retval[0] = p->p_ucred->cr_rgid; 261#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 262 p->p_retval[1] = p->p_ucred->cr_groups[0]; 263#endif | 301 p->p_retval[0] = p->p_ucred->cr_rgid; 302#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 303 p->p_retval[1] = p->p_ucred->cr_groups[0]; 304#endif |
305 mtx_unlock(&Giant); |
|
264 return (0); 265} 266 267/* 268 * Get effective group ID. The "egid" is groups[0], and could be obtained 269 * via getgroups. This syscall exists because it is somewhat painful to do 270 * correctly in a library function. 271 */ 272#ifndef _SYS_SYSPROTO_H_ 273struct getegid_args { 274 int dummy; 275}; 276#endif 277 | 306 return (0); 307} 308 309/* 310 * Get effective group ID. The "egid" is groups[0], and could be obtained 311 * via getgroups. This syscall exists because it is somewhat painful to do 312 * correctly in a library function. 313 */ 314#ifndef _SYS_SYSPROTO_H_ 315struct getegid_args { 316 int dummy; 317}; 318#endif 319 |
320/* 321 * MPSAFE 322 */ |
|
278/* ARGSUSED */ 279int 280getegid(p, uap) 281 struct proc *p; 282 struct getegid_args *uap; 283{ 284 | 323/* ARGSUSED */ 324int 325getegid(p, uap) 326 struct proc *p; 327 struct getegid_args *uap; 328{ 329 |
330 mtx_lock(&Giant); |
|
285 p->p_retval[0] = p->p_ucred->cr_groups[0]; | 331 p->p_retval[0] = p->p_ucred->cr_groups[0]; |
332 mtx_unlock(&Giant); |
|
286 return (0); 287} 288 289#ifndef _SYS_SYSPROTO_H_ 290struct getgroups_args { 291 u_int gidsetsize; 292 gid_t *gidset; 293}; 294#endif | 333 return (0); 334} 335 336#ifndef _SYS_SYSPROTO_H_ 337struct getgroups_args { 338 u_int gidsetsize; 339 gid_t *gidset; 340}; 341#endif |
342/* 343 * MPSAFE 344 */ |
|
295int 296getgroups(p, uap) 297 struct proc *p; 298 register struct getgroups_args *uap; 299{ | 345int 346getgroups(p, uap) 347 struct proc *p; 348 register struct getgroups_args *uap; 349{ |
300 struct ucred *cred = p->p_ucred; | 350 struct ucred *cred; |
301 u_int ngrp; | 351 u_int ngrp; |
302 int error; | 352 int error = 0; |
303 | 353 |
354 mtx_lock(&Giant); 355 cred = p->p_ucred; |
|
304 if ((ngrp = uap->gidsetsize) == 0) { 305 p->p_retval[0] = cred->cr_ngroups; | 356 if ((ngrp = uap->gidsetsize) == 0) { 357 p->p_retval[0] = cred->cr_ngroups; |
306 return (0); | 358 error = 0; 359 goto done2; |
307 } | 360 } |
308 if (ngrp < cred->cr_ngroups) 309 return (EINVAL); | 361 if (ngrp < cred->cr_ngroups) { 362 error = EINVAL; 363 goto done2; 364 } |
310 ngrp = cred->cr_ngroups; 311 if ((error = copyout((caddr_t)cred->cr_groups, | 365 ngrp = cred->cr_ngroups; 366 if ((error = copyout((caddr_t)cred->cr_groups, |
312 (caddr_t)uap->gidset, ngrp * sizeof(gid_t)))) 313 return (error); | 367 (caddr_t)uap->gidset, ngrp * sizeof(gid_t)))) { 368 goto done2; 369 } |
314 p->p_retval[0] = ngrp; | 370 p->p_retval[0] = ngrp; |
315 return (0); | 371done2: 372 mtx_unlock(&Giant); 373 return (error); |
316} 317 318#ifndef _SYS_SYSPROTO_H_ 319struct setsid_args { 320 int dummy; 321}; 322#endif 323 | 374} 375 376#ifndef _SYS_SYSPROTO_H_ 377struct setsid_args { 378 int dummy; 379}; 380#endif 381 |
382/* 383 * MPSAFE 384 */ |
|
324/* ARGSUSED */ 325int 326setsid(p, uap) 327 register struct proc *p; 328 struct setsid_args *uap; 329{ | 385/* ARGSUSED */ 386int 387setsid(p, uap) 388 register struct proc *p; 389 struct setsid_args *uap; 390{ |
391 int error; |
|
330 | 392 |
393 mtx_lock(&Giant); |
|
331 if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) { | 394 if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) { |
332 return (EPERM); | 395 error = EPERM; |
333 } else { 334 (void)enterpgrp(p, p->p_pid, 1); 335 p->p_retval[0] = p->p_pid; | 396 } else { 397 (void)enterpgrp(p, p->p_pid, 1); 398 p->p_retval[0] = p->p_pid; |
336 return (0); | 399 error = 0; |
337 } | 400 } |
401 mtx_unlock(&Giant); 402 return (error); |
|
338} 339 340/* 341 * set process group (setpgid/old setpgrp) 342 * 343 * caller does setpgid(targpid, targpgid) 344 * 345 * pid must be caller or child of caller (ESRCH) --- 5 unchanged lines hidden (view full) --- 351 * pid must not be session leader (EPERM) 352 */ 353#ifndef _SYS_SYSPROTO_H_ 354struct setpgid_args { 355 int pid; /* target process id */ 356 int pgid; /* target pgrp id */ 357}; 358#endif | 403} 404 405/* 406 * set process group (setpgid/old setpgrp) 407 * 408 * caller does setpgid(targpid, targpgid) 409 * 410 * pid must be caller or child of caller (ESRCH) --- 5 unchanged lines hidden (view full) --- 416 * pid must not be session leader (EPERM) 417 */ 418#ifndef _SYS_SYSPROTO_H_ 419struct setpgid_args { 420 int pid; /* target process id */ 421 int pgid; /* target pgrp id */ 422}; 423#endif |
424/* 425 * MPSAFE 426 */ |
|
359/* ARGSUSED */ 360int 361setpgid(curp, uap) 362 struct proc *curp; 363 register struct setpgid_args *uap; 364{ 365 register struct proc *targp; /* target process */ 366 register struct pgrp *pgrp; /* target pgrp */ 367 int error; 368 369 if (uap->pgid < 0) 370 return (EINVAL); | 427/* ARGSUSED */ 428int 429setpgid(curp, uap) 430 struct proc *curp; 431 register struct setpgid_args *uap; 432{ 433 register struct proc *targp; /* target process */ 434 register struct pgrp *pgrp; /* target pgrp */ 435 int error; 436 437 if (uap->pgid < 0) 438 return (EINVAL); |
439 440 mtx_lock(&Giant); 441 |
|
371 if (uap->pid != 0 && uap->pid != curp->p_pid) { 372 if ((targp = pfind(uap->pid)) == NULL || !inferior(targp)) { 373 if (targp) 374 PROC_UNLOCK(targp); | 442 if (uap->pid != 0 && uap->pid != curp->p_pid) { 443 if ((targp = pfind(uap->pid)) == NULL || !inferior(targp)) { 444 if (targp) 445 PROC_UNLOCK(targp); |
375 return (ESRCH); | 446 error = ESRCH; 447 goto done2; |
376 } 377 if ((error = p_cansee(curproc, targp))) { 378 PROC_UNLOCK(targp); | 448 } 449 if ((error = p_cansee(curproc, targp))) { 450 PROC_UNLOCK(targp); |
379 return (error); | 451 goto done2; |
380 } 381 if (targp->p_pgrp == NULL || 382 targp->p_session != curp->p_session) { 383 PROC_UNLOCK(targp); | 452 } 453 if (targp->p_pgrp == NULL || 454 targp->p_session != curp->p_session) { 455 PROC_UNLOCK(targp); |
384 return (EPERM); | 456 error = EPERM; 457 goto done2; |
385 } 386 if (targp->p_flag & P_EXEC) { 387 PROC_UNLOCK(targp); | 458 } 459 if (targp->p_flag & P_EXEC) { 460 PROC_UNLOCK(targp); |
388 return (EACCES); | 461 error = EACCES; 462 goto done2; |
389 } 390 } else { 391 targp = curp; 392 PROC_LOCK(curp); /* XXX: not needed */ 393 } 394 if (SESS_LEADER(targp)) { 395 PROC_UNLOCK(targp); | 463 } 464 } else { 465 targp = curp; 466 PROC_LOCK(curp); /* XXX: not needed */ 467 } 468 if (SESS_LEADER(targp)) { 469 PROC_UNLOCK(targp); |
396 return (EPERM); | 470 error = EPERM; 471 goto done2; |
397 } | 472 } |
398 if (uap->pgid == 0) | 473 if (uap->pgid == 0) { |
399 uap->pgid = targp->p_pid; | 474 uap->pgid = targp->p_pid; |
400 else if (uap->pgid != targp->p_pid) | 475 } else if (uap->pgid != targp->p_pid) { |
401 if ((pgrp = pgfind(uap->pgid)) == 0 || 402 pgrp->pg_session != curp->p_session) { 403 PROC_UNLOCK(targp); | 476 if ((pgrp = pgfind(uap->pgid)) == 0 || 477 pgrp->pg_session != curp->p_session) { 478 PROC_UNLOCK(targp); |
404 return (EPERM); | 479 error = EPERM; 480 goto done2; |
405 } | 481 } |
482 } |
|
406 /* XXX: We should probably hold the lock across enterpgrp. */ 407 PROC_UNLOCK(targp); | 483 /* XXX: We should probably hold the lock across enterpgrp. */ 484 PROC_UNLOCK(targp); |
408 return (enterpgrp(targp, uap->pgid, 0)); | 485 error = enterpgrp(targp, uap->pgid, 0); 486done2: 487 mtx_unlock(&Giant); 488 return (error); |
409} 410 411/* 412 * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD 413 * compatible. It says that setting the uid/gid to euid/egid is a special 414 * case of "appropriate privilege". Once the rules are expanded out, this 415 * basically means that setuid(nnn) sets all three id's, in all permitted 416 * cases unless _POSIX_SAVED_IDS is enabled. In that case, setuid(getuid()) 417 * does not set the saved id - this is dangerous for traditional BSD 418 * programs. For this reason, we *really* do not want to set 419 * _POSIX_SAVED_IDS and do not want to clear POSIX_APPENDIX_B_4_2_2. 420 */ 421#define POSIX_APPENDIX_B_4_2_2 422 423#ifndef _SYS_SYSPROTO_H_ 424struct setuid_args { 425 uid_t uid; 426}; 427#endif | 489} 490 491/* 492 * Use the clause in B.4.2.2 that allows setuid/setgid to be 4.2/4.3BSD 493 * compatible. It says that setting the uid/gid to euid/egid is a special 494 * case of "appropriate privilege". Once the rules are expanded out, this 495 * basically means that setuid(nnn) sets all three id's, in all permitted 496 * cases unless _POSIX_SAVED_IDS is enabled. In that case, setuid(getuid()) 497 * does not set the saved id - this is dangerous for traditional BSD 498 * programs. For this reason, we *really* do not want to set 499 * _POSIX_SAVED_IDS and do not want to clear POSIX_APPENDIX_B_4_2_2. 500 */ 501#define POSIX_APPENDIX_B_4_2_2 502 503#ifndef _SYS_SYSPROTO_H_ 504struct setuid_args { 505 uid_t uid; 506}; 507#endif |
508/* 509 * MPSAFE 510 */ |
|
428/* ARGSUSED */ 429int 430setuid(p, uap) 431 struct proc *p; 432 struct setuid_args *uap; 433{ 434 struct ucred *newcred, *oldcred; 435 uid_t uid; | 511/* ARGSUSED */ 512int 513setuid(p, uap) 514 struct proc *p; 515 struct setuid_args *uap; 516{ 517 struct ucred *newcred, *oldcred; 518 uid_t uid; |
436 int error; | 519 int error = 0; |
437 438 uid = uap->uid; 439 oldcred = p->p_ucred; | 520 521 uid = uap->uid; 522 oldcred = p->p_ucred; |
523 mtx_lock(&Giant); 524 |
|
440 /* 441 * See if we have "permission" by POSIX 1003.1 rules. 442 * 443 * Note that setuid(geteuid()) is a special case of 444 * "appropriate privileges" in appendix B.4.2.2. We need 445 * to use this clause to be compatible with traditional BSD 446 * semantics. Basically, it means that "setuid(xx)" sets all 447 * three id's (assuming you have privs). --- 9 unchanged lines hidden (view full) --- 457 if (uid != oldcred->cr_ruid && /* allow setuid(getuid()) */ 458#ifdef _POSIX_SAVED_IDS 459 uid != oldcred->cr_svuid && /* allow setuid(saved gid) */ 460#endif 461#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 462 uid != oldcred->cr_uid && /* allow setuid(geteuid()) */ 463#endif 464 (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) | 525 /* 526 * See if we have "permission" by POSIX 1003.1 rules. 527 * 528 * Note that setuid(geteuid()) is a special case of 529 * "appropriate privileges" in appendix B.4.2.2. We need 530 * to use this clause to be compatible with traditional BSD 531 * semantics. Basically, it means that "setuid(xx)" sets all 532 * three id's (assuming you have privs). --- 9 unchanged lines hidden (view full) --- 542 if (uid != oldcred->cr_ruid && /* allow setuid(getuid()) */ 543#ifdef _POSIX_SAVED_IDS 544 uid != oldcred->cr_svuid && /* allow setuid(saved gid) */ 545#endif 546#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 547 uid != oldcred->cr_uid && /* allow setuid(geteuid()) */ 548#endif 549 (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) |
465 return (error); | 550 goto done2; |
466 467 newcred = crdup(oldcred); 468#ifdef _POSIX_SAVED_IDS 469 /* 470 * Do we have "appropriate privileges" (are we root or uid == euid) 471 * If so, we are changing the real uid and/or saved uid. 472 */ 473 if ( --- 28 unchanged lines hidden (view full) --- 502 * Copy credentials so other references do not see our changes. 503 */ 504 if (uid != oldcred->cr_uid) { 505 change_euid(newcred, uid); 506 setsugid(p); 507 } 508 p->p_ucred = newcred; 509 crfree(oldcred); | 551 552 newcred = crdup(oldcred); 553#ifdef _POSIX_SAVED_IDS 554 /* 555 * Do we have "appropriate privileges" (are we root or uid == euid) 556 * If so, we are changing the real uid and/or saved uid. 557 */ 558 if ( --- 28 unchanged lines hidden (view full) --- 587 * Copy credentials so other references do not see our changes. 588 */ 589 if (uid != oldcred->cr_uid) { 590 change_euid(newcred, uid); 591 setsugid(p); 592 } 593 p->p_ucred = newcred; 594 crfree(oldcred); |
510 return (0); | 595done2: 596 mtx_unlock(&Giant); 597 return (error); |
511} 512 513#ifndef _SYS_SYSPROTO_H_ 514struct seteuid_args { 515 uid_t euid; 516}; 517#endif | 598} 599 600#ifndef _SYS_SYSPROTO_H_ 601struct seteuid_args { 602 uid_t euid; 603}; 604#endif |
605/* 606 * MPSAFE 607 */ |
|
518/* ARGSUSED */ 519int 520seteuid(p, uap) 521 struct proc *p; 522 struct seteuid_args *uap; 523{ 524 struct ucred *newcred, *oldcred; 525 uid_t euid; | 608/* ARGSUSED */ 609int 610seteuid(p, uap) 611 struct proc *p; 612 struct seteuid_args *uap; 613{ 614 struct ucred *newcred, *oldcred; 615 uid_t euid; |
526 int error; | 616 int error = 0; |
527 528 euid = uap->euid; | 617 618 euid = uap->euid; |
619 620 mtx_lock(&Giant); |
|
529 oldcred = p->p_ucred; 530 if (euid != oldcred->cr_ruid && /* allow seteuid(getuid()) */ 531 euid != oldcred->cr_svuid && /* allow seteuid(saved uid) */ | 621 oldcred = p->p_ucred; 622 if (euid != oldcred->cr_ruid && /* allow seteuid(getuid()) */ 623 euid != oldcred->cr_svuid && /* allow seteuid(saved uid) */ |
532 (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) 533 return (error); | 624 (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) { 625 goto done2; 626 } |
534 /* 535 * Everything's okay, do it. Copy credentials so other references do 536 * not see our changes. 537 */ 538 newcred = crdup(oldcred); 539 if (oldcred->cr_uid != euid) { 540 change_euid(newcred, euid); 541 setsugid(p); 542 } 543 p->p_ucred = newcred; 544 crfree(oldcred); | 627 /* 628 * Everything's okay, do it. Copy credentials so other references do 629 * not see our changes. 630 */ 631 newcred = crdup(oldcred); 632 if (oldcred->cr_uid != euid) { 633 change_euid(newcred, euid); 634 setsugid(p); 635 } 636 p->p_ucred = newcred; 637 crfree(oldcred); |
545 return (0); | 638done2: 639 mtx_unlock(&Giant); 640 return (error); |
546} 547 548#ifndef _SYS_SYSPROTO_H_ 549struct setgid_args { 550 gid_t gid; 551}; 552#endif | 641} 642 643#ifndef _SYS_SYSPROTO_H_ 644struct setgid_args { 645 gid_t gid; 646}; 647#endif |
648/* 649 * MPSAFE 650 */ |
|
553/* ARGSUSED */ 554int 555setgid(p, uap) 556 struct proc *p; 557 struct setgid_args *uap; 558{ 559 struct ucred *newcred, *oldcred; 560 gid_t gid; | 651/* ARGSUSED */ 652int 653setgid(p, uap) 654 struct proc *p; 655 struct setgid_args *uap; 656{ 657 struct ucred *newcred, *oldcred; 658 gid_t gid; |
561 int error; | 659 int error = 0; |
562 563 gid = uap->gid; | 660 661 gid = uap->gid; |
662 663 mtx_lock(&Giant); |
|
564 oldcred = p->p_ucred; 565 /* 566 * See if we have "permission" by POSIX 1003.1 rules. 567 * 568 * Note that setgid(getegid()) is a special case of 569 * "appropriate privileges" in appendix B.4.2.2. We need 570 * to use this clause to be compatible with traditional BSD 571 * semantics. Basically, it means that "setgid(xx)" sets all 572 * three id's (assuming you have privs). 573 * 574 * For notes on the logic here, see setuid() above. 575 */ 576 if (gid != oldcred->cr_rgid && /* allow setgid(getgid()) */ 577#ifdef _POSIX_SAVED_IDS 578 gid != oldcred->cr_svgid && /* allow setgid(saved gid) */ 579#endif 580#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 581 gid != oldcred->cr_groups[0] && /* allow setgid(getegid()) */ 582#endif | 664 oldcred = p->p_ucred; 665 /* 666 * See if we have "permission" by POSIX 1003.1 rules. 667 * 668 * Note that setgid(getegid()) is a special case of 669 * "appropriate privileges" in appendix B.4.2.2. We need 670 * to use this clause to be compatible with traditional BSD 671 * semantics. Basically, it means that "setgid(xx)" sets all 672 * three id's (assuming you have privs). 673 * 674 * For notes on the logic here, see setuid() above. 675 */ 676 if (gid != oldcred->cr_rgid && /* allow setgid(getgid()) */ 677#ifdef _POSIX_SAVED_IDS 678 gid != oldcred->cr_svgid && /* allow setgid(saved gid) */ 679#endif 680#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 681 gid != oldcred->cr_groups[0] && /* allow setgid(getegid()) */ 682#endif |
583 (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) 584 return (error); | 683 (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) { 684 goto done2; 685 } |
585 586 newcred = crdup(oldcred); 587#ifdef _POSIX_SAVED_IDS 588 /* 589 * Do we have "appropriate privileges" (are we root or gid == egid) 590 * If so, we are changing the real uid and saved gid. 591 */ 592 if ( --- 27 unchanged lines hidden (view full) --- 620 * Copy credentials so other references do not see our changes. 621 */ 622 if (oldcred->cr_groups[0] != gid) { 623 change_egid(newcred, gid); 624 setsugid(p); 625 } 626 p->p_ucred = newcred; 627 crfree(oldcred); | 686 687 newcred = crdup(oldcred); 688#ifdef _POSIX_SAVED_IDS 689 /* 690 * Do we have "appropriate privileges" (are we root or gid == egid) 691 * If so, we are changing the real uid and saved gid. 692 */ 693 if ( --- 27 unchanged lines hidden (view full) --- 721 * Copy credentials so other references do not see our changes. 722 */ 723 if (oldcred->cr_groups[0] != gid) { 724 change_egid(newcred, gid); 725 setsugid(p); 726 } 727 p->p_ucred = newcred; 728 crfree(oldcred); |
628 return (0); | 729done2: 730 mtx_unlock(&Giant); 731 return (error); |
629} 630 631#ifndef _SYS_SYSPROTO_H_ 632struct setegid_args { 633 gid_t egid; 634}; 635#endif | 732} 733 734#ifndef _SYS_SYSPROTO_H_ 735struct setegid_args { 736 gid_t egid; 737}; 738#endif |
739/* 740 * MPSAFE 741 */ |
|
636/* ARGSUSED */ 637int 638setegid(p, uap) 639 struct proc *p; 640 struct setegid_args *uap; 641{ 642 struct ucred *newcred, *oldcred; 643 gid_t egid; | 742/* ARGSUSED */ 743int 744setegid(p, uap) 745 struct proc *p; 746 struct setegid_args *uap; 747{ 748 struct ucred *newcred, *oldcred; 749 gid_t egid; |
644 int error; | 750 int error = 0; |
645 646 egid = uap->egid; | 751 752 egid = uap->egid; |
753 754 mtx_lock(&Giant); |
|
647 oldcred = p->p_ucred; 648 if (egid != oldcred->cr_rgid && /* allow setegid(getgid()) */ 649 egid != oldcred->cr_svgid && /* allow setegid(saved gid) */ | 755 oldcred = p->p_ucred; 756 if (egid != oldcred->cr_rgid && /* allow setegid(getgid()) */ 757 egid != oldcred->cr_svgid && /* allow setegid(saved gid) */ |
650 (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) 651 return (error); | 758 (error = suser_xxx(oldcred, NULL, PRISON_ROOT))) { 759 goto done2; 760 } |
652 newcred = crdup(oldcred); 653 if (oldcred->cr_groups[0] != egid) { 654 change_egid(newcred, egid); 655 setsugid(p); 656 } 657 p->p_ucred = newcred; 658 crfree(oldcred); | 761 newcred = crdup(oldcred); 762 if (oldcred->cr_groups[0] != egid) { 763 change_egid(newcred, egid); 764 setsugid(p); 765 } 766 p->p_ucred = newcred; 767 crfree(oldcred); |
659 return (0); | 768done2: 769 mtx_unlock(&Giant); 770 return (error); |
660} 661 662#ifndef _SYS_SYSPROTO_H_ 663struct setgroups_args { 664 u_int gidsetsize; 665 gid_t *gidset; 666}; 667#endif | 771} 772 773#ifndef _SYS_SYSPROTO_H_ 774struct setgroups_args { 775 u_int gidsetsize; 776 gid_t *gidset; 777}; 778#endif |
779/* 780 * MPSAFE 781 */ |
|
668/* ARGSUSED */ 669int 670setgroups(p, uap) 671 struct proc *p; 672 struct setgroups_args *uap; 673{ 674 struct ucred *newcred, *oldcred; 675 u_int ngrp; 676 int error; 677 | 782/* ARGSUSED */ 783int 784setgroups(p, uap) 785 struct proc *p; 786 struct setgroups_args *uap; 787{ 788 struct ucred *newcred, *oldcred; 789 u_int ngrp; 790 int error; 791 |
792 mtx_lock(&Giant); 793 |
|
678 ngrp = uap->gidsetsize; 679 oldcred = p->p_ucred; 680 if ((error = suser_xxx(oldcred, NULL, PRISON_ROOT))) | 794 ngrp = uap->gidsetsize; 795 oldcred = p->p_ucred; 796 if ((error = suser_xxx(oldcred, NULL, PRISON_ROOT))) |
681 return (error); 682 if (ngrp > NGROUPS) 683 return (EINVAL); | 797 goto done2; 798 if (ngrp > NGROUPS) { 799 error = EINVAL; 800 goto done2; 801 } |
684 /* 685 * XXX A little bit lazy here. We could test if anything has 686 * changed before crcopy() and setting P_SUGID. 687 */ 688 newcred = crdup(oldcred); 689 if (ngrp < 1) { 690 /* 691 * setgroups(0, NULL) is a legitimate way of clearing the 692 * groups vector on non-BSD systems (which generally do not 693 * have the egid in the groups[0]). We risk security holes 694 * when running non-BSD software if we do not do the same. 695 */ 696 newcred->cr_ngroups = 1; 697 } else { 698 if ((error = copyin((caddr_t)uap->gidset, 699 (caddr_t)newcred->cr_groups, ngrp * sizeof(gid_t)))) { 700 crfree(newcred); | 802 /* 803 * XXX A little bit lazy here. We could test if anything has 804 * changed before crcopy() and setting P_SUGID. 805 */ 806 newcred = crdup(oldcred); 807 if (ngrp < 1) { 808 /* 809 * setgroups(0, NULL) is a legitimate way of clearing the 810 * groups vector on non-BSD systems (which generally do not 811 * have the egid in the groups[0]). We risk security holes 812 * when running non-BSD software if we do not do the same. 813 */ 814 newcred->cr_ngroups = 1; 815 } else { 816 if ((error = copyin((caddr_t)uap->gidset, 817 (caddr_t)newcred->cr_groups, ngrp * sizeof(gid_t)))) { 818 crfree(newcred); |
701 return (error); | 819 goto done2; |
702 } 703 newcred->cr_ngroups = ngrp; 704 } 705 setsugid(p); 706 p->p_ucred = newcred; 707 crfree(oldcred); | 820 } 821 newcred->cr_ngroups = ngrp; 822 } 823 setsugid(p); 824 p->p_ucred = newcred; 825 crfree(oldcred); |
708 return (0); | 826done2: 827 mtx_unlock(&Giant); 828 return (error); |
709} 710 711#ifndef _SYS_SYSPROTO_H_ 712struct setreuid_args { 713 uid_t ruid; 714 uid_t euid; 715}; 716#endif | 829} 830 831#ifndef _SYS_SYSPROTO_H_ 832struct setreuid_args { 833 uid_t ruid; 834 uid_t euid; 835}; 836#endif |
837/* 838 * MPSAFE 839 */ |
|
717/* ARGSUSED */ 718int 719setreuid(p, uap) 720 register struct proc *p; 721 struct setreuid_args *uap; 722{ 723 struct ucred *newcred, *oldcred; 724 uid_t ruid, euid; | 840/* ARGSUSED */ 841int 842setreuid(p, uap) 843 register struct proc *p; 844 struct setreuid_args *uap; 845{ 846 struct ucred *newcred, *oldcred; 847 uid_t ruid, euid; |
725 int error; | 848 int error = 0; |
726 727 ruid = uap->ruid; 728 euid = uap->euid; | 849 850 ruid = uap->ruid; 851 euid = uap->euid; |
852 853 mtx_lock(&Giant); 854 |
|
729 oldcred = p->p_ucred; 730 if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && 731 ruid != oldcred->cr_svuid) || 732 (euid != (uid_t)-1 && euid != oldcred->cr_uid && 733 euid != oldcred->cr_ruid && euid != oldcred->cr_svuid)) && | 855 oldcred = p->p_ucred; 856 if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && 857 ruid != oldcred->cr_svuid) || 858 (euid != (uid_t)-1 && euid != oldcred->cr_uid && 859 euid != oldcred->cr_ruid && euid != oldcred->cr_svuid)) && |
734 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 735 return (error); | 860 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) { 861 goto done2; 862 } |
736 newcred = crdup(oldcred); 737 if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { 738 change_euid(newcred, euid); 739 setsugid(p); 740 } 741 if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { 742 change_ruid(newcred, ruid); 743 setsugid(p); 744 } 745 if ((ruid != (uid_t)-1 || newcred->cr_uid != newcred->cr_ruid) && 746 newcred->cr_svuid != newcred->cr_uid) { 747 change_svuid(newcred, newcred->cr_uid); 748 setsugid(p); 749 } 750 p->p_ucred = newcred; 751 crfree(oldcred); | 863 newcred = crdup(oldcred); 864 if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { 865 change_euid(newcred, euid); 866 setsugid(p); 867 } 868 if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { 869 change_ruid(newcred, ruid); 870 setsugid(p); 871 } 872 if ((ruid != (uid_t)-1 || newcred->cr_uid != newcred->cr_ruid) && 873 newcred->cr_svuid != newcred->cr_uid) { 874 change_svuid(newcred, newcred->cr_uid); 875 setsugid(p); 876 } 877 p->p_ucred = newcred; 878 crfree(oldcred); |
752 return (0); | 879done2: 880 mtx_unlock(&Giant); 881 return (error); |
753} 754 755#ifndef _SYS_SYSPROTO_H_ 756struct setregid_args { 757 gid_t rgid; 758 gid_t egid; 759}; 760#endif | 882} 883 884#ifndef _SYS_SYSPROTO_H_ 885struct setregid_args { 886 gid_t rgid; 887 gid_t egid; 888}; 889#endif |
890/* 891 * MPSAFE 892 */ |
|
761/* ARGSUSED */ 762int 763setregid(p, uap) 764 register struct proc *p; 765 struct setregid_args *uap; 766{ 767 struct ucred *newcred, *oldcred; 768 gid_t rgid, egid; | 893/* ARGSUSED */ 894int 895setregid(p, uap) 896 register struct proc *p; 897 struct setregid_args *uap; 898{ 899 struct ucred *newcred, *oldcred; 900 gid_t rgid, egid; |
769 int error; | 901 int error = 0; |
770 771 rgid = uap->rgid; 772 egid = uap->egid; | 902 903 rgid = uap->rgid; 904 egid = uap->egid; |
905 906 mtx_lock(&Giant); 907 |
|
773 oldcred = p->p_ucred; 774 if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && 775 rgid != oldcred->cr_svgid) || 776 (egid != (gid_t)-1 && egid != oldcred->cr_groups[0] && 777 egid != oldcred->cr_rgid && egid != oldcred->cr_svgid)) && | 908 oldcred = p->p_ucred; 909 if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && 910 rgid != oldcred->cr_svgid) || 911 (egid != (gid_t)-1 && egid != oldcred->cr_groups[0] && 912 egid != oldcred->cr_rgid && egid != oldcred->cr_svgid)) && |
778 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 779 return (error); | 913 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) { 914 goto done2; 915 } |
780 781 newcred = crdup(oldcred); 782 if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { 783 change_egid(newcred, egid); 784 setsugid(p); 785 } 786 if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { 787 change_rgid(newcred, rgid); 788 setsugid(p); 789 } 790 if ((rgid != (gid_t)-1 || newcred->cr_groups[0] != newcred->cr_rgid) && 791 newcred->cr_svgid != newcred->cr_groups[0]) { 792 change_svgid(newcred, newcred->cr_groups[0]); 793 setsugid(p); 794 } 795 p->p_ucred = newcred; 796 crfree(oldcred); | 916 917 newcred = crdup(oldcred); 918 if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { 919 change_egid(newcred, egid); 920 setsugid(p); 921 } 922 if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { 923 change_rgid(newcred, rgid); 924 setsugid(p); 925 } 926 if ((rgid != (gid_t)-1 || newcred->cr_groups[0] != newcred->cr_rgid) && 927 newcred->cr_svgid != newcred->cr_groups[0]) { 928 change_svgid(newcred, newcred->cr_groups[0]); 929 setsugid(p); 930 } 931 p->p_ucred = newcred; 932 crfree(oldcred); |
797 return (0); | 933done2: 934 mtx_unlock(&Giant); 935 return (error); |
798} 799 800/* 801 * setresuid(ruid, euid, suid) is like setreuid except control over the 802 * saved uid is explicit. 803 */ 804 805#ifndef _SYS_SYSPROTO_H_ 806struct setresuid_args { 807 uid_t ruid; 808 uid_t euid; 809 uid_t suid; 810}; 811#endif | 936} 937 938/* 939 * setresuid(ruid, euid, suid) is like setreuid except control over the 940 * saved uid is explicit. 941 */ 942 943#ifndef _SYS_SYSPROTO_H_ 944struct setresuid_args { 945 uid_t ruid; 946 uid_t euid; 947 uid_t suid; 948}; 949#endif |
950/* 951 * MPSAFE 952 */ |
|
812/* ARGSUSED */ 813int 814setresuid(p, uap) 815 register struct proc *p; 816 struct setresuid_args *uap; 817{ 818 struct ucred *newcred, *oldcred; 819 uid_t ruid, euid, suid; 820 int error; 821 822 ruid = uap->ruid; 823 euid = uap->euid; 824 suid = uap->suid; | 953/* ARGSUSED */ 954int 955setresuid(p, uap) 956 register struct proc *p; 957 struct setresuid_args *uap; 958{ 959 struct ucred *newcred, *oldcred; 960 uid_t ruid, euid, suid; 961 int error; 962 963 ruid = uap->ruid; 964 euid = uap->euid; 965 suid = uap->suid; |
966 967 mtx_lock(&Giant); |
|
825 oldcred = p->p_ucred; 826 if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && 827 ruid != oldcred->cr_svuid && 828 ruid != oldcred->cr_uid) || 829 (euid != (uid_t)-1 && euid != oldcred->cr_ruid && 830 euid != oldcred->cr_svuid && 831 euid != oldcred->cr_uid) || 832 (suid != (uid_t)-1 && suid != oldcred->cr_ruid && 833 suid != oldcred->cr_svuid && 834 suid != oldcred->cr_uid)) && | 968 oldcred = p->p_ucred; 969 if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && 970 ruid != oldcred->cr_svuid && 971 ruid != oldcred->cr_uid) || 972 (euid != (uid_t)-1 && euid != oldcred->cr_ruid && 973 euid != oldcred->cr_svuid && 974 euid != oldcred->cr_uid) || 975 (suid != (uid_t)-1 && suid != oldcred->cr_ruid && 976 suid != oldcred->cr_svuid && 977 suid != oldcred->cr_uid)) && |
835 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 836 return (error); | 978 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) { 979 goto done2; 980 } |
837 838 newcred = crdup(oldcred); 839 if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { 840 change_euid(newcred, euid); 841 setsugid(p); 842 } 843 if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { 844 change_ruid(newcred, ruid); 845 setsugid(p); 846 } 847 if (suid != (uid_t)-1 && oldcred->cr_svuid != suid) { 848 change_svuid(newcred, suid); 849 setsugid(p); 850 } 851 p->p_ucred = newcred; 852 crfree(oldcred); | 981 982 newcred = crdup(oldcred); 983 if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { 984 change_euid(newcred, euid); 985 setsugid(p); 986 } 987 if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { 988 change_ruid(newcred, ruid); 989 setsugid(p); 990 } 991 if (suid != (uid_t)-1 && oldcred->cr_svuid != suid) { 992 change_svuid(newcred, suid); 993 setsugid(p); 994 } 995 p->p_ucred = newcred; 996 crfree(oldcred); |
853 return (0); | 997 error = 0; 998done2: 999 mtx_unlock(&Giant); 1000 return (error); |
854} 855 856/* 857 * setresgid(rgid, egid, sgid) is like setregid except control over the 858 * saved gid is explicit. 859 */ 860 861#ifndef _SYS_SYSPROTO_H_ 862struct setresgid_args { 863 gid_t rgid; 864 gid_t egid; 865 gid_t sgid; 866}; 867#endif | 1001} 1002 1003/* 1004 * setresgid(rgid, egid, sgid) is like setregid except control over the 1005 * saved gid is explicit. 1006 */ 1007 1008#ifndef _SYS_SYSPROTO_H_ 1009struct setresgid_args { 1010 gid_t rgid; 1011 gid_t egid; 1012 gid_t sgid; 1013}; 1014#endif |
1015/* 1016 * MPSAFE 1017 */ |
|
868/* ARGSUSED */ 869int 870setresgid(p, uap) 871 register struct proc *p; 872 struct setresgid_args *uap; 873{ 874 struct ucred *newcred, *oldcred; 875 gid_t rgid, egid, sgid; 876 int error; 877 878 rgid = uap->rgid; 879 egid = uap->egid; 880 sgid = uap->sgid; | 1018/* ARGSUSED */ 1019int 1020setresgid(p, uap) 1021 register struct proc *p; 1022 struct setresgid_args *uap; 1023{ 1024 struct ucred *newcred, *oldcred; 1025 gid_t rgid, egid, sgid; 1026 int error; 1027 1028 rgid = uap->rgid; 1029 egid = uap->egid; 1030 sgid = uap->sgid; |
1031 1032 mtx_lock(&Giant); |
|
881 oldcred = p->p_ucred; 882 if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && 883 rgid != oldcred->cr_svgid && 884 rgid != oldcred->cr_groups[0]) || 885 (egid != (gid_t)-1 && egid != oldcred->cr_rgid && 886 egid != oldcred->cr_svgid && 887 egid != oldcred->cr_groups[0]) || 888 (sgid != (gid_t)-1 && sgid != oldcred->cr_rgid && 889 sgid != oldcred->cr_svgid && 890 sgid != oldcred->cr_groups[0])) && | 1033 oldcred = p->p_ucred; 1034 if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && 1035 rgid != oldcred->cr_svgid && 1036 rgid != oldcred->cr_groups[0]) || 1037 (egid != (gid_t)-1 && egid != oldcred->cr_rgid && 1038 egid != oldcred->cr_svgid && 1039 egid != oldcred->cr_groups[0]) || 1040 (sgid != (gid_t)-1 && sgid != oldcred->cr_rgid && 1041 sgid != oldcred->cr_svgid && 1042 sgid != oldcred->cr_groups[0])) && |
891 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 892 return (error); 893 | 1043 (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) { 1044 goto done2; 1045 } |
894 newcred = crdup(oldcred); 895 if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { 896 change_egid(newcred, egid); 897 setsugid(p); 898 } 899 if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { 900 change_rgid(newcred, rgid); 901 setsugid(p); 902 } 903 if (sgid != (gid_t)-1 && oldcred->cr_svgid != sgid) { 904 change_svgid(newcred, sgid); 905 setsugid(p); 906 } 907 p->p_ucred = newcred; 908 crfree(oldcred); | 1046 newcred = crdup(oldcred); 1047 if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { 1048 change_egid(newcred, egid); 1049 setsugid(p); 1050 } 1051 if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { 1052 change_rgid(newcred, rgid); 1053 setsugid(p); 1054 } 1055 if (sgid != (gid_t)-1 && oldcred->cr_svgid != sgid) { 1056 change_svgid(newcred, sgid); 1057 setsugid(p); 1058 } 1059 p->p_ucred = newcred; 1060 crfree(oldcred); |
909 return (0); | 1061 error = 0; 1062done2: 1063 mtx_unlock(&Giant); 1064 return (error); |
910} 911 912#ifndef _SYS_SYSPROTO_H_ 913struct getresuid_args { 914 uid_t *ruid; 915 uid_t *euid; 916 uid_t *suid; 917}; 918#endif | 1065} 1066 1067#ifndef _SYS_SYSPROTO_H_ 1068struct getresuid_args { 1069 uid_t *ruid; 1070 uid_t *euid; 1071 uid_t *suid; 1072}; 1073#endif |
1074/* 1075 * MPSAFE 1076 */ |
|
919/* ARGSUSED */ 920int 921getresuid(p, uap) 922 register struct proc *p; 923 struct getresuid_args *uap; 924{ | 1077/* ARGSUSED */ 1078int 1079getresuid(p, uap) 1080 register struct proc *p; 1081 struct getresuid_args *uap; 1082{ |
925 struct ucred *cred = p->p_ucred; | 1083 struct ucred *cred; |
926 int error1 = 0, error2 = 0, error3 = 0; 927 | 1084 int error1 = 0, error2 = 0, error3 = 0; 1085 |
1086 mtx_lock(&Giant); 1087 cred = p->p_ucred; 1088 |
|
928 if (uap->ruid) 929 error1 = copyout((caddr_t)&cred->cr_ruid, 930 (caddr_t)uap->ruid, sizeof(cred->cr_ruid)); 931 if (uap->euid) 932 error2 = copyout((caddr_t)&cred->cr_uid, 933 (caddr_t)uap->euid, sizeof(cred->cr_uid)); 934 if (uap->suid) 935 error3 = copyout((caddr_t)&cred->cr_svuid, 936 (caddr_t)uap->suid, sizeof(cred->cr_svuid)); | 1089 if (uap->ruid) 1090 error1 = copyout((caddr_t)&cred->cr_ruid, 1091 (caddr_t)uap->ruid, sizeof(cred->cr_ruid)); 1092 if (uap->euid) 1093 error2 = copyout((caddr_t)&cred->cr_uid, 1094 (caddr_t)uap->euid, sizeof(cred->cr_uid)); 1095 if (uap->suid) 1096 error3 = copyout((caddr_t)&cred->cr_svuid, 1097 (caddr_t)uap->suid, sizeof(cred->cr_svuid)); |
1098 mtx_unlock(&Giant); |
|
937 return error1 ? error1 : (error2 ? error2 : error3); 938} 939 940#ifndef _SYS_SYSPROTO_H_ 941struct getresgid_args { 942 gid_t *rgid; 943 gid_t *egid; 944 gid_t *sgid; 945}; 946#endif | 1099 return error1 ? error1 : (error2 ? error2 : error3); 1100} 1101 1102#ifndef _SYS_SYSPROTO_H_ 1103struct getresgid_args { 1104 gid_t *rgid; 1105 gid_t *egid; 1106 gid_t *sgid; 1107}; 1108#endif |
1109/* 1110 * MPSAFE 1111 */ |
|
947/* ARGSUSED */ 948int 949getresgid(p, uap) 950 register struct proc *p; 951 struct getresgid_args *uap; 952{ | 1112/* ARGSUSED */ 1113int 1114getresgid(p, uap) 1115 register struct proc *p; 1116 struct getresgid_args *uap; 1117{ |
953 struct ucred *cred = p->p_ucred; | 1118 struct ucred *cred; |
954 int error1 = 0, error2 = 0, error3 = 0; 955 | 1119 int error1 = 0, error2 = 0, error3 = 0; 1120 |
1121 mtx_lock(&Giant); 1122 cred = p->p_ucred; 1123 |
|
956 if (uap->rgid) 957 error1 = copyout((caddr_t)&cred->cr_rgid, 958 (caddr_t)uap->rgid, sizeof(cred->cr_rgid)); 959 if (uap->egid) 960 error2 = copyout((caddr_t)&cred->cr_groups[0], 961 (caddr_t)uap->egid, sizeof(cred->cr_groups[0])); 962 if (uap->sgid) 963 error3 = copyout((caddr_t)&cred->cr_svgid, 964 (caddr_t)uap->sgid, sizeof(cred->cr_svgid)); | 1124 if (uap->rgid) 1125 error1 = copyout((caddr_t)&cred->cr_rgid, 1126 (caddr_t)uap->rgid, sizeof(cred->cr_rgid)); 1127 if (uap->egid) 1128 error2 = copyout((caddr_t)&cred->cr_groups[0], 1129 (caddr_t)uap->egid, sizeof(cred->cr_groups[0])); 1130 if (uap->sgid) 1131 error3 = copyout((caddr_t)&cred->cr_svgid, 1132 (caddr_t)uap->sgid, sizeof(cred->cr_svgid)); |
1133 mtx_unlock(&Giant); |
|
965 return error1 ? error1 : (error2 ? error2 : error3); 966} 967 968 969#ifndef _SYS_SYSPROTO_H_ 970struct issetugid_args { 971 int dummy; 972}; --- 11 unchanged lines hidden (view full) --- 984 * This is significant for procs that start as root and "become" 985 * a user without an exec - programs cannot know *everything* 986 * that libc *might* have put in their data segment. 987 */ 988 p->p_retval[0] = (p->p_flag & P_SUGID) ? 1 : 0; 989 return (0); 990} 991 | 1134 return error1 ? error1 : (error2 ? error2 : error3); 1135} 1136 1137 1138#ifndef _SYS_SYSPROTO_H_ 1139struct issetugid_args { 1140 int dummy; 1141}; --- 11 unchanged lines hidden (view full) --- 1153 * This is significant for procs that start as root and "become" 1154 * a user without an exec - programs cannot know *everything* 1155 * that libc *might* have put in their data segment. 1156 */ 1157 p->p_retval[0] = (p->p_flag & P_SUGID) ? 1 : 0; 1158 return (0); 1159} 1160 |
1161/* 1162 * MPSAFE 1163 */ |
|
992int 993__setugid(p, uap) 994 struct proc *p; 995 struct __setugid_args *uap; 996{ | 1164int 1165__setugid(p, uap) 1166 struct proc *p; 1167 struct __setugid_args *uap; 1168{ |
997 | |
998#ifdef REGRESSION | 1169#ifdef REGRESSION |
1170 int error = 0; 1171 1172 mtx_lock(&Giant); |
|
999 switch (uap->flag) { 1000 case 0: 1001 p->p_flag &= ~P_SUGID; | 1173 switch (uap->flag) { 1174 case 0: 1175 p->p_flag &= ~P_SUGID; |
1002 return (0); | 1176 break; |
1003 case 1: 1004 p->p_flag |= P_SUGID; | 1177 case 1: 1178 p->p_flag |= P_SUGID; |
1005 return (0); | 1179 break; |
1006 default: | 1180 default: |
1007 return (EINVAL); | 1181 error = EINVAL; 1182 break; |
1008 } | 1183 } |
1184 mtx_unlock(&Giant); 1185 return (error); |
|
1009#else /* !REGRESSION */ 1010 return (ENOSYS); 1011#endif /* !REGRESSION */ 1012} 1013 1014/* 1015 * Check if gid is a member of the group set. 1016 */ --- 362 unchanged lines hidden (view full) --- 1379 * Get login name, if available. 1380 */ 1381#ifndef _SYS_SYSPROTO_H_ 1382struct getlogin_args { 1383 char *namebuf; 1384 u_int namelen; 1385}; 1386#endif | 1186#else /* !REGRESSION */ 1187 return (ENOSYS); 1188#endif /* !REGRESSION */ 1189} 1190 1191/* 1192 * Check if gid is a member of the group set. 1193 */ --- 362 unchanged lines hidden (view full) --- 1556 * Get login name, if available. 1557 */ 1558#ifndef _SYS_SYSPROTO_H_ 1559struct getlogin_args { 1560 char *namebuf; 1561 u_int namelen; 1562}; 1563#endif |
1564/* 1565 * MPSAFE 1566 */ |
|
1387/* ARGSUSED */ 1388int 1389getlogin(p, uap) 1390 struct proc *p; 1391 struct getlogin_args *uap; 1392{ | 1567/* ARGSUSED */ 1568int 1569getlogin(p, uap) 1570 struct proc *p; 1571 struct getlogin_args *uap; 1572{ |
1573 int error; |
|
1393 | 1574 |
1575 mtx_lock(&Giant); |
|
1394 if (uap->namelen > MAXLOGNAME) 1395 uap->namelen = MAXLOGNAME; | 1576 if (uap->namelen > MAXLOGNAME) 1577 uap->namelen = MAXLOGNAME; |
1396 return (copyout((caddr_t) p->p_pgrp->pg_session->s_login, 1397 (caddr_t) uap->namebuf, uap->namelen)); | 1578 error = copyout((caddr_t) p->p_pgrp->pg_session->s_login, 1579 (caddr_t) uap->namebuf, uap->namelen); 1580 mtx_unlock(&Giant); 1581 return(error); |
1398} 1399 1400/* 1401 * Set login name. 1402 */ 1403#ifndef _SYS_SYSPROTO_H_ 1404struct setlogin_args { 1405 char *namebuf; 1406}; 1407#endif | 1582} 1583 1584/* 1585 * Set login name. 1586 */ 1587#ifndef _SYS_SYSPROTO_H_ 1588struct setlogin_args { 1589 char *namebuf; 1590}; 1591#endif |
1592/* 1593 * MPSAFE 1594 */ |
|
1408/* ARGSUSED */ 1409int 1410setlogin(p, uap) 1411 struct proc *p; 1412 struct setlogin_args *uap; 1413{ 1414 int error; 1415 char logintmp[MAXLOGNAME]; 1416 | 1595/* ARGSUSED */ 1596int 1597setlogin(p, uap) 1598 struct proc *p; 1599 struct setlogin_args *uap; 1600{ 1601 int error; 1602 char logintmp[MAXLOGNAME]; 1603 |
1604 mtx_lock(&Giant); |
|
1417 if ((error = suser_xxx(0, p, PRISON_ROOT))) | 1605 if ((error = suser_xxx(0, p, PRISON_ROOT))) |
1418 return (error); | 1606 goto done2; |
1419 error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp, 1420 sizeof(logintmp), (size_t *)0); | 1607 error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp, 1608 sizeof(logintmp), (size_t *)0); |
1421 if (error == ENAMETOOLONG) | 1609 if (error == ENAMETOOLONG) { |
1422 error = EINVAL; | 1610 error = EINVAL; |
1423 else if (!error) | 1611 } else if (!error) { |
1424 (void) memcpy(p->p_pgrp->pg_session->s_login, logintmp, 1425 sizeof(logintmp)); | 1612 (void) memcpy(p->p_pgrp->pg_session->s_login, logintmp, 1613 sizeof(logintmp)); |
1614 } 1615done2: 1616 mtx_unlock(&Giant); |
|
1426 return (error); 1427} 1428 1429void 1430setsugid(p) 1431 struct proc *p; 1432{ 1433 p->p_flag |= P_SUGID; --- 101 unchanged lines hidden --- | 1617 return (error); 1618} 1619 1620void 1621setsugid(p) 1622 struct proc *p; 1623{ 1624 p->p_flag |= P_SUGID; --- 101 unchanged lines hidden --- |