hc
2024-05-10 61598093bbdd283a7edc367d900f223070ead8d2
kernel/kernel/sys.c
....@@ -644,6 +644,7 @@
644644 struct cred *new;
645645 int retval;
646646 kuid_t kruid, keuid, ksuid;
647
+ bool ruid_new, euid_new, suid_new;
647648
648649 kruid = make_kuid(ns, ruid);
649650 keuid = make_kuid(ns, euid);
....@@ -658,24 +659,28 @@
658659 if ((suid != (uid_t) -1) && !uid_valid(ksuid))
659660 return -EINVAL;
660661
662
+ old = current_cred();
663
+
664
+ /* check for no-op */
665
+ if ((ruid == (uid_t) -1 || uid_eq(kruid, old->uid)) &&
666
+ (euid == (uid_t) -1 || (uid_eq(keuid, old->euid) &&
667
+ uid_eq(keuid, old->fsuid))) &&
668
+ (suid == (uid_t) -1 || uid_eq(ksuid, old->suid)))
669
+ return 0;
670
+
671
+ ruid_new = ruid != (uid_t) -1 && !uid_eq(kruid, old->uid) &&
672
+ !uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid);
673
+ euid_new = euid != (uid_t) -1 && !uid_eq(keuid, old->uid) &&
674
+ !uid_eq(keuid, old->euid) && !uid_eq(keuid, old->suid);
675
+ suid_new = suid != (uid_t) -1 && !uid_eq(ksuid, old->uid) &&
676
+ !uid_eq(ksuid, old->euid) && !uid_eq(ksuid, old->suid);
677
+ if ((ruid_new || euid_new || suid_new) &&
678
+ !ns_capable_setid(old->user_ns, CAP_SETUID))
679
+ return -EPERM;
680
+
661681 new = prepare_creds();
662682 if (!new)
663683 return -ENOMEM;
664
-
665
- old = current_cred();
666
-
667
- retval = -EPERM;
668
- if (!ns_capable_setid(old->user_ns, CAP_SETUID)) {
669
- if (ruid != (uid_t) -1 && !uid_eq(kruid, old->uid) &&
670
- !uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid))
671
- goto error;
672
- if (euid != (uid_t) -1 && !uid_eq(keuid, old->uid) &&
673
- !uid_eq(keuid, old->euid) && !uid_eq(keuid, old->suid))
674
- goto error;
675
- if (suid != (uid_t) -1 && !uid_eq(ksuid, old->uid) &&
676
- !uid_eq(ksuid, old->euid) && !uid_eq(ksuid, old->suid))
677
- goto error;
678
- }
679684
680685 if (ruid != (uid_t) -1) {
681686 new->uid = kruid;
....@@ -736,6 +741,7 @@
736741 struct cred *new;
737742 int retval;
738743 kgid_t krgid, kegid, ksgid;
744
+ bool rgid_new, egid_new, sgid_new;
739745
740746 krgid = make_kgid(ns, rgid);
741747 kegid = make_kgid(ns, egid);
....@@ -748,23 +754,28 @@
748754 if ((sgid != (gid_t) -1) && !gid_valid(ksgid))
749755 return -EINVAL;
750756
757
+ old = current_cred();
758
+
759
+ /* check for no-op */
760
+ if ((rgid == (gid_t) -1 || gid_eq(krgid, old->gid)) &&
761
+ (egid == (gid_t) -1 || (gid_eq(kegid, old->egid) &&
762
+ gid_eq(kegid, old->fsgid))) &&
763
+ (sgid == (gid_t) -1 || gid_eq(ksgid, old->sgid)))
764
+ return 0;
765
+
766
+ rgid_new = rgid != (gid_t) -1 && !gid_eq(krgid, old->gid) &&
767
+ !gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid);
768
+ egid_new = egid != (gid_t) -1 && !gid_eq(kegid, old->gid) &&
769
+ !gid_eq(kegid, old->egid) && !gid_eq(kegid, old->sgid);
770
+ sgid_new = sgid != (gid_t) -1 && !gid_eq(ksgid, old->gid) &&
771
+ !gid_eq(ksgid, old->egid) && !gid_eq(ksgid, old->sgid);
772
+ if ((rgid_new || egid_new || sgid_new) &&
773
+ !ns_capable_setid(old->user_ns, CAP_SETGID))
774
+ return -EPERM;
775
+
751776 new = prepare_creds();
752777 if (!new)
753778 return -ENOMEM;
754
- old = current_cred();
755
-
756
- retval = -EPERM;
757
- if (!ns_capable_setid(old->user_ns, CAP_SETGID)) {
758
- if (rgid != (gid_t) -1 && !gid_eq(krgid, old->gid) &&
759
- !gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid))
760
- goto error;
761
- if (egid != (gid_t) -1 && !gid_eq(kegid, old->gid) &&
762
- !gid_eq(kegid, old->egid) && !gid_eq(kegid, old->sgid))
763
- goto error;
764
- if (sgid != (gid_t) -1 && !gid_eq(ksgid, old->gid) &&
765
- !gid_eq(ksgid, old->egid) && !gid_eq(ksgid, old->sgid))
766
- goto error;
767
- }
768779
769780 if (rgid != (gid_t) -1)
770781 new->gid = krgid;
....@@ -1558,6 +1569,8 @@
15581569
15591570 if (resource >= RLIM_NLIMITS)
15601571 return -EINVAL;
1572
+ resource = array_index_nospec(resource, RLIM_NLIMITS);
1573
+
15611574 if (new_rlim) {
15621575 if (new_rlim->rlim_cur > new_rlim->rlim_max)
15631576 return -EINVAL;