This source file includes following definitions.
- sys_getpid
- sys_getthrid
- sys_getppid
- sys_getpgrp
- sys_getpgid
- sys_getsid
- sys_getuid
- sys_geteuid
- sys_issetugid
- sys_getgid
- sys_getegid
- sys_getgroups
- sys_setsid
- sys_setpgid
- sys_getresuid
- sys_setresuid
- sys_getresgid
- sys_setresgid
- sys_setregid
- sys_setreuid
- sys_setuid
- sys_seteuid
- sys_setgid
- sys_setegid
- sys_setgroups
- groupmember
- suser
- suser_ucred
- crget
- crfree
- crcopy
- crdup
- sys_getlogin
- sys_setlogin
- proc_cansugid
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 #include <sys/param.h>
45 #include <sys/acct.h>
46 #include <sys/systm.h>
47 #include <sys/ucred.h>
48 #include <sys/proc.h>
49 #include <sys/timeb.h>
50 #include <sys/times.h>
51 #include <sys/malloc.h>
52 #include <sys/filedesc.h>
53 #include <sys/pool.h>
54
55 #include <sys/mount.h>
56 #include <sys/syscallargs.h>
57
58
59 int
60 sys_getpid(struct proc *p, void *v, register_t *retval)
61 {
62
63 *retval = p->p_p->ps_mainproc->p_pid;
64 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) || defined(COMPAT_IBCS2) || \
65 defined(COMPAT_FREEBSD) || defined(COMPAT_BSDOS)
66 retval[1] = p->p_p->ps_mainproc->p_pptr->p_pid;
67 #endif
68 return (0);
69 }
70
71 #ifdef RTHREADS
72
73 int
74 sys_getthrid(p, v, retval)
75 struct proc *p;
76 void *v;
77 register_t *retval;
78 {
79
80 *retval = p->p_pid;
81 return (0);
82 }
83 #endif
84
85
86 int
87 sys_getppid(struct proc *p, void *v, register_t *retval)
88 {
89
90 *retval = p->p_p->ps_mainproc->p_pptr->p_pid;
91 return (0);
92 }
93
94
95 int
96 sys_getpgrp(struct proc *p, void *v, register_t *retval)
97 {
98
99 *retval = p->p_pgrp->pg_id;
100 return (0);
101 }
102
103
104
105
106 pid_t
107 sys_getpgid(struct proc *curp, void *v, register_t *retval)
108 {
109 struct sys_getpgid_args
110
111 *uap = v;
112 struct proc *targp = curp;
113
114 if (SCARG(uap, pid) == 0 || SCARG(uap, pid) == curp->p_pid)
115 goto found;
116 if ((targp = pfind(SCARG(uap, pid))) == NULL)
117 return (ESRCH);
118 if (targp->p_session != curp->p_session)
119 return (EPERM);
120 found:
121 *retval = targp->p_pgid;
122 return (0);
123 }
124
125 pid_t
126 sys_getsid(struct proc *curp, void *v, register_t *retval)
127 {
128 struct sys_getsid_args
129
130 *uap = v;
131 struct proc *targp = curp;
132
133 if (SCARG(uap, pid) == 0 || SCARG(uap, pid) == curp->p_pid)
134 goto found;
135 if ((targp = pfind(SCARG(uap, pid))) == NULL)
136 return (ESRCH);
137 if (targp->p_session != curp->p_session)
138 return (EPERM);
139 found:
140
141 if (targp->p_pgrp->pg_session->s_leader == NULL)
142 return (ESRCH);
143 *retval = targp->p_pgrp->pg_session->s_leader->p_pid;
144 return (0);
145 }
146
147
148 int
149 sys_getuid(struct proc *p, void *v, register_t *retval)
150 {
151
152 *retval = p->p_cred->p_ruid;
153 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) || defined(COMPAT_IBCS2) || \
154 defined(COMPAT_FREEBSD) || defined(COMPAT_BSDOS)
155 retval[1] = p->p_ucred->cr_uid;
156 #endif
157 return (0);
158 }
159
160
161 int
162 sys_geteuid(struct proc *p, void *v, register_t *retval)
163 {
164
165 *retval = p->p_ucred->cr_uid;
166 return (0);
167 }
168
169
170 int
171 sys_issetugid(struct proc *p, void *v, register_t *retval)
172 {
173 if (p->p_flag & P_SUGIDEXEC)
174 *retval = 1;
175 else
176 *retval = 0;
177 return (0);
178 }
179
180
181 int
182 sys_getgid(struct proc *p, void *v, register_t *retval)
183 {
184
185 *retval = p->p_cred->p_rgid;
186 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) || defined(COMPAT_FREEBSD) || defined(COMPAT_BSDOS)
187 retval[1] = p->p_ucred->cr_gid;
188 #endif
189 return (0);
190 }
191
192
193
194
195
196
197
198 int
199 sys_getegid(struct proc *p, void *v, register_t *retval)
200 {
201
202 *retval = p->p_ucred->cr_gid;
203 return (0);
204 }
205
206 int
207 sys_getgroups(struct proc *p, void *v, register_t *retval)
208 {
209 struct sys_getgroups_args
210
211
212 *uap = v;
213 struct pcred *pc = p->p_cred;
214 u_int ngrp;
215 int error;
216
217 if ((ngrp = SCARG(uap, gidsetsize)) == 0) {
218 *retval = pc->pc_ucred->cr_ngroups;
219 return (0);
220 }
221 if (ngrp < pc->pc_ucred->cr_ngroups)
222 return (EINVAL);
223 ngrp = pc->pc_ucred->cr_ngroups;
224 error = copyout((caddr_t)pc->pc_ucred->cr_groups,
225 (caddr_t)SCARG(uap, gidset), ngrp * sizeof(gid_t));
226 if (error)
227 return (error);
228 *retval = ngrp;
229 return (0);
230 }
231
232
233 int
234 sys_setsid(struct proc *p, void *v, register_t *retval)
235 {
236
237 if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) {
238 return (EPERM);
239 } else {
240 (void)enterpgrp(p, p->p_pid, 1);
241 *retval = p->p_pid;
242 return (0);
243 }
244 }
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260 int
261 sys_setpgid(struct proc *curp, void *v, register_t *retval)
262 {
263 struct sys_setpgid_args
264
265
266 *uap = v;
267 struct proc *targp;
268 struct pgrp *pgrp;
269 pid_t pid;
270 int pgid;
271
272 pid = SCARG(uap, pid);
273 pgid = SCARG(uap, pgid);
274
275 if (pgid < 0)
276 return (EINVAL);
277
278 if (pid != 0 && pid != curp->p_pid) {
279 if ((targp = pfind(pid)) == 0 || !inferior(targp))
280 return (ESRCH);
281 if (targp->p_session != curp->p_session)
282 return (EPERM);
283 if (targp->p_flag & P_EXEC)
284 return (EACCES);
285 } else
286 targp = curp;
287 if (SESS_LEADER(targp))
288 return (EPERM);
289 if (pgid == 0)
290 pgid = targp->p_pid;
291 else if (pgid != targp->p_pid)
292 if ((pgrp = pgfind(pgid)) == 0 ||
293 pgrp->pg_session != curp->p_session)
294 return (EPERM);
295 return (enterpgrp(targp, pgid, 0));
296 }
297
298
299 int
300 sys_getresuid(struct proc *p, void *v, register_t *retval)
301 {
302 struct sys_getresuid_args
303
304
305
306 *uap = v;
307 struct pcred *pc = p->p_cred;
308 uid_t *ruid, *euid, *suid;
309 int error1 = 0, error2 = 0, error3 = 0;
310
311 ruid = SCARG(uap, ruid);
312 euid = SCARG(uap, euid);
313 suid = SCARG(uap, suid);
314
315 if (ruid != NULL)
316 error1 = copyout(&pc->p_ruid, ruid, sizeof(*ruid));
317 if (euid != NULL)
318 error2 = copyout(&pc->pc_ucred->cr_uid, euid, sizeof(*euid));
319 if (suid != NULL)
320 error3 = copyout(&pc->p_svuid, suid, sizeof(*suid));
321
322 return (error1 ? error1 : error2 ? error2 : error3);
323 }
324
325
326 int
327 sys_setresuid(struct proc *p, void *v, register_t *retval)
328 {
329 struct sys_setresuid_args
330
331
332
333 *uap = v;
334 struct pcred *pc = p->p_cred;
335 uid_t ruid, euid, suid;
336 int error;
337
338 ruid = SCARG(uap, ruid);
339 euid = SCARG(uap, euid);
340 suid = SCARG(uap, suid);
341
342 if ((ruid == -1 || ruid == pc->p_ruid) &&
343 (euid == -1 || euid == pc->pc_ucred->cr_uid) &&
344 (suid == -1 || suid == pc->p_svuid))
345 return (0);
346
347
348
349
350
351 if (ruid != (uid_t)-1 &&
352 ruid != pc->p_ruid &&
353 ruid != pc->pc_ucred->cr_uid &&
354 ruid != pc->p_svuid &&
355 (error = suser(p, 0)))
356 return (error);
357
358 if (euid != (uid_t)-1 &&
359 euid != pc->p_ruid &&
360 euid != pc->pc_ucred->cr_uid &&
361 euid != pc->p_svuid &&
362 (error = suser(p, 0)))
363 return (error);
364
365 if (suid != (uid_t)-1 &&
366 suid != pc->p_ruid &&
367 suid != pc->pc_ucred->cr_uid &&
368 suid != pc->p_svuid &&
369 (error = suser(p, 0)))
370 return (error);
371
372
373
374
375
376 if (ruid != (uid_t)-1 && ruid != pc->p_ruid) {
377
378
379
380 (void)chgproccnt(pc->p_ruid, -1);
381 (void)chgproccnt(ruid, 1);
382 pc->p_ruid = ruid;
383 }
384 if (euid != (uid_t)-1 && euid != pc->pc_ucred->cr_uid) {
385
386
387
388 pc->pc_ucred = crcopy(pc->pc_ucred);
389 pc->pc_ucred->cr_uid = euid;
390 }
391 if (suid != (uid_t)-1 && suid != pc->p_svuid)
392 pc->p_svuid = suid;
393
394 atomic_setbits_int(&p->p_flag, P_SUGID);
395 return (0);
396 }
397
398
399 int
400 sys_getresgid(struct proc *p, void *v, register_t *retval)
401 {
402 struct sys_getresgid_args
403
404
405
406 *uap = v;
407 struct pcred *pc = p->p_cred;
408 gid_t *rgid, *egid, *sgid;
409 int error1 = 0, error2 = 0, error3 = 0;
410
411 rgid = SCARG(uap, rgid);
412 egid = SCARG(uap, egid);
413 sgid = SCARG(uap, sgid);
414
415 if (rgid != NULL)
416 error1 = copyout(&pc->p_rgid, rgid, sizeof(*rgid));
417 if (egid != NULL)
418 error2 = copyout(&pc->pc_ucred->cr_gid, egid, sizeof(*egid));
419 if (sgid != NULL)
420 error3 = copyout(&pc->p_svgid, sgid, sizeof(*sgid));
421
422 return (error1 ? error1 : error2 ? error2 : error3);
423 }
424
425
426 int
427 sys_setresgid(struct proc *p, void *v, register_t *retval)
428 {
429 struct sys_setresgid_args
430
431
432
433 *uap = v;
434 struct pcred *pc = p->p_cred;
435 gid_t rgid, egid, sgid;
436 int error;
437
438 rgid = SCARG(uap, rgid);
439 egid = SCARG(uap, egid);
440 sgid = SCARG(uap, sgid);
441
442 if ((rgid == -1 || rgid == pc->p_rgid) &&
443 (egid == -1 || egid == pc->pc_ucred->cr_gid) &&
444 (sgid == -1 || sgid == pc->p_svgid))
445 return (0);
446
447
448
449
450
451 if (rgid != (gid_t)-1 &&
452 rgid != pc->p_rgid &&
453 rgid != pc->pc_ucred->cr_gid &&
454 rgid != pc->p_svgid &&
455 (error = suser(p, 0)))
456 return (error);
457
458 if (egid != (gid_t)-1 &&
459 egid != pc->p_rgid &&
460 egid != pc->pc_ucred->cr_gid &&
461 egid != pc->p_svgid &&
462 (error = suser(p, 0)))
463 return (error);
464
465 if (sgid != (gid_t)-1 &&
466 sgid != pc->p_rgid &&
467 sgid != pc->pc_ucred->cr_gid &&
468 sgid != pc->p_svgid &&
469 (error = suser(p, 0)))
470 return (error);
471
472
473
474
475
476 if (rgid != (gid_t)-1)
477 pc->p_rgid = rgid;
478 if (egid != (gid_t)-1) {
479
480
481
482 pc->pc_ucred = crcopy(pc->pc_ucred);
483 pc->pc_ucred->cr_gid = egid;
484 }
485 if (sgid != (gid_t)-1)
486 pc->p_svgid = sgid;
487
488 atomic_setbits_int(&p->p_flag, P_SUGID);
489 return (0);
490 }
491
492
493 int
494 sys_setregid(struct proc *p, void *v, register_t *retval)
495 {
496 struct sys_setregid_args
497
498
499 *uap = v;
500 struct pcred *pc = p->p_cred;
501 struct sys_setresgid_args sresgidargs;
502 gid_t rgid, egid;
503
504 rgid = SCARG(&sresgidargs, rgid) = SCARG(uap, rgid);
505 egid = SCARG(&sresgidargs, egid) = SCARG(uap, egid);
506
507
508
509
510
511
512
513 if (rgid != (gid_t)-1 && (rgid != pc->p_rgid ||
514 pc->p_svgid != (egid != (gid_t)-1 ? egid : pc->pc_ucred->cr_gid)))
515 SCARG(&sresgidargs, sgid) = rgid;
516 else
517 SCARG(&sresgidargs, sgid) = (gid_t)-1;
518
519 return (sys_setresgid(p, &sresgidargs, retval));
520 }
521
522
523 int
524 sys_setreuid(struct proc *p, void *v, register_t *retval)
525 {
526 struct sys_setreuid_args
527
528
529 *uap = v;
530 struct pcred *pc = p->p_cred;
531 struct sys_setresuid_args sresuidargs;
532 uid_t ruid, euid;
533
534 ruid = SCARG(&sresuidargs, ruid) = SCARG(uap, ruid);
535 euid = SCARG(&sresuidargs, euid) = SCARG(uap, euid);
536
537
538
539
540
541
542
543 if (ruid != (uid_t)-1 && (ruid != pc->p_ruid ||
544 pc->p_svuid != (euid != (uid_t)-1 ? euid : pc->pc_ucred->cr_uid)))
545 SCARG(&sresuidargs, suid) = ruid;
546 else
547 SCARG(&sresuidargs, suid) = (uid_t)-1;
548
549 return (sys_setresuid(p, &sresuidargs, retval));
550 }
551
552
553 int
554 sys_setuid(struct proc *p, void *v, register_t *retval)
555 {
556 struct sys_setuid_args
557
558 *uap = v;
559 struct pcred *pc = p->p_cred;
560 uid_t uid;
561 int error;
562
563 uid = SCARG(uap, uid);
564
565 if (pc->pc_ucred->cr_uid == uid &&
566 pc->p_ruid == uid &&
567 pc->p_svuid == uid)
568 return (0);
569
570 if (uid != pc->p_ruid &&
571 uid != pc->p_svuid &&
572 uid != pc->pc_ucred->cr_uid &&
573 (error = suser(p, 0)))
574 return (error);
575
576
577
578
579 if (uid == pc->pc_ucred->cr_uid ||
580 suser(p, 0) == 0) {
581
582
583
584 if (uid != pc->p_ruid) {
585 (void)chgproccnt(pc->p_ruid, -1);
586 (void)chgproccnt(uid, 1);
587 }
588 pc->p_ruid = uid;
589 pc->p_svuid = uid;
590 }
591
592
593
594
595 pc->pc_ucred = crcopy(pc->pc_ucred);
596 pc->pc_ucred->cr_uid = uid;
597 atomic_setbits_int(&p->p_flag, P_SUGID);
598 return (0);
599 }
600
601
602 int
603 sys_seteuid(struct proc *p, void *v, register_t *retval)
604 {
605 struct sys_seteuid_args
606
607 *uap = v;
608 struct pcred *pc = p->p_cred;
609 uid_t euid;
610 int error;
611
612 euid = SCARG(uap, euid);
613
614 if (pc->pc_ucred->cr_uid == euid)
615 return (0);
616
617 if (euid != pc->p_ruid && euid != pc->p_svuid &&
618 (error = suser(p, 0)))
619 return (error);
620
621
622
623
624 pc->pc_ucred = crcopy(pc->pc_ucred);
625 pc->pc_ucred->cr_uid = euid;
626 atomic_setbits_int(&p->p_flag, P_SUGID);
627 return (0);
628 }
629
630
631 int
632 sys_setgid(struct proc *p, void *v, register_t *retval)
633 {
634 struct sys_setgid_args
635
636 *uap = v;
637 struct pcred *pc = p->p_cred;
638 gid_t gid;
639 int error;
640
641 gid = SCARG(uap, gid);
642
643 if (pc->pc_ucred->cr_gid == gid &&
644 pc->p_rgid == gid &&
645 pc->p_svgid == gid)
646 return (0);
647
648 if (gid != pc->p_rgid &&
649 gid != pc->p_svgid &&
650 gid != pc->pc_ucred->cr_gid &&
651 (error = suser(p, 0)))
652 return (error);
653
654 if (gid == pc->pc_ucred->cr_gid ||
655 suser(p, 0) == 0) {
656 pc->p_rgid = gid;
657 pc->p_svgid = gid;
658 }
659
660
661
662
663 pc->pc_ucred = crcopy(pc->pc_ucred);
664 pc->pc_ucred->cr_gid = gid;
665 atomic_setbits_int(&p->p_flag, P_SUGID);
666 return (0);
667 }
668
669
670 int
671 sys_setegid(struct proc *p, void *v, register_t *retval)
672 {
673 struct sys_setegid_args
674
675 *uap = v;
676 struct pcred *pc = p->p_cred;
677 gid_t egid;
678 int error;
679
680 egid = SCARG(uap, egid);
681
682 if (pc->pc_ucred->cr_gid == egid)
683 return (0);
684
685 if (egid != pc->p_rgid && egid != pc->p_svgid &&
686 (error = suser(p, 0)))
687 return (error);
688
689
690
691
692 pc->pc_ucred = crcopy(pc->pc_ucred);
693 pc->pc_ucred->cr_gid = egid;
694 atomic_setbits_int(&p->p_flag, P_SUGID);
695 return (0);
696 }
697
698
699 int
700 sys_setgroups(struct proc *p, void *v, register_t *retval)
701 {
702 struct sys_setgroups_args
703
704
705 *uap = v;
706 struct pcred *pc = p->p_cred;
707 u_int ngrp;
708 int error;
709
710 if ((error = suser(p, 0)) != 0)
711 return (error);
712 ngrp = SCARG(uap, gidsetsize);
713 if (ngrp > NGROUPS)
714 return (EINVAL);
715 pc->pc_ucred = crcopy(pc->pc_ucred);
716 error = copyin((caddr_t)SCARG(uap, gidset),
717 (caddr_t)pc->pc_ucred->cr_groups, ngrp * sizeof(gid_t));
718 if (error)
719 return (error);
720 pc->pc_ucred->cr_ngroups = ngrp;
721 atomic_setbits_int(&p->p_flag, P_SUGID);
722 return (0);
723 }
724
725
726
727
728 int
729 groupmember(gid_t gid, struct ucred *cred)
730 {
731 gid_t *gp;
732 gid_t *egp;
733
734 egp = &(cred->cr_groups[cred->cr_ngroups]);
735 for (gp = cred->cr_groups; gp < egp; gp++)
736 if (*gp == gid)
737 return (1);
738 return (0);
739 }
740
741
742
743
744
745 int
746 suser(struct proc *p, u_int flags)
747 {
748 struct ucred *cred = p->p_ucred;
749
750 if (cred->cr_uid == 0) {
751 if (!(flags & SUSER_NOACCT))
752 p->p_acflag |= ASU;
753 return (0);
754 }
755 return (EPERM);
756 }
757
758
759
760
761 int
762 suser_ucred(struct ucred *cred)
763 {
764 if (cred->cr_uid == 0)
765 return (0);
766 return (EPERM);
767 }
768
769
770
771
772 struct ucred *
773 crget(void)
774 {
775 struct ucred *cr;
776
777 cr = pool_get(&ucred_pool, PR_WAITOK);
778 bzero((caddr_t)cr, sizeof(*cr));
779 cr->cr_ref = 1;
780 return (cr);
781 }
782
783
784
785
786
787 void
788 crfree(struct ucred *cr)
789 {
790
791 if (--cr->cr_ref == 0)
792 pool_put(&ucred_pool, cr);
793 }
794
795
796
797
798 struct ucred *
799 crcopy(struct ucred *cr)
800 {
801 struct ucred *newcr;
802
803 if (cr->cr_ref == 1)
804 return (cr);
805 newcr = crget();
806 *newcr = *cr;
807 crfree(cr);
808 newcr->cr_ref = 1;
809 return (newcr);
810 }
811
812
813
814
815 struct ucred *
816 crdup(struct ucred *cr)
817 {
818 struct ucred *newcr;
819
820 newcr = crget();
821 *newcr = *cr;
822 newcr->cr_ref = 1;
823 return (newcr);
824 }
825
826
827
828
829
830 int
831 sys_getlogin(struct proc *p, void *v, register_t *retval)
832 {
833 struct sys_getlogin_args
834
835
836 *uap = v;
837
838 if (SCARG(uap, namelen) > sizeof (p->p_pgrp->pg_session->s_login))
839 SCARG(uap, namelen) = sizeof (p->p_pgrp->pg_session->s_login);
840 return (copyout((caddr_t) p->p_pgrp->pg_session->s_login,
841 (caddr_t) SCARG(uap, namebuf), SCARG(uap, namelen)));
842 }
843
844
845
846
847
848 int
849 sys_setlogin(struct proc *p, void *v, register_t *retval)
850 {
851 struct sys_setlogin_args
852
853 *uap = v;
854 int error;
855
856 if ((error = suser(p, 0)) != 0)
857 return (error);
858 error = copyinstr((caddr_t) SCARG(uap, namebuf),
859 (caddr_t) p->p_pgrp->pg_session->s_login,
860 sizeof (p->p_pgrp->pg_session->s_login), (size_t *)0);
861 if (error == ENAMETOOLONG)
862 error = EINVAL;
863 return (error);
864 }
865
866
867
868
869 int
870 proc_cansugid(struct proc *p)
871 {
872
873 if ((p->p_flag & P_TRACED) != 0)
874 return (0);
875
876
877 if (p->p_fd->fd_refcnt > 1)
878 return (0);
879
880
881 return (1);
882 }