aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c266
1 files changed, 174 insertions, 92 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index ba0ae8eea6fb..6df42624e454 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -93,10 +93,8 @@
93int overflowuid = DEFAULT_OVERFLOWUID; 93int overflowuid = DEFAULT_OVERFLOWUID;
94int overflowgid = DEFAULT_OVERFLOWGID; 94int overflowgid = DEFAULT_OVERFLOWGID;
95 95
96#ifdef CONFIG_UID16
97EXPORT_SYMBOL(overflowuid); 96EXPORT_SYMBOL(overflowuid);
98EXPORT_SYMBOL(overflowgid); 97EXPORT_SYMBOL(overflowgid);
99#endif
100 98
101/* 99/*
102 * the same as above, but for filesystems which can only store a 16-bit 100 * the same as above, but for filesystems which can only store a 16-bit
@@ -133,11 +131,10 @@ static bool set_one_prio_perm(struct task_struct *p)
133{ 131{
134 const struct cred *cred = current_cred(), *pcred = __task_cred(p); 132 const struct cred *cred = current_cred(), *pcred = __task_cred(p);
135 133
136 if (pcred->user->user_ns == cred->user->user_ns && 134 if (uid_eq(pcred->uid, cred->euid) ||
137 (pcred->uid == cred->euid || 135 uid_eq(pcred->euid, cred->euid))
138 pcred->euid == cred->euid))
139 return true; 136 return true;
140 if (ns_capable(pcred->user->user_ns, CAP_SYS_NICE)) 137 if (ns_capable(pcred->user_ns, CAP_SYS_NICE))
141 return true; 138 return true;
142 return false; 139 return false;
143} 140}
@@ -177,6 +174,7 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)
177 const struct cred *cred = current_cred(); 174 const struct cred *cred = current_cred();
178 int error = -EINVAL; 175 int error = -EINVAL;
179 struct pid *pgrp; 176 struct pid *pgrp;
177 kuid_t uid;
180 178
181 if (which > PRIO_USER || which < PRIO_PROCESS) 179 if (which > PRIO_USER || which < PRIO_PROCESS)
182 goto out; 180 goto out;
@@ -209,18 +207,19 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)
209 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); 207 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
210 break; 208 break;
211 case PRIO_USER: 209 case PRIO_USER:
212 user = (struct user_struct *) cred->user; 210 uid = make_kuid(cred->user_ns, who);
211 user = cred->user;
213 if (!who) 212 if (!who)
214 who = cred->uid; 213 uid = cred->uid;
215 else if ((who != cred->uid) && 214 else if (!uid_eq(uid, cred->uid) &&
216 !(user = find_user(who))) 215 !(user = find_user(uid)))
217 goto out_unlock; /* No processes for this user */ 216 goto out_unlock; /* No processes for this user */
218 217
219 do_each_thread(g, p) { 218 do_each_thread(g, p) {
220 if (__task_cred(p)->uid == who) 219 if (uid_eq(task_uid(p), uid))
221 error = set_one_prio(p, niceval, error); 220 error = set_one_prio(p, niceval, error);
222 } while_each_thread(g, p); 221 } while_each_thread(g, p);
223 if (who != cred->uid) 222 if (!uid_eq(uid, cred->uid))
224 free_uid(user); /* For find_user() */ 223 free_uid(user); /* For find_user() */
225 break; 224 break;
226 } 225 }
@@ -244,6 +243,7 @@ SYSCALL_DEFINE2(getpriority, int, which, int, who)
244 const struct cred *cred = current_cred(); 243 const struct cred *cred = current_cred();
245 long niceval, retval = -ESRCH; 244 long niceval, retval = -ESRCH;
246 struct pid *pgrp; 245 struct pid *pgrp;
246 kuid_t uid;
247 247
248 if (which > PRIO_USER || which < PRIO_PROCESS) 248 if (which > PRIO_USER || which < PRIO_PROCESS)
249 return -EINVAL; 249 return -EINVAL;
@@ -274,21 +274,22 @@ SYSCALL_DEFINE2(getpriority, int, which, int, who)
274 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); 274 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
275 break; 275 break;
276 case PRIO_USER: 276 case PRIO_USER:
277 user = (struct user_struct *) cred->user; 277 uid = make_kuid(cred->user_ns, who);
278 user = cred->user;
278 if (!who) 279 if (!who)
279 who = cred->uid; 280 uid = cred->uid;
280 else if ((who != cred->uid) && 281 else if (!uid_eq(uid, cred->uid) &&
281 !(user = find_user(who))) 282 !(user = find_user(uid)))
282 goto out_unlock; /* No processes for this user */ 283 goto out_unlock; /* No processes for this user */
283 284
284 do_each_thread(g, p) { 285 do_each_thread(g, p) {
285 if (__task_cred(p)->uid == who) { 286 if (uid_eq(task_uid(p), uid)) {
286 niceval = 20 - task_nice(p); 287 niceval = 20 - task_nice(p);
287 if (niceval > retval) 288 if (niceval > retval)
288 retval = niceval; 289 retval = niceval;
289 } 290 }
290 } while_each_thread(g, p); 291 } while_each_thread(g, p);
291 if (who != cred->uid) 292 if (!uid_eq(uid, cred->uid))
292 free_uid(user); /* for find_user() */ 293 free_uid(user); /* for find_user() */
293 break; 294 break;
294 } 295 }
@@ -553,9 +554,19 @@ void ctrl_alt_del(void)
553 */ 554 */
554SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid) 555SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
555{ 556{
557 struct user_namespace *ns = current_user_ns();
556 const struct cred *old; 558 const struct cred *old;
557 struct cred *new; 559 struct cred *new;
558 int retval; 560 int retval;
561 kgid_t krgid, kegid;
562
563 krgid = make_kgid(ns, rgid);
564 kegid = make_kgid(ns, egid);
565
566 if ((rgid != (gid_t) -1) && !gid_valid(krgid))
567 return -EINVAL;
568 if ((egid != (gid_t) -1) && !gid_valid(kegid))
569 return -EINVAL;
559 570
560 new = prepare_creds(); 571 new = prepare_creds();
561 if (!new) 572 if (!new)
@@ -564,25 +575,25 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
564 575
565 retval = -EPERM; 576 retval = -EPERM;
566 if (rgid != (gid_t) -1) { 577 if (rgid != (gid_t) -1) {
567 if (old->gid == rgid || 578 if (gid_eq(old->gid, krgid) ||
568 old->egid == rgid || 579 gid_eq(old->egid, krgid) ||
569 nsown_capable(CAP_SETGID)) 580 nsown_capable(CAP_SETGID))
570 new->gid = rgid; 581 new->gid = krgid;
571 else 582 else
572 goto error; 583 goto error;
573 } 584 }
574 if (egid != (gid_t) -1) { 585 if (egid != (gid_t) -1) {
575 if (old->gid == egid || 586 if (gid_eq(old->gid, kegid) ||
576 old->egid == egid || 587 gid_eq(old->egid, kegid) ||
577 old->sgid == egid || 588 gid_eq(old->sgid, kegid) ||
578 nsown_capable(CAP_SETGID)) 589 nsown_capable(CAP_SETGID))
579 new->egid = egid; 590 new->egid = kegid;
580 else 591 else
581 goto error; 592 goto error;
582 } 593 }
583 594
584 if (rgid != (gid_t) -1 || 595 if (rgid != (gid_t) -1 ||
585 (egid != (gid_t) -1 && egid != old->gid)) 596 (egid != (gid_t) -1 && !gid_eq(kegid, old->gid)))
586 new->sgid = new->egid; 597 new->sgid = new->egid;
587 new->fsgid = new->egid; 598 new->fsgid = new->egid;
588 599
@@ -600,9 +611,15 @@ error:
600 */ 611 */
601SYSCALL_DEFINE1(setgid, gid_t, gid) 612SYSCALL_DEFINE1(setgid, gid_t, gid)
602{ 613{
614 struct user_namespace *ns = current_user_ns();
603 const struct cred *old; 615 const struct cred *old;
604 struct cred *new; 616 struct cred *new;
605 int retval; 617 int retval;
618 kgid_t kgid;
619
620 kgid = make_kgid(ns, gid);
621 if (!gid_valid(kgid))
622 return -EINVAL;
606 623
607 new = prepare_creds(); 624 new = prepare_creds();
608 if (!new) 625 if (!new)
@@ -611,9 +628,9 @@ SYSCALL_DEFINE1(setgid, gid_t, gid)
611 628
612 retval = -EPERM; 629 retval = -EPERM;
613 if (nsown_capable(CAP_SETGID)) 630 if (nsown_capable(CAP_SETGID))
614 new->gid = new->egid = new->sgid = new->fsgid = gid; 631 new->gid = new->egid = new->sgid = new->fsgid = kgid;
615 else if (gid == old->gid || gid == old->sgid) 632 else if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->sgid))
616 new->egid = new->fsgid = gid; 633 new->egid = new->fsgid = kgid;
617 else 634 else
618 goto error; 635 goto error;
619 636
@@ -631,7 +648,7 @@ static int set_user(struct cred *new)
631{ 648{
632 struct user_struct *new_user; 649 struct user_struct *new_user;
633 650
634 new_user = alloc_uid(current_user_ns(), new->uid); 651 new_user = alloc_uid(new->uid);
635 if (!new_user) 652 if (!new_user)
636 return -EAGAIN; 653 return -EAGAIN;
637 654
@@ -670,9 +687,19 @@ static int set_user(struct cred *new)
670 */ 687 */
671SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid) 688SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
672{ 689{
690 struct user_namespace *ns = current_user_ns();
673 const struct cred *old; 691 const struct cred *old;
674 struct cred *new; 692 struct cred *new;
675 int retval; 693 int retval;
694 kuid_t kruid, keuid;
695
696 kruid = make_kuid(ns, ruid);
697 keuid = make_kuid(ns, euid);
698
699 if ((ruid != (uid_t) -1) && !uid_valid(kruid))
700 return -EINVAL;
701 if ((euid != (uid_t) -1) && !uid_valid(keuid))
702 return -EINVAL;
676 703
677 new = prepare_creds(); 704 new = prepare_creds();
678 if (!new) 705 if (!new)
@@ -681,29 +708,29 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
681 708
682 retval = -EPERM; 709 retval = -EPERM;
683 if (ruid != (uid_t) -1) { 710 if (ruid != (uid_t) -1) {
684 new->uid = ruid; 711 new->uid = kruid;
685 if (old->uid != ruid && 712 if (!uid_eq(old->uid, kruid) &&
686 old->euid != ruid && 713 !uid_eq(old->euid, kruid) &&
687 !nsown_capable(CAP_SETUID)) 714 !nsown_capable(CAP_SETUID))
688 goto error; 715 goto error;
689 } 716 }
690 717
691 if (euid != (uid_t) -1) { 718 if (euid != (uid_t) -1) {
692 new->euid = euid; 719 new->euid = keuid;
693 if (old->uid != euid && 720 if (!uid_eq(old->uid, keuid) &&
694 old->euid != euid && 721 !uid_eq(old->euid, keuid) &&
695 old->suid != euid && 722 !uid_eq(old->suid, keuid) &&
696 !nsown_capable(CAP_SETUID)) 723 !nsown_capable(CAP_SETUID))
697 goto error; 724 goto error;
698 } 725 }
699 726
700 if (new->uid != old->uid) { 727 if (!uid_eq(new->uid, old->uid)) {
701 retval = set_user(new); 728 retval = set_user(new);
702 if (retval < 0) 729 if (retval < 0)
703 goto error; 730 goto error;
704 } 731 }
705 if (ruid != (uid_t) -1 || 732 if (ruid != (uid_t) -1 ||
706 (euid != (uid_t) -1 && euid != old->uid)) 733 (euid != (uid_t) -1 && !uid_eq(keuid, old->uid)))
707 new->suid = new->euid; 734 new->suid = new->euid;
708 new->fsuid = new->euid; 735 new->fsuid = new->euid;
709 736
@@ -731,9 +758,15 @@ error:
731 */ 758 */
732SYSCALL_DEFINE1(setuid, uid_t, uid) 759SYSCALL_DEFINE1(setuid, uid_t, uid)
733{ 760{
761 struct user_namespace *ns = current_user_ns();
734 const struct cred *old; 762 const struct cred *old;
735 struct cred *new; 763 struct cred *new;
736 int retval; 764 int retval;
765 kuid_t kuid;
766
767 kuid = make_kuid(ns, uid);
768 if (!uid_valid(kuid))
769 return -EINVAL;
737 770
738 new = prepare_creds(); 771 new = prepare_creds();
739 if (!new) 772 if (!new)
@@ -742,17 +775,17 @@ SYSCALL_DEFINE1(setuid, uid_t, uid)
742 775
743 retval = -EPERM; 776 retval = -EPERM;
744 if (nsown_capable(CAP_SETUID)) { 777 if (nsown_capable(CAP_SETUID)) {
745 new->suid = new->uid = uid; 778 new->suid = new->uid = kuid;
746 if (uid != old->uid) { 779 if (!uid_eq(kuid, old->uid)) {
747 retval = set_user(new); 780 retval = set_user(new);
748 if (retval < 0) 781 if (retval < 0)
749 goto error; 782 goto error;
750 } 783 }
751 } else if (uid != old->uid && uid != new->suid) { 784 } else if (!uid_eq(kuid, old->uid) && !uid_eq(kuid, new->suid)) {
752 goto error; 785 goto error;
753 } 786 }
754 787
755 new->fsuid = new->euid = uid; 788 new->fsuid = new->euid = kuid;
756 789
757 retval = security_task_fix_setuid(new, old, LSM_SETID_ID); 790 retval = security_task_fix_setuid(new, old, LSM_SETID_ID);
758 if (retval < 0) 791 if (retval < 0)
@@ -772,9 +805,24 @@ error:
772 */ 805 */
773SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid) 806SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
774{ 807{
808 struct user_namespace *ns = current_user_ns();
775 const struct cred *old; 809 const struct cred *old;
776 struct cred *new; 810 struct cred *new;
777 int retval; 811 int retval;
812 kuid_t kruid, keuid, ksuid;
813
814 kruid = make_kuid(ns, ruid);
815 keuid = make_kuid(ns, euid);
816 ksuid = make_kuid(ns, suid);
817
818 if ((ruid != (uid_t) -1) && !uid_valid(kruid))
819 return -EINVAL;
820
821 if ((euid != (uid_t) -1) && !uid_valid(keuid))
822 return -EINVAL;
823
824 if ((suid != (uid_t) -1) && !uid_valid(ksuid))
825 return -EINVAL;
778 826
779 new = prepare_creds(); 827 new = prepare_creds();
780 if (!new) 828 if (!new)
@@ -784,29 +832,29 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
784 832
785 retval = -EPERM; 833 retval = -EPERM;
786 if (!nsown_capable(CAP_SETUID)) { 834 if (!nsown_capable(CAP_SETUID)) {
787 if (ruid != (uid_t) -1 && ruid != old->uid && 835 if (ruid != (uid_t) -1 && !uid_eq(kruid, old->uid) &&
788 ruid != old->euid && ruid != old->suid) 836 !uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid))
789 goto error; 837 goto error;
790 if (euid != (uid_t) -1 && euid != old->uid && 838 if (euid != (uid_t) -1 && !uid_eq(keuid, old->uid) &&
791 euid != old->euid && euid != old->suid) 839 !uid_eq(keuid, old->euid) && !uid_eq(keuid, old->suid))
792 goto error; 840 goto error;
793 if (suid != (uid_t) -1 && suid != old->uid && 841 if (suid != (uid_t) -1 && !uid_eq(ksuid, old->uid) &&
794 suid != old->euid && suid != old->suid) 842 !uid_eq(ksuid, old->euid) && !uid_eq(ksuid, old->suid))
795 goto error; 843 goto error;
796 } 844 }
797 845
798 if (ruid != (uid_t) -1) { 846 if (ruid != (uid_t) -1) {
799 new->uid = ruid; 847 new->uid = kruid;
800 if (ruid != old->uid) { 848 if (!uid_eq(kruid, old->uid)) {
801 retval = set_user(new); 849 retval = set_user(new);
802 if (retval < 0) 850 if (retval < 0)
803 goto error; 851 goto error;
804 } 852 }
805 } 853 }
806 if (euid != (uid_t) -1) 854 if (euid != (uid_t) -1)
807 new->euid = euid; 855 new->euid = keuid;
808 if (suid != (uid_t) -1) 856 if (suid != (uid_t) -1)
809 new->suid = suid; 857 new->suid = ksuid;
810 new->fsuid = new->euid; 858 new->fsuid = new->euid;
811 859
812 retval = security_task_fix_setuid(new, old, LSM_SETID_RES); 860 retval = security_task_fix_setuid(new, old, LSM_SETID_RES);
@@ -820,14 +868,19 @@ error:
820 return retval; 868 return retval;
821} 869}
822 870
823SYSCALL_DEFINE3(getresuid, uid_t __user *, ruid, uid_t __user *, euid, uid_t __user *, suid) 871SYSCALL_DEFINE3(getresuid, uid_t __user *, ruidp, uid_t __user *, euidp, uid_t __user *, suidp)
824{ 872{
825 const struct cred *cred = current_cred(); 873 const struct cred *cred = current_cred();
826 int retval; 874 int retval;
875 uid_t ruid, euid, suid;
876
877 ruid = from_kuid_munged(cred->user_ns, cred->uid);
878 euid = from_kuid_munged(cred->user_ns, cred->euid);
879 suid = from_kuid_munged(cred->user_ns, cred->suid);
827 880
828 if (!(retval = put_user(cred->uid, ruid)) && 881 if (!(retval = put_user(ruid, ruidp)) &&
829 !(retval = put_user(cred->euid, euid))) 882 !(retval = put_user(euid, euidp)))
830 retval = put_user(cred->suid, suid); 883 retval = put_user(suid, suidp);
831 884
832 return retval; 885 return retval;
833} 886}
@@ -837,9 +890,22 @@ SYSCALL_DEFINE3(getresuid, uid_t __user *, ruid, uid_t __user *, euid, uid_t __u
837 */ 890 */
838SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid) 891SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
839{ 892{
893 struct user_namespace *ns = current_user_ns();
840 const struct cred *old; 894 const struct cred *old;
841 struct cred *new; 895 struct cred *new;
842 int retval; 896 int retval;
897 kgid_t krgid, kegid, ksgid;
898
899 krgid = make_kgid(ns, rgid);
900 kegid = make_kgid(ns, egid);
901 ksgid = make_kgid(ns, sgid);
902
903 if ((rgid != (gid_t) -1) && !gid_valid(krgid))
904 return -EINVAL;
905 if ((egid != (gid_t) -1) && !gid_valid(kegid))
906 return -EINVAL;
907 if ((sgid != (gid_t) -1) && !gid_valid(ksgid))
908 return -EINVAL;
843 909
844 new = prepare_creds(); 910 new = prepare_creds();
845 if (!new) 911 if (!new)
@@ -848,23 +914,23 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
848 914
849 retval = -EPERM; 915 retval = -EPERM;
850 if (!nsown_capable(CAP_SETGID)) { 916 if (!nsown_capable(CAP_SETGID)) {
851 if (rgid != (gid_t) -1 && rgid != old->gid && 917 if (rgid != (gid_t) -1 && !gid_eq(krgid, old->gid) &&
852 rgid != old->egid && rgid != old->sgid) 918 !gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid))
853 goto error; 919 goto error;
854 if (egid != (gid_t) -1 && egid != old->gid && 920 if (egid != (gid_t) -1 && !gid_eq(kegid, old->gid) &&
855 egid != old->egid && egid != old->sgid) 921 !gid_eq(kegid, old->egid) && !gid_eq(kegid, old->sgid))
856 goto error; 922 goto error;
857 if (sgid != (gid_t) -1 && sgid != old->gid && 923 if (sgid != (gid_t) -1 && !gid_eq(ksgid, old->gid) &&
858 sgid != old->egid && sgid != old->sgid) 924 !gid_eq(ksgid, old->egid) && !gid_eq(ksgid, old->sgid))
859 goto error; 925 goto error;
860 } 926 }
861 927
862 if (rgid != (gid_t) -1) 928 if (rgid != (gid_t) -1)
863 new->gid = rgid; 929 new->gid = krgid;
864 if (egid != (gid_t) -1) 930 if (egid != (gid_t) -1)
865 new->egid = egid; 931 new->egid = kegid;
866 if (sgid != (gid_t) -1) 932 if (sgid != (gid_t) -1)
867 new->sgid = sgid; 933 new->sgid = ksgid;
868 new->fsgid = new->egid; 934 new->fsgid = new->egid;
869 935
870 return commit_creds(new); 936 return commit_creds(new);
@@ -874,14 +940,19 @@ error:
874 return retval; 940 return retval;
875} 941}
876 942
877SYSCALL_DEFINE3(getresgid, gid_t __user *, rgid, gid_t __user *, egid, gid_t __user *, sgid) 943SYSCALL_DEFINE3(getresgid, gid_t __user *, rgidp, gid_t __user *, egidp, gid_t __user *, sgidp)
878{ 944{
879 const struct cred *cred = current_cred(); 945 const struct cred *cred = current_cred();
880 int retval; 946 int retval;
947 gid_t rgid, egid, sgid;
948
949 rgid = from_kgid_munged(cred->user_ns, cred->gid);
950 egid = from_kgid_munged(cred->user_ns, cred->egid);
951 sgid = from_kgid_munged(cred->user_ns, cred->sgid);
881 952
882 if (!(retval = put_user(cred->gid, rgid)) && 953 if (!(retval = put_user(rgid, rgidp)) &&
883 !(retval = put_user(cred->egid, egid))) 954 !(retval = put_user(egid, egidp)))
884 retval = put_user(cred->sgid, sgid); 955 retval = put_user(sgid, sgidp);
885 956
886 return retval; 957 return retval;
887} 958}
@@ -898,18 +969,24 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
898 const struct cred *old; 969 const struct cred *old;
899 struct cred *new; 970 struct cred *new;
900 uid_t old_fsuid; 971 uid_t old_fsuid;
972 kuid_t kuid;
973
974 old = current_cred();
975 old_fsuid = from_kuid_munged(old->user_ns, old->fsuid);
976
977 kuid = make_kuid(old->user_ns, uid);
978 if (!uid_valid(kuid))
979 return old_fsuid;
901 980
902 new = prepare_creds(); 981 new = prepare_creds();
903 if (!new) 982 if (!new)
904 return current_fsuid(); 983 return old_fsuid;
905 old = current_cred();
906 old_fsuid = old->fsuid;
907 984
908 if (uid == old->uid || uid == old->euid || 985 if (uid_eq(kuid, old->uid) || uid_eq(kuid, old->euid) ||
909 uid == old->suid || uid == old->fsuid || 986 uid_eq(kuid, old->suid) || uid_eq(kuid, old->fsuid) ||
910 nsown_capable(CAP_SETUID)) { 987 nsown_capable(CAP_SETUID)) {
911 if (uid != old_fsuid) { 988 if (!uid_eq(kuid, old->fsuid)) {
912 new->fsuid = uid; 989 new->fsuid = kuid;
913 if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0) 990 if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0)
914 goto change_okay; 991 goto change_okay;
915 } 992 }
@@ -931,18 +1008,24 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
931 const struct cred *old; 1008 const struct cred *old;
932 struct cred *new; 1009 struct cred *new;
933 gid_t old_fsgid; 1010 gid_t old_fsgid;
1011 kgid_t kgid;
1012
1013 old = current_cred();
1014 old_fsgid = from_kgid_munged(old->user_ns, old->fsgid);
1015
1016 kgid = make_kgid(old->user_ns, gid);
1017 if (!gid_valid(kgid))
1018 return old_fsgid;
934 1019
935 new = prepare_creds(); 1020 new = prepare_creds();
936 if (!new) 1021 if (!new)
937 return current_fsgid(); 1022 return old_fsgid;
938 old = current_cred();
939 old_fsgid = old->fsgid;
940 1023
941 if (gid == old->gid || gid == old->egid || 1024 if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->egid) ||
942 gid == old->sgid || gid == old->fsgid || 1025 gid_eq(kgid, old->sgid) || gid_eq(kgid, old->fsgid) ||
943 nsown_capable(CAP_SETGID)) { 1026 nsown_capable(CAP_SETGID)) {
944 if (gid != old_fsgid) { 1027 if (!gid_eq(kgid, old->fsgid)) {
945 new->fsgid = gid; 1028 new->fsgid = kgid;
946 goto change_okay; 1029 goto change_okay;
947 } 1030 }
948 } 1031 }
@@ -1498,15 +1581,14 @@ static int check_prlimit_permission(struct task_struct *task)
1498 return 0; 1581 return 0;
1499 1582
1500 tcred = __task_cred(task); 1583 tcred = __task_cred(task);
1501 if (cred->user->user_ns == tcred->user->user_ns && 1584 if (uid_eq(cred->uid, tcred->euid) &&
1502 (cred->uid == tcred->euid && 1585 uid_eq(cred->uid, tcred->suid) &&
1503 cred->uid == tcred->suid && 1586 uid_eq(cred->uid, tcred->uid) &&
1504 cred->uid == tcred->uid && 1587 gid_eq(cred->gid, tcred->egid) &&
1505 cred->gid == tcred->egid && 1588 gid_eq(cred->gid, tcred->sgid) &&
1506 cred->gid == tcred->sgid && 1589 gid_eq(cred->gid, tcred->gid))
1507 cred->gid == tcred->gid))
1508 return 0; 1590 return 0;
1509 if (ns_capable(tcred->user->user_ns, CAP_SYS_RESOURCE)) 1591 if (ns_capable(tcred->user_ns, CAP_SYS_RESOURCE))
1510 return 0; 1592 return 0;
1511 1593
1512 return -EPERM; 1594 return -EPERM;