aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2008-11-13 18:39:16 -0500
committerJames Morris <jmorris@namei.org>2008-11-13 18:39:16 -0500
commitb6dff3ec5e116e3af6f537d4caedcad6b9e5082a (patch)
tree9e76f972eb7ce9b84e0146c8e4126a3f86acb428 /kernel/sys.c
parent15a2460ed0af7538ca8e6c610fe607a2cd9da142 (diff)
CRED: Separate task security context from task_struct
Separate the task security context from task_struct. At this point, the security data is temporarily embedded in the task_struct with two pointers pointing to it. Note that the Alpha arch is altered as it refers to (E)UID and (E)GID in entry.S via asm-offsets. With comment fixes Signed-off-by: Marc Dionne <marc.c.dionne@gmail.com> Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: James Morris <jmorris@namei.org> Acked-by: Serge Hallyn <serue@us.ibm.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c266
1 files changed, 151 insertions, 115 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index ed5c29c748ac..5d81f07c0150 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -117,7 +117,9 @@ static int set_one_prio(struct task_struct *p, int niceval, int error)
117 uid_t euid = current_euid(); 117 uid_t euid = current_euid();
118 int no_nice; 118 int no_nice;
119 119
120 if (p->uid != euid && p->euid != euid && !capable(CAP_SYS_NICE)) { 120 if (p->cred->uid != euid &&
121 p->cred->euid != euid &&
122 !capable(CAP_SYS_NICE)) {
121 error = -EPERM; 123 error = -EPERM;
122 goto out; 124 goto out;
123 } 125 }
@@ -174,7 +176,7 @@ asmlinkage long sys_setpriority(int which, int who, int niceval)
174 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); 176 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
175 break; 177 break;
176 case PRIO_USER: 178 case PRIO_USER:
177 user = current->user; 179 user = current->cred->user;
178 if (!who) 180 if (!who)
179 who = current_uid(); 181 who = current_uid();
180 else 182 else
@@ -182,7 +184,7 @@ asmlinkage long sys_setpriority(int which, int who, int niceval)
182 goto out_unlock; /* No processes for this user */ 184 goto out_unlock; /* No processes for this user */
183 185
184 do_each_thread(g, p) 186 do_each_thread(g, p)
185 if (p->uid == who) 187 if (p->cred->uid == who)
186 error = set_one_prio(p, niceval, error); 188 error = set_one_prio(p, niceval, error);
187 while_each_thread(g, p); 189 while_each_thread(g, p);
188 if (who != current_uid()) 190 if (who != current_uid())
@@ -236,7 +238,7 @@ asmlinkage long sys_getpriority(int which, int who)
236 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); 238 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
237 break; 239 break;
238 case PRIO_USER: 240 case PRIO_USER:
239 user = current->user; 241 user = current->cred->user;
240 if (!who) 242 if (!who)
241 who = current_uid(); 243 who = current_uid();
242 else 244 else
@@ -244,7 +246,7 @@ asmlinkage long sys_getpriority(int which, int who)
244 goto out_unlock; /* No processes for this user */ 246 goto out_unlock; /* No processes for this user */
245 247
246 do_each_thread(g, p) 248 do_each_thread(g, p)
247 if (p->uid == who) { 249 if (p->cred->uid == who) {
248 niceval = 20 - task_nice(p); 250 niceval = 20 - task_nice(p);
249 if (niceval > retval) 251 if (niceval > retval)
250 retval = niceval; 252 retval = niceval;
@@ -472,8 +474,9 @@ void ctrl_alt_del(void)
472 */ 474 */
473asmlinkage long sys_setregid(gid_t rgid, gid_t egid) 475asmlinkage long sys_setregid(gid_t rgid, gid_t egid)
474{ 476{
475 int old_rgid = current->gid; 477 struct cred *cred = current->cred;
476 int old_egid = current->egid; 478 int old_rgid = cred->gid;
479 int old_egid = cred->egid;
477 int new_rgid = old_rgid; 480 int new_rgid = old_rgid;
478 int new_egid = old_egid; 481 int new_egid = old_egid;
479 int retval; 482 int retval;
@@ -484,7 +487,7 @@ asmlinkage long sys_setregid(gid_t rgid, gid_t egid)
484 487
485 if (rgid != (gid_t) -1) { 488 if (rgid != (gid_t) -1) {
486 if ((old_rgid == rgid) || 489 if ((old_rgid == rgid) ||
487 (current->egid==rgid) || 490 (cred->egid == rgid) ||
488 capable(CAP_SETGID)) 491 capable(CAP_SETGID))
489 new_rgid = rgid; 492 new_rgid = rgid;
490 else 493 else
@@ -492,8 +495,8 @@ asmlinkage long sys_setregid(gid_t rgid, gid_t egid)
492 } 495 }
493 if (egid != (gid_t) -1) { 496 if (egid != (gid_t) -1) {
494 if ((old_rgid == egid) || 497 if ((old_rgid == egid) ||
495 (current->egid == egid) || 498 (cred->egid == egid) ||
496 (current->sgid == egid) || 499 (cred->sgid == egid) ||
497 capable(CAP_SETGID)) 500 capable(CAP_SETGID))
498 new_egid = egid; 501 new_egid = egid;
499 else 502 else
@@ -505,10 +508,10 @@ asmlinkage long sys_setregid(gid_t rgid, gid_t egid)
505 } 508 }
506 if (rgid != (gid_t) -1 || 509 if (rgid != (gid_t) -1 ||
507 (egid != (gid_t) -1 && egid != old_rgid)) 510 (egid != (gid_t) -1 && egid != old_rgid))
508 current->sgid = new_egid; 511 cred->sgid = new_egid;
509 current->fsgid = new_egid; 512 cred->fsgid = new_egid;
510 current->egid = new_egid; 513 cred->egid = new_egid;
511 current->gid = new_rgid; 514 cred->gid = new_rgid;
512 key_fsgid_changed(current); 515 key_fsgid_changed(current);
513 proc_id_connector(current, PROC_EVENT_GID); 516 proc_id_connector(current, PROC_EVENT_GID);
514 return 0; 517 return 0;
@@ -521,7 +524,8 @@ asmlinkage long sys_setregid(gid_t rgid, gid_t egid)
521 */ 524 */
522asmlinkage long sys_setgid(gid_t gid) 525asmlinkage long sys_setgid(gid_t gid)
523{ 526{
524 int old_egid = current->egid; 527 struct cred *cred = current->cred;
528 int old_egid = cred->egid;
525 int retval; 529 int retval;
526 530
527 retval = security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_ID); 531 retval = security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_ID);
@@ -533,13 +537,13 @@ asmlinkage long sys_setgid(gid_t gid)
533 set_dumpable(current->mm, suid_dumpable); 537 set_dumpable(current->mm, suid_dumpable);
534 smp_wmb(); 538 smp_wmb();
535 } 539 }
536 current->gid = current->egid = current->sgid = current->fsgid = gid; 540 cred->gid = cred->egid = cred->sgid = cred->fsgid = gid;
537 } else if ((gid == current->gid) || (gid == current->sgid)) { 541 } else if ((gid == cred->gid) || (gid == cred->sgid)) {
538 if (old_egid != gid) { 542 if (old_egid != gid) {
539 set_dumpable(current->mm, suid_dumpable); 543 set_dumpable(current->mm, suid_dumpable);
540 smp_wmb(); 544 smp_wmb();
541 } 545 }
542 current->egid = current->fsgid = gid; 546 cred->egid = cred->fsgid = gid;
543 } 547 }
544 else 548 else
545 return -EPERM; 549 return -EPERM;
@@ -570,7 +574,7 @@ static int set_user(uid_t new_ruid, int dumpclear)
570 set_dumpable(current->mm, suid_dumpable); 574 set_dumpable(current->mm, suid_dumpable);
571 smp_wmb(); 575 smp_wmb();
572 } 576 }
573 current->uid = new_ruid; 577 current->cred->uid = new_ruid;
574 return 0; 578 return 0;
575} 579}
576 580
@@ -591,6 +595,7 @@ static int set_user(uid_t new_ruid, int dumpclear)
591 */ 595 */
592asmlinkage long sys_setreuid(uid_t ruid, uid_t euid) 596asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
593{ 597{
598 struct cred *cred = current->cred;
594 int old_ruid, old_euid, old_suid, new_ruid, new_euid; 599 int old_ruid, old_euid, old_suid, new_ruid, new_euid;
595 int retval; 600 int retval;
596 601
@@ -598,14 +603,14 @@ asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
598 if (retval) 603 if (retval)
599 return retval; 604 return retval;
600 605
601 new_ruid = old_ruid = current->uid; 606 new_ruid = old_ruid = cred->uid;
602 new_euid = old_euid = current->euid; 607 new_euid = old_euid = cred->euid;
603 old_suid = current->suid; 608 old_suid = cred->suid;
604 609
605 if (ruid != (uid_t) -1) { 610 if (ruid != (uid_t) -1) {
606 new_ruid = ruid; 611 new_ruid = ruid;
607 if ((old_ruid != ruid) && 612 if ((old_ruid != ruid) &&
608 (current->euid != ruid) && 613 (cred->euid != ruid) &&
609 !capable(CAP_SETUID)) 614 !capable(CAP_SETUID))
610 return -EPERM; 615 return -EPERM;
611 } 616 }
@@ -613,8 +618,8 @@ asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
613 if (euid != (uid_t) -1) { 618 if (euid != (uid_t) -1) {
614 new_euid = euid; 619 new_euid = euid;
615 if ((old_ruid != euid) && 620 if ((old_ruid != euid) &&
616 (current->euid != euid) && 621 (cred->euid != euid) &&
617 (current->suid != euid) && 622 (cred->suid != euid) &&
618 !capable(CAP_SETUID)) 623 !capable(CAP_SETUID))
619 return -EPERM; 624 return -EPERM;
620 } 625 }
@@ -626,11 +631,11 @@ asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
626 set_dumpable(current->mm, suid_dumpable); 631 set_dumpable(current->mm, suid_dumpable);
627 smp_wmb(); 632 smp_wmb();
628 } 633 }
629 current->fsuid = current->euid = new_euid; 634 cred->fsuid = cred->euid = new_euid;
630 if (ruid != (uid_t) -1 || 635 if (ruid != (uid_t) -1 ||
631 (euid != (uid_t) -1 && euid != old_ruid)) 636 (euid != (uid_t) -1 && euid != old_ruid))
632 current->suid = current->euid; 637 cred->suid = cred->euid;
633 current->fsuid = current->euid; 638 cred->fsuid = cred->euid;
634 639
635 key_fsuid_changed(current); 640 key_fsuid_changed(current);
636 proc_id_connector(current, PROC_EVENT_UID); 641 proc_id_connector(current, PROC_EVENT_UID);
@@ -653,7 +658,8 @@ asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
653 */ 658 */
654asmlinkage long sys_setuid(uid_t uid) 659asmlinkage long sys_setuid(uid_t uid)
655{ 660{
656 int old_euid = current->euid; 661 struct cred *cred = current->cred;
662 int old_euid = cred->euid;
657 int old_ruid, old_suid, new_suid; 663 int old_ruid, old_suid, new_suid;
658 int retval; 664 int retval;
659 665
@@ -661,23 +667,23 @@ asmlinkage long sys_setuid(uid_t uid)
661 if (retval) 667 if (retval)
662 return retval; 668 return retval;
663 669
664 old_ruid = current->uid; 670 old_ruid = cred->uid;
665 old_suid = current->suid; 671 old_suid = cred->suid;
666 new_suid = old_suid; 672 new_suid = old_suid;
667 673
668 if (capable(CAP_SETUID)) { 674 if (capable(CAP_SETUID)) {
669 if (uid != old_ruid && set_user(uid, old_euid != uid) < 0) 675 if (uid != old_ruid && set_user(uid, old_euid != uid) < 0)
670 return -EAGAIN; 676 return -EAGAIN;
671 new_suid = uid; 677 new_suid = uid;
672 } else if ((uid != current->uid) && (uid != new_suid)) 678 } else if ((uid != cred->uid) && (uid != new_suid))
673 return -EPERM; 679 return -EPERM;
674 680
675 if (old_euid != uid) { 681 if (old_euid != uid) {
676 set_dumpable(current->mm, suid_dumpable); 682 set_dumpable(current->mm, suid_dumpable);
677 smp_wmb(); 683 smp_wmb();
678 } 684 }
679 current->fsuid = current->euid = uid; 685 cred->fsuid = cred->euid = uid;
680 current->suid = new_suid; 686 cred->suid = new_suid;
681 687
682 key_fsuid_changed(current); 688 key_fsuid_changed(current);
683 proc_id_connector(current, PROC_EVENT_UID); 689 proc_id_connector(current, PROC_EVENT_UID);
@@ -692,9 +698,10 @@ asmlinkage long sys_setuid(uid_t uid)
692 */ 698 */
693asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid) 699asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
694{ 700{
695 int old_ruid = current->uid; 701 struct cred *cred = current->cred;
696 int old_euid = current->euid; 702 int old_ruid = cred->uid;
697 int old_suid = current->suid; 703 int old_euid = cred->euid;
704 int old_suid = cred->suid;
698 int retval; 705 int retval;
699 706
700 retval = security_task_setuid(ruid, euid, suid, LSM_SETID_RES); 707 retval = security_task_setuid(ruid, euid, suid, LSM_SETID_RES);
@@ -702,30 +709,31 @@ asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
702 return retval; 709 return retval;
703 710
704 if (!capable(CAP_SETUID)) { 711 if (!capable(CAP_SETUID)) {
705 if ((ruid != (uid_t) -1) && (ruid != current->uid) && 712 if ((ruid != (uid_t) -1) && (ruid != cred->uid) &&
706 (ruid != current->euid) && (ruid != current->suid)) 713 (ruid != cred->euid) && (ruid != cred->suid))
707 return -EPERM; 714 return -EPERM;
708 if ((euid != (uid_t) -1) && (euid != current->uid) && 715 if ((euid != (uid_t) -1) && (euid != cred->uid) &&
709 (euid != current->euid) && (euid != current->suid)) 716 (euid != cred->euid) && (euid != cred->suid))
710 return -EPERM; 717 return -EPERM;
711 if ((suid != (uid_t) -1) && (suid != current->uid) && 718 if ((suid != (uid_t) -1) && (suid != cred->uid) &&
712 (suid != current->euid) && (suid != current->suid)) 719 (suid != cred->euid) && (suid != cred->suid))
713 return -EPERM; 720 return -EPERM;
714 } 721 }
715 if (ruid != (uid_t) -1) { 722 if (ruid != (uid_t) -1) {
716 if (ruid != current->uid && set_user(ruid, euid != current->euid) < 0) 723 if (ruid != cred->uid &&
724 set_user(ruid, euid != cred->euid) < 0)
717 return -EAGAIN; 725 return -EAGAIN;
718 } 726 }
719 if (euid != (uid_t) -1) { 727 if (euid != (uid_t) -1) {
720 if (euid != current->euid) { 728 if (euid != cred->euid) {
721 set_dumpable(current->mm, suid_dumpable); 729 set_dumpable(current->mm, suid_dumpable);
722 smp_wmb(); 730 smp_wmb();
723 } 731 }
724 current->euid = euid; 732 cred->euid = euid;
725 } 733 }
726 current->fsuid = current->euid; 734 cred->fsuid = cred->euid;
727 if (suid != (uid_t) -1) 735 if (suid != (uid_t) -1)
728 current->suid = suid; 736 cred->suid = suid;
729 737
730 key_fsuid_changed(current); 738 key_fsuid_changed(current);
731 proc_id_connector(current, PROC_EVENT_UID); 739 proc_id_connector(current, PROC_EVENT_UID);
@@ -735,11 +743,12 @@ asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
735 743
736asmlinkage long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __user *suid) 744asmlinkage long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __user *suid)
737{ 745{
746 struct cred *cred = current->cred;
738 int retval; 747 int retval;
739 748
740 if (!(retval = put_user(current->uid, ruid)) && 749 if (!(retval = put_user(cred->uid, ruid)) &&
741 !(retval = put_user(current->euid, euid))) 750 !(retval = put_user(cred->euid, euid)))
742 retval = put_user(current->suid, suid); 751 retval = put_user(cred->suid, suid);
743 752
744 return retval; 753 return retval;
745} 754}
@@ -749,6 +758,7 @@ asmlinkage long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __us
749 */ 758 */
750asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid) 759asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
751{ 760{
761 struct cred *cred = current->cred;
752 int retval; 762 int retval;
753 763
754 retval = security_task_setgid(rgid, egid, sgid, LSM_SETID_RES); 764 retval = security_task_setgid(rgid, egid, sgid, LSM_SETID_RES);
@@ -756,28 +766,28 @@ asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
756 return retval; 766 return retval;
757 767
758 if (!capable(CAP_SETGID)) { 768 if (!capable(CAP_SETGID)) {
759 if ((rgid != (gid_t) -1) && (rgid != current->gid) && 769 if ((rgid != (gid_t) -1) && (rgid != cred->gid) &&
760 (rgid != current->egid) && (rgid != current->sgid)) 770 (rgid != cred->egid) && (rgid != cred->sgid))
761 return -EPERM; 771 return -EPERM;
762 if ((egid != (gid_t) -1) && (egid != current->gid) && 772 if ((egid != (gid_t) -1) && (egid != cred->gid) &&
763 (egid != current->egid) && (egid != current->sgid)) 773 (egid != cred->egid) && (egid != cred->sgid))
764 return -EPERM; 774 return -EPERM;
765 if ((sgid != (gid_t) -1) && (sgid != current->gid) && 775 if ((sgid != (gid_t) -1) && (sgid != cred->gid) &&
766 (sgid != current->egid) && (sgid != current->sgid)) 776 (sgid != cred->egid) && (sgid != cred->sgid))
767 return -EPERM; 777 return -EPERM;
768 } 778 }
769 if (egid != (gid_t) -1) { 779 if (egid != (gid_t) -1) {
770 if (egid != current->egid) { 780 if (egid != cred->egid) {
771 set_dumpable(current->mm, suid_dumpable); 781 set_dumpable(current->mm, suid_dumpable);
772 smp_wmb(); 782 smp_wmb();
773 } 783 }
774 current->egid = egid; 784 cred->egid = egid;
775 } 785 }
776 current->fsgid = current->egid; 786 cred->fsgid = cred->egid;
777 if (rgid != (gid_t) -1) 787 if (rgid != (gid_t) -1)
778 current->gid = rgid; 788 cred->gid = rgid;
779 if (sgid != (gid_t) -1) 789 if (sgid != (gid_t) -1)
780 current->sgid = sgid; 790 cred->sgid = sgid;
781 791
782 key_fsgid_changed(current); 792 key_fsgid_changed(current);
783 proc_id_connector(current, PROC_EVENT_GID); 793 proc_id_connector(current, PROC_EVENT_GID);
@@ -786,11 +796,12 @@ asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
786 796
787asmlinkage long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __user *sgid) 797asmlinkage long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __user *sgid)
788{ 798{
799 struct cred *cred = current->cred;
789 int retval; 800 int retval;
790 801
791 if (!(retval = put_user(current->gid, rgid)) && 802 if (!(retval = put_user(cred->gid, rgid)) &&
792 !(retval = put_user(current->egid, egid))) 803 !(retval = put_user(cred->egid, egid)))
793 retval = put_user(current->sgid, sgid); 804 retval = put_user(cred->sgid, sgid);
794 805
795 return retval; 806 return retval;
796} 807}
@@ -804,20 +815,21 @@ asmlinkage long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __us
804 */ 815 */
805asmlinkage long sys_setfsuid(uid_t uid) 816asmlinkage long sys_setfsuid(uid_t uid)
806{ 817{
818 struct cred *cred = current->cred;
807 int old_fsuid; 819 int old_fsuid;
808 820
809 old_fsuid = current->fsuid; 821 old_fsuid = cred->fsuid;
810 if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS)) 822 if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS))
811 return old_fsuid; 823 return old_fsuid;
812 824
813 if (uid == current->uid || uid == current->euid || 825 if (uid == cred->uid || uid == cred->euid ||
814 uid == current->suid || uid == current->fsuid || 826 uid == cred->suid || uid == cred->fsuid ||
815 capable(CAP_SETUID)) { 827 capable(CAP_SETUID)) {
816 if (uid != old_fsuid) { 828 if (uid != old_fsuid) {
817 set_dumpable(current->mm, suid_dumpable); 829 set_dumpable(current->mm, suid_dumpable);
818 smp_wmb(); 830 smp_wmb();
819 } 831 }
820 current->fsuid = uid; 832 cred->fsuid = uid;
821 } 833 }
822 834
823 key_fsuid_changed(current); 835 key_fsuid_changed(current);
@@ -833,20 +845,21 @@ asmlinkage long sys_setfsuid(uid_t uid)
833 */ 845 */
834asmlinkage long sys_setfsgid(gid_t gid) 846asmlinkage long sys_setfsgid(gid_t gid)
835{ 847{
848 struct cred *cred = current->cred;
836 int old_fsgid; 849 int old_fsgid;
837 850
838 old_fsgid = current->fsgid; 851 old_fsgid = cred->fsgid;
839 if (security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_FS)) 852 if (security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_FS))
840 return old_fsgid; 853 return old_fsgid;
841 854
842 if (gid == current->gid || gid == current->egid || 855 if (gid == cred->gid || gid == cred->egid ||
843 gid == current->sgid || gid == current->fsgid || 856 gid == cred->sgid || gid == cred->fsgid ||
844 capable(CAP_SETGID)) { 857 capable(CAP_SETGID)) {
845 if (gid != old_fsgid) { 858 if (gid != old_fsgid) {
846 set_dumpable(current->mm, suid_dumpable); 859 set_dumpable(current->mm, suid_dumpable);
847 smp_wmb(); 860 smp_wmb();
848 } 861 }
849 current->fsgid = gid; 862 cred->fsgid = gid;
850 key_fsgid_changed(current); 863 key_fsgid_changed(current);
851 proc_id_connector(current, PROC_EVENT_GID); 864 proc_id_connector(current, PROC_EVENT_GID);
852 } 865 }
@@ -1208,8 +1221,15 @@ int groups_search(struct group_info *group_info, gid_t grp)
1208 return 0; 1221 return 0;
1209} 1222}
1210 1223
1211/* validate and set current->group_info */ 1224/**
1212int set_current_groups(struct group_info *group_info) 1225 * set_groups - Change a group subscription in a security record
1226 * @sec: The security record to alter
1227 * @group_info: The group list to impose
1228 *
1229 * Validate a group subscription and, if valid, impose it upon a task security
1230 * record.
1231 */
1232int set_groups(struct cred *cred, struct group_info *group_info)
1213{ 1233{
1214 int retval; 1234 int retval;
1215 struct group_info *old_info; 1235 struct group_info *old_info;
@@ -1221,20 +1241,34 @@ int set_current_groups(struct group_info *group_info)
1221 groups_sort(group_info); 1241 groups_sort(group_info);
1222 get_group_info(group_info); 1242 get_group_info(group_info);
1223 1243
1224 task_lock(current); 1244 spin_lock(&cred->lock);
1225 old_info = current->group_info; 1245 old_info = cred->group_info;
1226 current->group_info = group_info; 1246 cred->group_info = group_info;
1227 task_unlock(current); 1247 spin_unlock(&cred->lock);
1228 1248
1229 put_group_info(old_info); 1249 put_group_info(old_info);
1230
1231 return 0; 1250 return 0;
1232} 1251}
1233 1252
1253EXPORT_SYMBOL(set_groups);
1254
1255/**
1256 * set_current_groups - Change current's group subscription
1257 * @group_info: The group list to impose
1258 *
1259 * Validate a group subscription and, if valid, impose it upon current's task
1260 * security record.
1261 */
1262int set_current_groups(struct group_info *group_info)
1263{
1264 return set_groups(current->cred, group_info);
1265}
1266
1234EXPORT_SYMBOL(set_current_groups); 1267EXPORT_SYMBOL(set_current_groups);
1235 1268
1236asmlinkage long sys_getgroups(int gidsetsize, gid_t __user *grouplist) 1269asmlinkage long sys_getgroups(int gidsetsize, gid_t __user *grouplist)
1237{ 1270{
1271 struct cred *cred = current->cred;
1238 int i = 0; 1272 int i = 0;
1239 1273
1240 /* 1274 /*
@@ -1246,13 +1280,13 @@ asmlinkage long sys_getgroups(int gidsetsize, gid_t __user *grouplist)
1246 return -EINVAL; 1280 return -EINVAL;
1247 1281
1248 /* no need to grab task_lock here; it cannot change */ 1282 /* no need to grab task_lock here; it cannot change */
1249 i = current->group_info->ngroups; 1283 i = cred->group_info->ngroups;
1250 if (gidsetsize) { 1284 if (gidsetsize) {
1251 if (i > gidsetsize) { 1285 if (i > gidsetsize) {
1252 i = -EINVAL; 1286 i = -EINVAL;
1253 goto out; 1287 goto out;
1254 } 1288 }
1255 if (groups_to_user(grouplist, current->group_info)) { 1289 if (groups_to_user(grouplist, cred->group_info)) {
1256 i = -EFAULT; 1290 i = -EFAULT;
1257 goto out; 1291 goto out;
1258 } 1292 }
@@ -1296,9 +1330,10 @@ asmlinkage long sys_setgroups(int gidsetsize, gid_t __user *grouplist)
1296 */ 1330 */
1297int in_group_p(gid_t grp) 1331int in_group_p(gid_t grp)
1298{ 1332{
1333 struct cred *cred = current->cred;
1299 int retval = 1; 1334 int retval = 1;
1300 if (grp != current->fsgid) 1335 if (grp != cred->fsgid)
1301 retval = groups_search(current->group_info, grp); 1336 retval = groups_search(cred->group_info, grp);
1302 return retval; 1337 return retval;
1303} 1338}
1304 1339
@@ -1306,9 +1341,10 @@ EXPORT_SYMBOL(in_group_p);
1306 1341
1307int in_egroup_p(gid_t grp) 1342int in_egroup_p(gid_t grp)
1308{ 1343{
1344 struct cred *cred = current->cred;
1309 int retval = 1; 1345 int retval = 1;
1310 if (grp != current->egid) 1346 if (grp != cred->egid)
1311 retval = groups_search(current->group_info, grp); 1347 retval = groups_search(cred->group_info, grp);
1312 return retval; 1348 return retval;
1313} 1349}
1314 1350
@@ -1624,7 +1660,9 @@ asmlinkage long sys_umask(int mask)
1624asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, 1660asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
1625 unsigned long arg4, unsigned long arg5) 1661 unsigned long arg4, unsigned long arg5)
1626{ 1662{
1627 long error = 0; 1663 struct task_struct *me = current;
1664 unsigned char comm[sizeof(me->comm)];
1665 long error;
1628 1666
1629 if (security_task_prctl(option, arg2, arg3, arg4, arg5, &error)) 1667 if (security_task_prctl(option, arg2, arg3, arg4, arg5, &error))
1630 return error; 1668 return error;
@@ -1635,39 +1673,41 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
1635 error = -EINVAL; 1673 error = -EINVAL;
1636 break; 1674 break;
1637 } 1675 }
1638 current->pdeath_signal = arg2; 1676 me->pdeath_signal = arg2;
1677 error = 0;
1639 break; 1678 break;
1640 case PR_GET_PDEATHSIG: 1679 case PR_GET_PDEATHSIG:
1641 error = put_user(current->pdeath_signal, (int __user *)arg2); 1680 error = put_user(me->pdeath_signal, (int __user *)arg2);
1642 break; 1681 break;
1643 case PR_GET_DUMPABLE: 1682 case PR_GET_DUMPABLE:
1644 error = get_dumpable(current->mm); 1683 error = get_dumpable(me->mm);
1645 break; 1684 break;
1646 case PR_SET_DUMPABLE: 1685 case PR_SET_DUMPABLE:
1647 if (arg2 < 0 || arg2 > 1) { 1686 if (arg2 < 0 || arg2 > 1) {
1648 error = -EINVAL; 1687 error = -EINVAL;
1649 break; 1688 break;
1650 } 1689 }
1651 set_dumpable(current->mm, arg2); 1690 set_dumpable(me->mm, arg2);
1691 error = 0;
1652 break; 1692 break;
1653 1693
1654 case PR_SET_UNALIGN: 1694 case PR_SET_UNALIGN:
1655 error = SET_UNALIGN_CTL(current, arg2); 1695 error = SET_UNALIGN_CTL(me, arg2);
1656 break; 1696 break;
1657 case PR_GET_UNALIGN: 1697 case PR_GET_UNALIGN:
1658 error = GET_UNALIGN_CTL(current, arg2); 1698 error = GET_UNALIGN_CTL(me, arg2);
1659 break; 1699 break;
1660 case PR_SET_FPEMU: 1700 case PR_SET_FPEMU:
1661 error = SET_FPEMU_CTL(current, arg2); 1701 error = SET_FPEMU_CTL(me, arg2);
1662 break; 1702 break;
1663 case PR_GET_FPEMU: 1703 case PR_GET_FPEMU:
1664 error = GET_FPEMU_CTL(current, arg2); 1704 error = GET_FPEMU_CTL(me, arg2);
1665 break; 1705 break;
1666 case PR_SET_FPEXC: 1706 case PR_SET_FPEXC:
1667 error = SET_FPEXC_CTL(current, arg2); 1707 error = SET_FPEXC_CTL(me, arg2);
1668 break; 1708 break;
1669 case PR_GET_FPEXC: 1709 case PR_GET_FPEXC:
1670 error = GET_FPEXC_CTL(current, arg2); 1710 error = GET_FPEXC_CTL(me, arg2);
1671 break; 1711 break;
1672 case PR_GET_TIMING: 1712 case PR_GET_TIMING:
1673 error = PR_TIMING_STATISTICAL; 1713 error = PR_TIMING_STATISTICAL;
@@ -1675,33 +1715,28 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
1675 case PR_SET_TIMING: 1715 case PR_SET_TIMING:
1676 if (arg2 != PR_TIMING_STATISTICAL) 1716 if (arg2 != PR_TIMING_STATISTICAL)
1677 error = -EINVAL; 1717 error = -EINVAL;
1718 else
1719 error = 0;
1678 break; 1720 break;
1679 1721
1680 case PR_SET_NAME: { 1722 case PR_SET_NAME:
1681 struct task_struct *me = current; 1723 comm[sizeof(me->comm)-1] = 0;
1682 unsigned char ncomm[sizeof(me->comm)]; 1724 if (strncpy_from_user(comm, (char __user *)arg2,
1683 1725 sizeof(me->comm) - 1) < 0)
1684 ncomm[sizeof(me->comm)-1] = 0;
1685 if (strncpy_from_user(ncomm, (char __user *)arg2,
1686 sizeof(me->comm)-1) < 0)
1687 return -EFAULT; 1726 return -EFAULT;
1688 set_task_comm(me, ncomm); 1727 set_task_comm(me, comm);
1689 return 0; 1728 return 0;
1690 } 1729 case PR_GET_NAME:
1691 case PR_GET_NAME: { 1730 get_task_comm(comm, me);
1692 struct task_struct *me = current; 1731 if (copy_to_user((char __user *)arg2, comm,
1693 unsigned char tcomm[sizeof(me->comm)]; 1732 sizeof(comm)))
1694
1695 get_task_comm(tcomm, me);
1696 if (copy_to_user((char __user *)arg2, tcomm, sizeof(tcomm)))
1697 return -EFAULT; 1733 return -EFAULT;
1698 return 0; 1734 return 0;
1699 }
1700 case PR_GET_ENDIAN: 1735 case PR_GET_ENDIAN:
1701 error = GET_ENDIAN(current, arg2); 1736 error = GET_ENDIAN(me, arg2);
1702 break; 1737 break;
1703 case PR_SET_ENDIAN: 1738 case PR_SET_ENDIAN:
1704 error = SET_ENDIAN(current, arg2); 1739 error = SET_ENDIAN(me, arg2);
1705 break; 1740 break;
1706 1741
1707 case PR_GET_SECCOMP: 1742 case PR_GET_SECCOMP:
@@ -1725,6 +1760,7 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
1725 current->default_timer_slack_ns; 1760 current->default_timer_slack_ns;
1726 else 1761 else
1727 current->timer_slack_ns = arg2; 1762 current->timer_slack_ns = arg2;
1763 error = 0;
1728 break; 1764 break;
1729 default: 1765 default:
1730 error = -EINVAL; 1766 error = -EINVAL;