kern_prot.c (193511) | kern_prot.c (194498) |
---|---|
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 --- 28 unchanged lines hidden (view full) --- 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 --- 28 unchanged lines hidden (view full) --- 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 193511 2009-06-05 14:55:22Z rwatson $"); | 45__FBSDID("$FreeBSD: head/sys/kern/kern_prot.c 194498 2009-06-19 17:10:35Z brooks $"); |
46 47#include "opt_compat.h" 48#include "opt_inet.h" 49#include "opt_inet6.h" 50 51#include <sys/param.h> 52#include <sys/systm.h> 53#include <sys/acct.h> --- 23 unchanged lines hidden (view full) --- 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 | 46 47#include "opt_compat.h" 48#include "opt_inet.h" 49#include "opt_inet6.h" 50 51#include <sys/param.h> 52#include <sys/systm.h> 53#include <sys/acct.h> --- 23 unchanged lines hidden (view full) --- 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 |
85static void crextend(struct ucred *cr, int n); 86static void crsetgroups_locked(struct ucred *cr, int ngrp, 87 gid_t *groups); 88 89 |
|
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) --- 178 unchanged lines hidden (view full) --- 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{ | 90#ifndef _SYS_SYSPROTO_H_ 91struct getpid_args { 92 int dummy; 93}; 94#endif 95/* ARGSUSED */ 96int 97getpid(struct thread *td, struct getpid_args *uap) --- 178 unchanged lines hidden (view full) --- 276struct getgroups_args { 277 u_int gidsetsize; 278 gid_t *gidset; 279}; 280#endif 281int 282getgroups(struct thread *td, register struct getgroups_args *uap) 283{ |
279 gid_t groups[NGROUPS]; | 284 gid_t *groups; |
280 u_int ngrp; 281 int error; 282 283 ngrp = MIN(uap->gidsetsize, NGROUPS); | 285 u_int ngrp; 286 int error; 287 288 ngrp = MIN(uap->gidsetsize, NGROUPS); |
289 groups = malloc(ngrp * sizeof(*groups), M_TEMP, M_WAITOK); |
|
284 error = kern_getgroups(td, &ngrp, groups); 285 if (error) | 290 error = kern_getgroups(td, &ngrp, groups); 291 if (error) |
286 return (error); | 292 goto out; |
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; | 293 if (uap->gidsetsize > 0) 294 error = copyout(groups, uap->gidset, ngrp * sizeof(gid_t)); 295 if (error == 0) 296 td->td_retval[0] = ngrp; |
297out: 298 free(groups, M_TEMP); |
|
291 return (error); 292} 293 294int 295kern_getgroups(struct thread *td, u_int *ngrp, gid_t *groups) 296{ 297 struct ucred *cred; 298 --- 182 unchanged lines hidden (view full) --- 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); | 299 return (error); 300} 301 302int 303kern_getgroups(struct thread *td, u_int *ngrp, gid_t *groups) 304{ 305 struct ucred *cred; 306 --- 182 unchanged lines hidden (view full) --- 489 struct uidinfo *uip; 490 int error; 491 492 uid = uap->uid; 493 AUDIT_ARG(uid, uid); 494 newcred = crget(); 495 uip = uifind(uid); 496 PROC_LOCK(p); |
489 oldcred = p->p_ucred; | 497 /* 498 * Copy credentials so other references do not see our changes. 499 */ 500 oldcred = crcopysafe(p, newcred); |
490 491#ifdef MAC 492 error = mac_cred_check_setuid(oldcred, uid); 493 if (error) 494 goto fail; 495#endif 496 497 /* --- 18 unchanged lines hidden (view full) --- 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 | 501 502#ifdef MAC 503 error = mac_cred_check_setuid(oldcred, uid); 504 if (error) 505 goto fail; 506#endif 507 508 /* --- 18 unchanged lines hidden (view full) --- 527 uid != oldcred->cr_svuid && /* allow setuid(saved gid) */ 528#endif 529#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 530 uid != oldcred->cr_uid && /* allow setuid(geteuid()) */ 531#endif 532 (error = priv_check_cred(oldcred, PRIV_CRED_SETUID, 0)) != 0) 533 goto fail; 534 |
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 || --- 57 unchanged lines hidden (view full) --- 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); | 535#ifdef _POSIX_SAVED_IDS 536 /* 537 * Do we have "appropriate privileges" (are we root or uid == euid) 538 * If so, we are changing the real uid and/or saved uid. 539 */ 540 if ( 541#ifdef POSIX_APPENDIX_B_4_2_2 /* Use the clause from B.4.2.2 */ 542 uid == oldcred->cr_uid || --- 57 unchanged lines hidden (view full) --- 600 struct uidinfo *euip; 601 int error; 602 603 euid = uap->euid; 604 AUDIT_ARG(euid, euid); 605 newcred = crget(); 606 euip = uifind(euid); 607 PROC_LOCK(p); |
601 oldcred = p->p_ucred; | 608 /* 609 * Copy credentials so other references do not see our changes. 610 */ 611 oldcred = crcopysafe(p, newcred); |
602 603#ifdef MAC 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 /* | 612 613#ifdef MAC 614 error = mac_cred_check_seteuid(oldcred, euid); 615 if (error) 616 goto fail; 617#endif 618 619 if (euid != oldcred->cr_ruid && /* allow seteuid(getuid()) */ 620 euid != oldcred->cr_svuid && /* allow seteuid(saved uid) */ 621 (error = priv_check_cred(oldcred, PRIV_CRED_SETEUID, 0)) != 0) 622 goto fail; 623 624 /* |
615 * Everything's okay, do it. Copy credentials so other references do 616 * not see our changes. | 625 * Everything's okay, do it. |
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); --- 21 unchanged lines hidden (view full) --- 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); | 626 */ 627 crcopy(newcred, oldcred); 628 if (oldcred->cr_uid != euid) { 629 change_euid(newcred, euip); 630 setsugid(p); 631 } 632 p->p_ucred = newcred; 633 PROC_UNLOCK(p); --- 21 unchanged lines hidden (view full) --- 655 struct ucred *newcred, *oldcred; 656 gid_t gid; 657 int error; 658 659 gid = uap->gid; 660 AUDIT_ARG(gid, gid); 661 newcred = crget(); 662 PROC_LOCK(p); |
654 oldcred = p->p_ucred; | 663 oldcred = crcopysafe(p, newcred); |
655 656#ifdef MAC 657 error = mac_cred_check_setgid(oldcred, gid); 658 if (error) 659 goto fail; 660#endif 661 662 /* --- 12 unchanged lines hidden (view full) --- 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 | 664 665#ifdef MAC 666 error = mac_cred_check_setgid(oldcred, gid); 667 if (error) 668 goto fail; 669#endif 670 671 /* --- 12 unchanged lines hidden (view full) --- 684 gid != oldcred->cr_svgid && /* allow setgid(saved gid) */ 685#endif 686#ifdef POSIX_APPENDIX_B_4_2_2 /* Use BSD-compat clause from B.4.2.2 */ 687 gid != oldcred->cr_groups[0] && /* allow setgid(getegid()) */ 688#endif 689 (error = priv_check_cred(oldcred, PRIV_CRED_SETGID, 0)) != 0) 690 goto fail; 691 |
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] || --- 53 unchanged lines hidden (view full) --- 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); | 692#ifdef _POSIX_SAVED_IDS 693 /* 694 * Do we have "appropriate privileges" (are we root or gid == egid) 695 * If so, we are changing the real uid and saved gid. 696 */ 697 if ( 698#ifdef POSIX_APPENDIX_B_4_2_2 /* use the clause from B.4.2.2 */ 699 gid == oldcred->cr_groups[0] || --- 53 unchanged lines hidden (view full) --- 753 struct ucred *newcred, *oldcred; 754 gid_t egid; 755 int error; 756 757 egid = uap->egid; 758 AUDIT_ARG(egid, egid); 759 newcred = crget(); 760 PROC_LOCK(p); |
753 oldcred = p->p_ucred; | 761 oldcred = crcopysafe(p, newcred); |
754 755#ifdef MAC 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 | 762 763#ifdef MAC 764 error = mac_cred_check_setegid(oldcred, egid); 765 if (error) 766 goto fail; 767#endif 768 769 if (egid != oldcred->cr_rgid && /* allow setegid(getgid()) */ 770 egid != oldcred->cr_svgid && /* allow setegid(saved gid) */ 771 (error = priv_check_cred(oldcred, PRIV_CRED_SETEGID, 0)) != 0) 772 goto fail; 773 |
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); --- 9 unchanged lines hidden (view full) --- 784 u_int gidsetsize; 785 gid_t *gidset; 786}; 787#endif 788/* ARGSUSED */ 789int 790setgroups(struct thread *td, struct setgroups_args *uap) 791{ | 774 if (oldcred->cr_groups[0] != egid) { 775 change_egid(newcred, egid); 776 setsugid(p); 777 } 778 p->p_ucred = newcred; 779 PROC_UNLOCK(p); 780 crfree(oldcred); 781 return (0); --- 9 unchanged lines hidden (view full) --- 791 u_int gidsetsize; 792 gid_t *gidset; 793}; 794#endif 795/* ARGSUSED */ 796int 797setgroups(struct thread *td, struct setgroups_args *uap) 798{ |
792 gid_t groups[NGROUPS]; | 799 gid_t *groups = NULL; |
793 int error; 794 795 if (uap->gidsetsize > NGROUPS) 796 return (EINVAL); | 800 int error; 801 802 if (uap->gidsetsize > NGROUPS) 803 return (EINVAL); |
804 groups = malloc(uap->gidsetsize * sizeof(gid_t), M_TEMP, M_WAITOK); |
|
797 error = copyin(uap->gidset, groups, uap->gidsetsize * sizeof(gid_t)); 798 if (error) | 805 error = copyin(uap->gidset, groups, uap->gidsetsize * sizeof(gid_t)); 806 if (error) |
799 return (error); 800 return (kern_setgroups(td, uap->gidsetsize, groups)); | 807 goto out; 808 error = kern_setgroups(td, uap->gidsetsize, groups); 809out: 810 free(groups, M_TEMP); 811 return (error); |
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(); | 812} 813 814int 815kern_setgroups(struct thread *td, u_int ngrp, gid_t *groups) 816{ 817 struct proc *p = td->td_proc; 818 struct ucred *newcred, *oldcred; 819 int error; 820 821 if (ngrp > NGROUPS) 822 return (EINVAL); 823 AUDIT_ARG(groupset, groups, ngrp); 824 newcred = crget(); |
825 crextend(newcred, ngrp); |
|
814 PROC_LOCK(p); | 826 PROC_LOCK(p); |
815 oldcred = p->p_ucred; | 827 oldcred = crcopysafe(p, newcred); |
816 817#ifdef MAC 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 | 828 829#ifdef MAC 830 error = mac_cred_check_setgroups(oldcred, ngrp, groups); 831 if (error) 832 goto fail; 833#endif 834 835 error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, 0); 836 if (error) 837 goto fail; 838 |
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 { | 839 if (ngrp < 1) { 840 /* 841 * setgroups(0, NULL) is a legitimate way of clearing the 842 * groups vector on non-BSD systems (which generally do not 843 * have the egid in the groups[0]). We risk security holes 844 * when running non-BSD software if we do not do the same. 845 */ 846 newcred->cr_ngroups = 1; 847 } else { |
841 bcopy(groups, newcred->cr_groups, ngrp * sizeof(gid_t)); 842 newcred->cr_ngroups = ngrp; | 848 crsetgroups_locked(newcred, ngrp, groups); |
843 } 844 setsugid(p); 845 p->p_ucred = newcred; 846 PROC_UNLOCK(p); 847 crfree(oldcred); 848 return (0); 849 850fail: --- 21 unchanged lines hidden (view full) --- 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); | 849 } 850 setsugid(p); 851 p->p_ucred = newcred; 852 PROC_UNLOCK(p); 853 crfree(oldcred); 854 return (0); 855 856fail: --- 21 unchanged lines hidden (view full) --- 878 euid = uap->euid; 879 ruid = uap->ruid; 880 AUDIT_ARG(euid, euid); 881 AUDIT_ARG(ruid, ruid); 882 newcred = crget(); 883 euip = uifind(euid); 884 ruip = uifind(ruid); 885 PROC_LOCK(p); |
880 oldcred = p->p_ucred; | 886 oldcred = crcopysafe(p, newcred); |
881 882#ifdef MAC 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 | 887 888#ifdef MAC 889 error = mac_cred_check_setreuid(oldcred, ruid, euid); 890 if (error) 891 goto fail; 892#endif 893 894 if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && 895 ruid != oldcred->cr_svuid) || 896 (euid != (uid_t)-1 && euid != oldcred->cr_uid && 897 euid != oldcred->cr_ruid && euid != oldcred->cr_svuid)) && 898 (error = priv_check_cred(oldcred, PRIV_CRED_SETREUID, 0)) != 0) 899 goto fail; 900 |
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 } --- 33 unchanged lines hidden (view full) --- 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); | 901 if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { 902 change_euid(newcred, euip); 903 setsugid(p); 904 } 905 if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { 906 change_ruid(newcred, ruip); 907 setsugid(p); 908 } --- 33 unchanged lines hidden (view full) --- 942 int error; 943 944 egid = uap->egid; 945 rgid = uap->rgid; 946 AUDIT_ARG(egid, egid); 947 AUDIT_ARG(rgid, rgid); 948 newcred = crget(); 949 PROC_LOCK(p); |
945 oldcred = p->p_ucred; | 950 oldcred = crcopysafe(p, newcred); |
946 947#ifdef MAC 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 | 951 952#ifdef MAC 953 error = mac_cred_check_setregid(oldcred, rgid, egid); 954 if (error) 955 goto fail; 956#endif 957 958 if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && 959 rgid != oldcred->cr_svgid) || 960 (egid != (gid_t)-1 && egid != oldcred->cr_groups[0] && 961 egid != oldcred->cr_rgid && egid != oldcred->cr_svgid)) && 962 (error = priv_check_cred(oldcred, PRIV_CRED_SETREGID, 0)) != 0) 963 goto fail; 964 |
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 } --- 39 unchanged lines hidden (view full) --- 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); | 965 if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { 966 change_egid(newcred, egid); 967 setsugid(p); 968 } 969 if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { 970 change_rgid(newcred, rgid); 971 setsugid(p); 972 } --- 39 unchanged lines hidden (view full) --- 1012 suid = uap->suid; 1013 AUDIT_ARG(euid, euid); 1014 AUDIT_ARG(ruid, ruid); 1015 AUDIT_ARG(suid, suid); 1016 newcred = crget(); 1017 euip = uifind(euid); 1018 ruip = uifind(ruid); 1019 PROC_LOCK(p); |
1016 oldcred = p->p_ucred; | 1020 oldcred = crcopysafe(p, newcred); |
1017 1018#ifdef MAC 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 | 1021 1022#ifdef MAC 1023 error = mac_cred_check_setresuid(oldcred, ruid, euid, suid); 1024 if (error) 1025 goto fail; 1026#endif 1027 1028 if (((ruid != (uid_t)-1 && ruid != oldcred->cr_ruid && 1029 ruid != oldcred->cr_svuid && 1030 ruid != oldcred->cr_uid) || 1031 (euid != (uid_t)-1 && euid != oldcred->cr_ruid && 1032 euid != oldcred->cr_svuid && 1033 euid != oldcred->cr_uid) || 1034 (suid != (uid_t)-1 && suid != oldcred->cr_ruid && 1035 suid != oldcred->cr_svuid && 1036 suid != oldcred->cr_uid)) && 1037 (error = priv_check_cred(oldcred, PRIV_CRED_SETRESUID, 0)) != 0) 1038 goto fail; 1039 |
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 } --- 40 unchanged lines hidden (view full) --- 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); | 1040 if (euid != (uid_t)-1 && oldcred->cr_uid != euid) { 1041 change_euid(newcred, euip); 1042 setsugid(p); 1043 } 1044 if (ruid != (uid_t)-1 && oldcred->cr_ruid != ruid) { 1045 change_ruid(newcred, ruip); 1046 setsugid(p); 1047 } --- 40 unchanged lines hidden (view full) --- 1088 egid = uap->egid; 1089 rgid = uap->rgid; 1090 sgid = uap->sgid; 1091 AUDIT_ARG(egid, egid); 1092 AUDIT_ARG(rgid, rgid); 1093 AUDIT_ARG(sgid, sgid); 1094 newcred = crget(); 1095 PROC_LOCK(p); |
1093 oldcred = p->p_ucred; | 1096 oldcred = crcopysafe(p, newcred); |
1094 1095#ifdef MAC 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 | 1097 1098#ifdef MAC 1099 error = mac_cred_check_setresgid(oldcred, rgid, egid, sgid); 1100 if (error) 1101 goto fail; 1102#endif 1103 1104 if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid && 1105 rgid != oldcred->cr_svgid && 1106 rgid != oldcred->cr_groups[0]) || 1107 (egid != (gid_t)-1 && egid != oldcred->cr_rgid && 1108 egid != oldcred->cr_svgid && 1109 egid != oldcred->cr_groups[0]) || 1110 (sgid != (gid_t)-1 && sgid != oldcred->cr_rgid && 1111 sgid != oldcred->cr_svgid && 1112 sgid != oldcred->cr_groups[0])) && 1113 (error = priv_check_cred(oldcred, PRIV_CRED_SETRESGID, 0)) != 0) 1114 goto fail; 1115 |
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 } --- 653 unchanged lines hidden (view full) --- 1775 cr = malloc(sizeof(*cr), M_CRED, M_WAITOK | M_ZERO); 1776 refcount_init(&cr->cr_ref, 1); 1777#ifdef AUDIT 1778 audit_cred_init(cr); 1779#endif 1780#ifdef MAC 1781 mac_cred_init(cr); 1782#endif | 1116 if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) { 1117 change_egid(newcred, egid); 1118 setsugid(p); 1119 } 1120 if (rgid != (gid_t)-1 && oldcred->cr_rgid != rgid) { 1121 change_rgid(newcred, rgid); 1122 setsugid(p); 1123 } --- 653 unchanged lines hidden (view full) --- 1777 cr = malloc(sizeof(*cr), M_CRED, M_WAITOK | M_ZERO); 1778 refcount_init(&cr->cr_ref, 1); 1779#ifdef AUDIT 1780 audit_cred_init(cr); 1781#endif 1782#ifdef MAC 1783 mac_cred_init(cr); 1784#endif |
1785 crextend(cr, XU_NGROUPS); |
|
1783 return (cr); 1784} 1785 1786/* 1787 * Claim another reference to a ucred structure. 1788 */ 1789struct ucred * 1790crhold(struct ucred *cr) --- 33 unchanged lines hidden (view full) --- 1824 refcount_release(&cr->cr_vimage->vi_ucredrefc); 1825#endif 1826#ifdef AUDIT 1827 audit_cred_destroy(cr); 1828#endif 1829#ifdef MAC 1830 mac_cred_destroy(cr); 1831#endif | 1786 return (cr); 1787} 1788 1789/* 1790 * Claim another reference to a ucred structure. 1791 */ 1792struct ucred * 1793crhold(struct ucred *cr) --- 33 unchanged lines hidden (view full) --- 1827 refcount_release(&cr->cr_vimage->vi_ucredrefc); 1828#endif 1829#ifdef AUDIT 1830 audit_cred_destroy(cr); 1831#endif 1832#ifdef MAC 1833 mac_cred_destroy(cr); 1834#endif |
1835 free(cr->cr_groups, M_CRED); |
|
1832 free(cr, M_CRED); 1833 } 1834} 1835 1836/* 1837 * Check to see if this ucred is shared. 1838 */ 1839int --- 9 unchanged lines hidden (view full) --- 1849void 1850crcopy(struct ucred *dest, struct ucred *src) 1851{ 1852 1853 KASSERT(crshared(dest) == 0, ("crcopy of shared ucred")); 1854 bcopy(&src->cr_startcopy, &dest->cr_startcopy, 1855 (unsigned)((caddr_t)&src->cr_endcopy - 1856 (caddr_t)&src->cr_startcopy)); | 1836 free(cr, M_CRED); 1837 } 1838} 1839 1840/* 1841 * Check to see if this ucred is shared. 1842 */ 1843int --- 9 unchanged lines hidden (view full) --- 1853void 1854crcopy(struct ucred *dest, struct ucred *src) 1855{ 1856 1857 KASSERT(crshared(dest) == 0, ("crcopy of shared ucred")); 1858 bcopy(&src->cr_startcopy, &dest->cr_startcopy, 1859 (unsigned)((caddr_t)&src->cr_endcopy - 1860 (caddr_t)&src->cr_startcopy)); |
1861 crsetgroups(dest, src->cr_ngroups, src->cr_groups); |
|
1857 uihold(dest->cr_uidinfo); 1858 uihold(dest->cr_ruidinfo); 1859 prison_hold(dest->cr_prison); 1860#ifdef VIMAGE 1861 KASSERT(src->cr_vimage != NULL, ("cr_vimage == NULL")); 1862 refcount_acquire(&dest->cr_vimage->vi_ucredrefc); 1863#endif 1864#ifdef AUDIT --- 18 unchanged lines hidden (view full) --- 1883} 1884 1885/* 1886 * Fill in a struct xucred based on a struct ucred. 1887 */ 1888void 1889cru2x(struct ucred *cr, struct xucred *xcr) 1890{ | 1862 uihold(dest->cr_uidinfo); 1863 uihold(dest->cr_ruidinfo); 1864 prison_hold(dest->cr_prison); 1865#ifdef VIMAGE 1866 KASSERT(src->cr_vimage != NULL, ("cr_vimage == NULL")); 1867 refcount_acquire(&dest->cr_vimage->vi_ucredrefc); 1868#endif 1869#ifdef AUDIT --- 18 unchanged lines hidden (view full) --- 1888} 1889 1890/* 1891 * Fill in a struct xucred based on a struct ucred. 1892 */ 1893void 1894cru2x(struct ucred *cr, struct xucred *xcr) 1895{ |
1896 int ngroups; |
|
1891 1892 bzero(xcr, sizeof(*xcr)); 1893 xcr->cr_version = XUCRED_VERSION; 1894 xcr->cr_uid = cr->cr_uid; | 1897 1898 bzero(xcr, sizeof(*xcr)); 1899 xcr->cr_version = XUCRED_VERSION; 1900 xcr->cr_uid = cr->cr_uid; |
1895 xcr->cr_ngroups = cr->cr_ngroups; 1896 bcopy(cr->cr_groups, xcr->cr_groups, sizeof(cr->cr_groups)); | 1901 1902 ngroups = MIN(cr->cr_ngroups, XU_NGROUPS); 1903 xcr->cr_ngroups = ngroups; 1904 bcopy(cr->cr_groups, xcr->cr_groups, 1905 ngroups * sizeof(*cr->cr_groups)); |
1897} 1898 1899/* 1900 * small routine to swap a thread's current ucred for the correct one taken 1901 * from the process. 1902 */ 1903void 1904cred_update_thread(struct thread *td) --- 5 unchanged lines hidden (view full) --- 1910 cred = td->td_ucred; 1911 PROC_LOCK(p); 1912 td->td_ucred = crhold(p->p_ucred); 1913 PROC_UNLOCK(p); 1914 if (cred != NULL) 1915 crfree(cred); 1916} 1917 | 1906} 1907 1908/* 1909 * small routine to swap a thread's current ucred for the correct one taken 1910 * from the process. 1911 */ 1912void 1913cred_update_thread(struct thread *td) --- 5 unchanged lines hidden (view full) --- 1919 cred = td->td_ucred; 1920 PROC_LOCK(p); 1921 td->td_ucred = crhold(p->p_ucred); 1922 PROC_UNLOCK(p); 1923 if (cred != NULL) 1924 crfree(cred); 1925} 1926 |
1927struct ucred * 1928crcopysafe(struct proc *p, struct ucred *cr) 1929{ 1930 struct ucred *oldcred; 1931 int groups; 1932 1933 PROC_LOCK_ASSERT(p, MA_OWNED); 1934 1935 oldcred = p->p_ucred; 1936 while (cr->cr_agroups < oldcred->cr_agroups) { 1937 groups = oldcred->cr_agroups; 1938 PROC_UNLOCK(p); 1939 crextend(cr, groups); 1940 PROC_LOCK(p); 1941 oldcred = p->p_ucred; 1942 } 1943 crcopy(cr, oldcred); 1944 1945 return (oldcred); 1946} 1947 |
|
1918/* | 1948/* |
1949 * Extend the passed in credential to hold n items. 1950 */ 1951static void 1952crextend(struct ucred *cr, int n) 1953{ 1954 int cnt; 1955 1956 /* Truncate? */ 1957 if (n <= cr->cr_agroups) 1958 return; 1959 1960 /* 1961 * We extend by 2 each time since we're using a power of two 1962 * allocator until we need enough groups to fill a page. 1963 * Once we're allocating multiple pages, only allocate as many 1964 * as we actually need. The case of processes needing a 1965 * non-power of two number of pages seems more likely than 1966 * a real world process that adds thousands of groups one at a 1967 * time. 1968 */ 1969 if ( n < PAGE_SIZE / sizeof(gid_t) ) { 1970 if (cr->cr_agroups == 0) 1971 cnt = MINALLOCSIZE / sizeof(gid_t); 1972 else 1973 cnt = cr->cr_agroups * 2; 1974 1975 while (cnt < n) 1976 cnt *= 2; 1977 } else 1978 cnt = roundup2(n, PAGE_SIZE / sizeof(gid_t)); 1979 1980 /* Free the old array. */ 1981 if (cr->cr_groups) 1982 free(cr->cr_groups, M_CRED); 1983 1984 cr->cr_groups = malloc(cnt * sizeof(gid_t), M_CRED, M_WAITOK | M_ZERO); 1985 cr->cr_agroups = cnt; 1986} 1987 1988/* 1989 * Copy groups in to a credential, preserving any necessicary invariants 1990 * (i.e. sorting in the future). crextend() must have been called 1991 * before hand to ensure sufficient space is available. If 1992 */ 1993static void 1994crsetgroups_locked(struct ucred *cr, int ngrp, gid_t *groups) 1995{ 1996 1997 KASSERT(cr->cr_agroups >= ngrp, ("cr_ngroups is too small")); 1998 1999 bcopy(groups, cr->cr_groups, ngrp * sizeof(gid_t)); 2000 cr->cr_ngroups = ngrp; 2001} 2002 2003/* 2004 * Copy groups in to a credential after expanding it if required. 2005 * Truncate the list to NGROUPS if it is too large. 2006 */ 2007void 2008crsetgroups(struct ucred *cr, int ngrp, gid_t *groups) 2009{ 2010 2011 if (ngrp > NGROUPS) 2012 ngrp = NGROUPS; 2013 2014 crextend(cr, ngrp); 2015 crsetgroups_locked(cr, ngrp, groups); 2016} 2017 2018/* |
|
1919 * Get login name, if available. 1920 */ 1921#ifndef _SYS_SYSPROTO_H_ 1922struct getlogin_args { 1923 char *namebuf; 1924 u_int namelen; 1925}; 1926#endif --- 149 unchanged lines hidden --- | 2019 * Get login name, if available. 2020 */ 2021#ifndef _SYS_SYSPROTO_H_ 2022struct getlogin_args { 2023 char *namebuf; 2024 u_int namelen; 2025}; 2026#endif --- 149 unchanged lines hidden --- |