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