aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2012-02-07 21:51:01 -0500
committerEric W. Biederman <ebiederm@xmission.com>2012-05-03 06:28:41 -0400
commita29c33f4e506e1dae7e0985b6328046535becbf8 (patch)
tree529720b8aefaf115b4be197e5d7628657cf5b4bc /kernel/sys.c
parent18815a18085364d8514c0d0c4c986776cb74272c (diff)
userns: Convert setting and getting uid and gid system calls to use kuid and kgid
Convert setregid, setgid, setreuid, setuid, setresuid, getresuid, setresgid, getresgid, setfsuid, setfsgid, getuid, geteuid, getgid, getegid, waitpid, waitid, wait4. Convert userspace uids and gids into kuids and kgids before being placed on struct cred. Convert struct cred kuids and kgids into userspace uids and gids when returning them. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c216
1 files changed, 149 insertions, 67 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index 39962818c008..aff09f208eb3 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -555,9 +555,19 @@ void ctrl_alt_del(void)
555 */ 555 */
556SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid) 556SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
557{ 557{
558 struct user_namespace *ns = current_user_ns();
558 const struct cred *old; 559 const struct cred *old;
559 struct cred *new; 560 struct cred *new;
560 int retval; 561 int retval;
562 kgid_t krgid, kegid;
563
564 krgid = make_kgid(ns, rgid);
565 kegid = make_kgid(ns, egid);
566
567 if ((rgid != (gid_t) -1) && !gid_valid(krgid))
568 return -EINVAL;
569 if ((egid != (gid_t) -1) && !gid_valid(kegid))
570 return -EINVAL;
561 571
562 new = prepare_creds(); 572 new = prepare_creds();
563 if (!new) 573 if (!new)
@@ -566,25 +576,25 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
566 576
567 retval = -EPERM; 577 retval = -EPERM;
568 if (rgid != (gid_t) -1) { 578 if (rgid != (gid_t) -1) {
569 if (old->gid == rgid || 579 if (gid_eq(old->gid, krgid) ||
570 old->egid == rgid || 580 gid_eq(old->egid, krgid) ||
571 nsown_capable(CAP_SETGID)) 581 nsown_capable(CAP_SETGID))
572 new->gid = rgid; 582 new->gid = krgid;
573 else 583 else
574 goto error; 584 goto error;
575 } 585 }
576 if (egid != (gid_t) -1) { 586 if (egid != (gid_t) -1) {
577 if (old->gid == egid || 587 if (gid_eq(old->gid, kegid) ||
578 old->egid == egid || 588 gid_eq(old->egid, kegid) ||
579 old->sgid == egid || 589 gid_eq(old->sgid, kegid) ||
580 nsown_capable(CAP_SETGID)) 590 nsown_capable(CAP_SETGID))
581 new->egid = egid; 591 new->egid = kegid;
582 else 592 else
583 goto error; 593 goto error;
584 } 594 }
585 595
586 if (rgid != (gid_t) -1 || 596 if (rgid != (gid_t) -1 ||
587 (egid != (gid_t) -1 && egid != old->gid)) 597 (egid != (gid_t) -1 && !gid_eq(kegid, old->gid)))
588 new->sgid = new->egid; 598 new->sgid = new->egid;
589 new->fsgid = new->egid; 599 new->fsgid = new->egid;
590 600
@@ -602,9 +612,15 @@ error:
602 */ 612 */
603SYSCALL_DEFINE1(setgid, gid_t, gid) 613SYSCALL_DEFINE1(setgid, gid_t, gid)
604{ 614{
615 struct user_namespace *ns = current_user_ns();
605 const struct cred *old; 616 const struct cred *old;
606 struct cred *new; 617 struct cred *new;
607 int retval; 618 int retval;
619 kgid_t kgid;
620
621 kgid = make_kgid(ns, gid);
622 if (!gid_valid(kgid))
623 return -EINVAL;
608 624
609 new = prepare_creds(); 625 new = prepare_creds();
610 if (!new) 626 if (!new)
@@ -613,9 +629,9 @@ SYSCALL_DEFINE1(setgid, gid_t, gid)
613 629
614 retval = -EPERM; 630 retval = -EPERM;
615 if (nsown_capable(CAP_SETGID)) 631 if (nsown_capable(CAP_SETGID))
616 new->gid = new->egid = new->sgid = new->fsgid = gid; 632 new->gid = new->egid = new->sgid = new->fsgid = kgid;
617 else if (gid == old->gid || gid == old->sgid) 633 else if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->sgid))
618 new->egid = new->fsgid = gid; 634 new->egid = new->fsgid = kgid;
619 else 635 else
620 goto error; 636 goto error;
621 637
@@ -672,9 +688,19 @@ static int set_user(struct cred *new)
672 */ 688 */
673SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid) 689SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
674{ 690{
691 struct user_namespace *ns = current_user_ns();
675 const struct cred *old; 692 const struct cred *old;
676 struct cred *new; 693 struct cred *new;
677 int retval; 694 int retval;
695 kuid_t kruid, keuid;
696
697 kruid = make_kuid(ns, ruid);
698 keuid = make_kuid(ns, euid);
699
700 if ((ruid != (uid_t) -1) && !uid_valid(kruid))
701 return -EINVAL;
702 if ((euid != (uid_t) -1) && !uid_valid(keuid))
703 return -EINVAL;
678 704
679 new = prepare_creds(); 705 new = prepare_creds();
680 if (!new) 706 if (!new)
@@ -683,29 +709,29 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
683 709
684 retval = -EPERM; 710 retval = -EPERM;
685 if (ruid != (uid_t) -1) { 711 if (ruid != (uid_t) -1) {
686 new->uid = ruid; 712 new->uid = kruid;
687 if (old->uid != ruid && 713 if (!uid_eq(old->uid, kruid) &&
688 old->euid != ruid && 714 !uid_eq(old->euid, kruid) &&
689 !nsown_capable(CAP_SETUID)) 715 !nsown_capable(CAP_SETUID))
690 goto error; 716 goto error;
691 } 717 }
692 718
693 if (euid != (uid_t) -1) { 719 if (euid != (uid_t) -1) {
694 new->euid = euid; 720 new->euid = keuid;
695 if (old->uid != euid && 721 if (!uid_eq(old->uid, keuid) &&
696 old->euid != euid && 722 !uid_eq(old->euid, keuid) &&
697 old->suid != euid && 723 !uid_eq(old->suid, keuid) &&
698 !nsown_capable(CAP_SETUID)) 724 !nsown_capable(CAP_SETUID))
699 goto error; 725 goto error;
700 } 726 }
701 727
702 if (new->uid != old->uid) { 728 if (!uid_eq(new->uid, old->uid)) {
703 retval = set_user(new); 729 retval = set_user(new);
704 if (retval < 0) 730 if (retval < 0)
705 goto error; 731 goto error;
706 } 732 }
707 if (ruid != (uid_t) -1 || 733 if (ruid != (uid_t) -1 ||
708 (euid != (uid_t) -1 && euid != old->uid)) 734 (euid != (uid_t) -1 && !uid_eq(keuid, old->uid)))
709 new->suid = new->euid; 735 new->suid = new->euid;
710 new->fsuid = new->euid; 736 new->fsuid = new->euid;
711 737
@@ -733,9 +759,15 @@ error:
733 */ 759 */
734SYSCALL_DEFINE1(setuid, uid_t, uid) 760SYSCALL_DEFINE1(setuid, uid_t, uid)
735{ 761{
762 struct user_namespace *ns = current_user_ns();
736 const struct cred *old; 763 const struct cred *old;
737 struct cred *new; 764 struct cred *new;
738 int retval; 765 int retval;
766 kuid_t kuid;
767
768 kuid = make_kuid(ns, uid);
769 if (!uid_valid(kuid))
770 return -EINVAL;
739 771
740 new = prepare_creds(); 772 new = prepare_creds();
741 if (!new) 773 if (!new)
@@ -744,17 +776,17 @@ SYSCALL_DEFINE1(setuid, uid_t, uid)
744 776
745 retval = -EPERM; 777 retval = -EPERM;
746 if (nsown_capable(CAP_SETUID)) { 778 if (nsown_capable(CAP_SETUID)) {
747 new->suid = new->uid = uid; 779 new->suid = new->uid = kuid;
748 if (uid != old->uid) { 780 if (!uid_eq(kuid, old->uid)) {
749 retval = set_user(new); 781 retval = set_user(new);
750 if (retval < 0) 782 if (retval < 0)
751 goto error; 783 goto error;
752 } 784 }
753 } else if (uid != old->uid && uid != new->suid) { 785 } else if (!uid_eq(kuid, old->uid) && !uid_eq(kuid, new->suid)) {
754 goto error; 786 goto error;
755 } 787 }
756 788
757 new->fsuid = new->euid = uid; 789 new->fsuid = new->euid = kuid;
758 790
759 retval = security_task_fix_setuid(new, old, LSM_SETID_ID); 791 retval = security_task_fix_setuid(new, old, LSM_SETID_ID);
760 if (retval < 0) 792 if (retval < 0)
@@ -774,9 +806,24 @@ error:
774 */ 806 */
775SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid) 807SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
776{ 808{
809 struct user_namespace *ns = current_user_ns();
777 const struct cred *old; 810 const struct cred *old;
778 struct cred *new; 811 struct cred *new;
779 int retval; 812 int retval;
813 kuid_t kruid, keuid, ksuid;
814
815 kruid = make_kuid(ns, ruid);
816 keuid = make_kuid(ns, euid);
817 ksuid = make_kuid(ns, suid);
818
819 if ((ruid != (uid_t) -1) && !uid_valid(kruid))
820 return -EINVAL;
821
822 if ((euid != (uid_t) -1) && !uid_valid(keuid))
823 return -EINVAL;
824
825 if ((suid != (uid_t) -1) && !uid_valid(ksuid))
826 return -EINVAL;
780 827
781 new = prepare_creds(); 828 new = prepare_creds();
782 if (!new) 829 if (!new)
@@ -786,29 +833,29 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
786 833
787 retval = -EPERM; 834 retval = -EPERM;
788 if (!nsown_capable(CAP_SETUID)) { 835 if (!nsown_capable(CAP_SETUID)) {
789 if (ruid != (uid_t) -1 && ruid != old->uid && 836 if (ruid != (uid_t) -1 && !uid_eq(kruid, old->uid) &&
790 ruid != old->euid && ruid != old->suid) 837 !uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid))
791 goto error; 838 goto error;
792 if (euid != (uid_t) -1 && euid != old->uid && 839 if (euid != (uid_t) -1 && !uid_eq(keuid, old->uid) &&
793 euid != old->euid && euid != old->suid) 840 !uid_eq(keuid, old->euid) && !uid_eq(keuid, old->suid))
794 goto error; 841 goto error;
795 if (suid != (uid_t) -1 && suid != old->uid && 842 if (suid != (uid_t) -1 && !uid_eq(ksuid, old->uid) &&
796 suid != old->euid && suid != old->suid) 843 !uid_eq(ksuid, old->euid) && !uid_eq(ksuid, old->suid))
797 goto error; 844 goto error;
798 } 845 }
799 846
800 if (ruid != (uid_t) -1) { 847 if (ruid != (uid_t) -1) {
801 new->uid = ruid; 848 new->uid = kruid;
802 if (ruid != old->uid) { 849 if (!uid_eq(kruid, old->uid)) {
803 retval = set_user(new); 850 retval = set_user(new);
804 if (retval < 0) 851 if (retval < 0)
805 goto error; 852 goto error;
806 } 853 }
807 } 854 }
808 if (euid != (uid_t) -1) 855 if (euid != (uid_t) -1)
809 new->euid = euid; 856 new->euid = keuid;
810 if (suid != (uid_t) -1) 857 if (suid != (uid_t) -1)
811 new->suid = suid; 858 new->suid = ksuid;
812 new->fsuid = new->euid; 859 new->fsuid = new->euid;
813 860
814 retval = security_task_fix_setuid(new, old, LSM_SETID_RES); 861 retval = security_task_fix_setuid(new, old, LSM_SETID_RES);
@@ -822,14 +869,19 @@ error:
822 return retval; 869 return retval;
823} 870}
824 871
825SYSCALL_DEFINE3(getresuid, uid_t __user *, ruid, uid_t __user *, euid, uid_t __user *, suid) 872SYSCALL_DEFINE3(getresuid, uid_t __user *, ruidp, uid_t __user *, euidp, uid_t __user *, suidp)
826{ 873{
827 const struct cred *cred = current_cred(); 874 const struct cred *cred = current_cred();
828 int retval; 875 int retval;
876 uid_t ruid, euid, suid;
877
878 ruid = from_kuid_munged(cred->user_ns, cred->uid);
879 euid = from_kuid_munged(cred->user_ns, cred->euid);
880 suid = from_kuid_munged(cred->user_ns, cred->suid);
829 881
830 if (!(retval = put_user(cred->uid, ruid)) && 882 if (!(retval = put_user(ruid, ruidp)) &&
831 !(retval = put_user(cred->euid, euid))) 883 !(retval = put_user(euid, euidp)))
832 retval = put_user(cred->suid, suid); 884 retval = put_user(suid, suidp);
833 885
834 return retval; 886 return retval;
835} 887}
@@ -839,9 +891,22 @@ SYSCALL_DEFINE3(getresuid, uid_t __user *, ruid, uid_t __user *, euid, uid_t __u
839 */ 891 */
840SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid) 892SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
841{ 893{
894 struct user_namespace *ns = current_user_ns();
842 const struct cred *old; 895 const struct cred *old;
843 struct cred *new; 896 struct cred *new;
844 int retval; 897 int retval;
898 kgid_t krgid, kegid, ksgid;
899
900 krgid = make_kgid(ns, rgid);
901 kegid = make_kgid(ns, egid);
902 ksgid = make_kgid(ns, sgid);
903
904 if ((rgid != (gid_t) -1) && !gid_valid(krgid))
905 return -EINVAL;
906 if ((egid != (gid_t) -1) && !gid_valid(kegid))
907 return -EINVAL;
908 if ((sgid != (gid_t) -1) && !gid_valid(ksgid))
909 return -EINVAL;
845 910
846 new = prepare_creds(); 911 new = prepare_creds();
847 if (!new) 912 if (!new)
@@ -850,23 +915,23 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
850 915
851 retval = -EPERM; 916 retval = -EPERM;
852 if (!nsown_capable(CAP_SETGID)) { 917 if (!nsown_capable(CAP_SETGID)) {
853 if (rgid != (gid_t) -1 && rgid != old->gid && 918 if (rgid != (gid_t) -1 && !gid_eq(krgid, old->gid) &&
854 rgid != old->egid && rgid != old->sgid) 919 !gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid))
855 goto error; 920 goto error;
856 if (egid != (gid_t) -1 && egid != old->gid && 921 if (egid != (gid_t) -1 && !gid_eq(kegid, old->gid) &&
857 egid != old->egid && egid != old->sgid) 922 !gid_eq(kegid, old->egid) && !gid_eq(kegid, old->sgid))
858 goto error; 923 goto error;
859 if (sgid != (gid_t) -1 && sgid != old->gid && 924 if (sgid != (gid_t) -1 && !gid_eq(ksgid, old->gid) &&
860 sgid != old->egid && sgid != old->sgid) 925 !gid_eq(ksgid, old->egid) && !gid_eq(ksgid, old->sgid))
861 goto error; 926 goto error;
862 } 927 }
863 928
864 if (rgid != (gid_t) -1) 929 if (rgid != (gid_t) -1)
865 new->gid = rgid; 930 new->gid = krgid;
866 if (egid != (gid_t) -1) 931 if (egid != (gid_t) -1)
867 new->egid = egid; 932 new->egid = kegid;
868 if (sgid != (gid_t) -1) 933 if (sgid != (gid_t) -1)
869 new->sgid = sgid; 934 new->sgid = ksgid;
870 new->fsgid = new->egid; 935 new->fsgid = new->egid;
871 936
872 return commit_creds(new); 937 return commit_creds(new);
@@ -876,14 +941,19 @@ error:
876 return retval; 941 return retval;
877} 942}
878 943
879SYSCALL_DEFINE3(getresgid, gid_t __user *, rgid, gid_t __user *, egid, gid_t __user *, sgid) 944SYSCALL_DEFINE3(getresgid, gid_t __user *, rgidp, gid_t __user *, egidp, gid_t __user *, sgidp)
880{ 945{
881 const struct cred *cred = current_cred(); 946 const struct cred *cred = current_cred();
882 int retval; 947 int retval;
948 gid_t rgid, egid, sgid;
949
950 rgid = from_kgid_munged(cred->user_ns, cred->gid);
951 egid = from_kgid_munged(cred->user_ns, cred->egid);
952 sgid = from_kgid_munged(cred->user_ns, cred->sgid);
883 953
884 if (!(retval = put_user(cred->gid, rgid)) && 954 if (!(retval = put_user(rgid, rgidp)) &&
885 !(retval = put_user(cred->egid, egid))) 955 !(retval = put_user(egid, egidp)))
886 retval = put_user(cred->sgid, sgid); 956 retval = put_user(sgid, sgidp);
887 957
888 return retval; 958 return retval;
889} 959}
@@ -900,18 +970,24 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
900 const struct cred *old; 970 const struct cred *old;
901 struct cred *new; 971 struct cred *new;
902 uid_t old_fsuid; 972 uid_t old_fsuid;
973 kuid_t kuid;
974
975 old = current_cred();
976 old_fsuid = from_kuid_munged(old->user_ns, old->fsuid);
977
978 kuid = make_kuid(old->user_ns, uid);
979 if (!uid_valid(kuid))
980 return old_fsuid;
903 981
904 new = prepare_creds(); 982 new = prepare_creds();
905 if (!new) 983 if (!new)
906 return current_fsuid(); 984 return old_fsuid;
907 old = current_cred();
908 old_fsuid = old->fsuid;
909 985
910 if (uid == old->uid || uid == old->euid || 986 if (uid_eq(kuid, old->uid) || uid_eq(kuid, old->euid) ||
911 uid == old->suid || uid == old->fsuid || 987 uid_eq(kuid, old->suid) || uid_eq(kuid, old->fsuid) ||
912 nsown_capable(CAP_SETUID)) { 988 nsown_capable(CAP_SETUID)) {
913 if (uid != old_fsuid) { 989 if (!uid_eq(kuid, old->fsuid)) {
914 new->fsuid = uid; 990 new->fsuid = kuid;
915 if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0) 991 if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0)
916 goto change_okay; 992 goto change_okay;
917 } 993 }
@@ -933,18 +1009,24 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
933 const struct cred *old; 1009 const struct cred *old;
934 struct cred *new; 1010 struct cred *new;
935 gid_t old_fsgid; 1011 gid_t old_fsgid;
1012 kgid_t kgid;
1013
1014 old = current_cred();
1015 old_fsgid = from_kgid_munged(old->user_ns, old->fsgid);
1016
1017 kgid = make_kgid(old->user_ns, gid);
1018 if (!gid_valid(kgid))
1019 return old_fsgid;
936 1020
937 new = prepare_creds(); 1021 new = prepare_creds();
938 if (!new) 1022 if (!new)
939 return current_fsgid(); 1023 return old_fsgid;
940 old = current_cred();
941 old_fsgid = old->fsgid;
942 1024
943 if (gid == old->gid || gid == old->egid || 1025 if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->egid) ||
944 gid == old->sgid || gid == old->fsgid || 1026 gid_eq(kgid, old->sgid) || gid_eq(kgid, old->fsgid) ||
945 nsown_capable(CAP_SETGID)) { 1027 nsown_capable(CAP_SETGID)) {
946 if (gid != old_fsgid) { 1028 if (!gid_eq(kgid, old->fsgid)) {
947 new->fsgid = gid; 1029 new->fsgid = kgid;
948 goto change_okay; 1030 goto change_okay;
949 } 1031 }
950 } 1032 }
@@ -1503,10 +1585,10 @@ static int check_prlimit_permission(struct task_struct *task)
1503 if (cred->user_ns == tcred->user_ns && 1585 if (cred->user_ns == tcred->user_ns &&
1504 (cred->uid == tcred->euid && 1586 (cred->uid == tcred->euid &&
1505 cred->uid == tcred->suid && 1587 cred->uid == tcred->suid &&
1506 cred->uid == tcred->uid && 1588 cred->uid == tcred->uid &&
1507 cred->gid == tcred->egid && 1589 cred->gid == tcred->egid &&
1508 cred->gid == tcred->sgid && 1590 cred->gid == tcred->sgid &&
1509 cred->gid == tcred->gid)) 1591 cred->gid == tcred->gid))
1510 return 0; 1592 return 0;
1511 if (ns_capable(tcred->user_ns, CAP_SYS_RESOURCE)) 1593 if (ns_capable(tcred->user_ns, CAP_SYS_RESOURCE))
1512 return 0; 1594 return 0;