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 ---