aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c117
1 files changed, 60 insertions, 57 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index 763c3c17ded3..37f458e6882a 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -143,7 +143,7 @@ out:
143 return error; 143 return error;
144} 144}
145 145
146asmlinkage long sys_setpriority(int which, int who, int niceval) 146SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)
147{ 147{
148 struct task_struct *g, *p; 148 struct task_struct *g, *p;
149 struct user_struct *user; 149 struct user_struct *user;
@@ -208,7 +208,7 @@ out:
208 * has been offset by 20 (ie it returns 40..1 instead of -20..19) 208 * has been offset by 20 (ie it returns 40..1 instead of -20..19)
209 * to stay compatible. 209 * to stay compatible.
210 */ 210 */
211asmlinkage long sys_getpriority(int which, int who) 211SYSCALL_DEFINE2(getpriority, int, which, int, who)
212{ 212{
213 struct task_struct *g, *p; 213 struct task_struct *g, *p;
214 struct user_struct *user; 214 struct user_struct *user;
@@ -355,7 +355,8 @@ EXPORT_SYMBOL_GPL(kernel_power_off);
355 * 355 *
356 * reboot doesn't sync: do that yourself before calling this. 356 * reboot doesn't sync: do that yourself before calling this.
357 */ 357 */
358asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user * arg) 358SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
359 void __user *, arg)
359{ 360{
360 char buffer[256]; 361 char buffer[256];
361 362
@@ -478,7 +479,7 @@ void ctrl_alt_del(void)
478 * SMP: There are not races, the GIDs are checked only by filesystem 479 * SMP: There are not races, the GIDs are checked only by filesystem
479 * operations (as far as semantic preservation is concerned). 480 * operations (as far as semantic preservation is concerned).
480 */ 481 */
481asmlinkage long sys_setregid(gid_t rgid, gid_t egid) 482SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
482{ 483{
483 const struct cred *old; 484 const struct cred *old;
484 struct cred *new; 485 struct cred *new;
@@ -529,7 +530,7 @@ error:
529 * 530 *
530 * SMP: Same implicit races as above. 531 * SMP: Same implicit races as above.
531 */ 532 */
532asmlinkage long sys_setgid(gid_t gid) 533SYSCALL_DEFINE1(setgid, gid_t, gid)
533{ 534{
534 const struct cred *old; 535 const struct cred *old;
535 struct cred *new; 536 struct cred *new;
@@ -558,7 +559,7 @@ error:
558 abort_creds(new); 559 abort_creds(new);
559 return retval; 560 return retval;
560} 561}
561 562
562/* 563/*
563 * change the user struct in a credentials set to match the new UID 564 * change the user struct in a credentials set to match the new UID
564 */ 565 */
@@ -570,6 +571,11 @@ static int set_user(struct cred *new)
570 if (!new_user) 571 if (!new_user)
571 return -EAGAIN; 572 return -EAGAIN;
572 573
574 if (!task_can_switch_user(new_user, current)) {
575 free_uid(new_user);
576 return -EINVAL;
577 }
578
573 if (atomic_read(&new_user->processes) >= 579 if (atomic_read(&new_user->processes) >=
574 current->signal->rlim[RLIMIT_NPROC].rlim_cur && 580 current->signal->rlim[RLIMIT_NPROC].rlim_cur &&
575 new_user != INIT_USER) { 581 new_user != INIT_USER) {
@@ -597,7 +603,7 @@ static int set_user(struct cred *new)
597 * 100% compatible with BSD. A program which uses just setuid() will be 603 * 100% compatible with BSD. A program which uses just setuid() will be
598 * 100% compatible with POSIX with saved IDs. 604 * 100% compatible with POSIX with saved IDs.
599 */ 605 */
600asmlinkage long sys_setreuid(uid_t ruid, uid_t euid) 606SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
601{ 607{
602 const struct cred *old; 608 const struct cred *old;
603 struct cred *new; 609 struct cred *new;
@@ -630,10 +636,11 @@ asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
630 goto error; 636 goto error;
631 } 637 }
632 638
633 retval = -EAGAIN; 639 if (new->uid != old->uid) {
634 if (new->uid != old->uid && set_user(new) < 0) 640 retval = set_user(new);
635 goto error; 641 if (retval < 0)
636 642 goto error;
643 }
637 if (ruid != (uid_t) -1 || 644 if (ruid != (uid_t) -1 ||
638 (euid != (uid_t) -1 && euid != old->uid)) 645 (euid != (uid_t) -1 && euid != old->uid))
639 new->suid = new->euid; 646 new->suid = new->euid;
@@ -661,7 +668,7 @@ error:
661 * will allow a root program to temporarily drop privileges and be able to 668 * will allow a root program to temporarily drop privileges and be able to
662 * regain them by swapping the real and effective uid. 669 * regain them by swapping the real and effective uid.
663 */ 670 */
664asmlinkage long sys_setuid(uid_t uid) 671SYSCALL_DEFINE1(setuid, uid_t, uid)
665{ 672{
666 const struct cred *old; 673 const struct cred *old;
667 struct cred *new; 674 struct cred *new;
@@ -679,9 +686,10 @@ asmlinkage long sys_setuid(uid_t uid)
679 retval = -EPERM; 686 retval = -EPERM;
680 if (capable(CAP_SETUID)) { 687 if (capable(CAP_SETUID)) {
681 new->suid = new->uid = uid; 688 new->suid = new->uid = uid;
682 if (uid != old->uid && set_user(new) < 0) { 689 if (uid != old->uid) {
683 retval = -EAGAIN; 690 retval = set_user(new);
684 goto error; 691 if (retval < 0)
692 goto error;
685 } 693 }
686 } else if (uid != old->uid && uid != new->suid) { 694 } else if (uid != old->uid && uid != new->suid) {
687 goto error; 695 goto error;
@@ -705,7 +713,7 @@ error:
705 * This function implements a generic ability to update ruid, euid, 713 * This function implements a generic ability to update ruid, euid,
706 * and suid. This allows you to implement the 4.4 compatible seteuid(). 714 * and suid. This allows you to implement the 4.4 compatible seteuid().
707 */ 715 */
708asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid) 716SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
709{ 717{
710 const struct cred *old; 718 const struct cred *old;
711 struct cred *new; 719 struct cred *new;
@@ -733,11 +741,13 @@ asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
733 goto error; 741 goto error;
734 } 742 }
735 743
736 retval = -EAGAIN;
737 if (ruid != (uid_t) -1) { 744 if (ruid != (uid_t) -1) {
738 new->uid = ruid; 745 new->uid = ruid;
739 if (ruid != old->uid && set_user(new) < 0) 746 if (ruid != old->uid) {
740 goto error; 747 retval = set_user(new);
748 if (retval < 0)
749 goto error;
750 }
741 } 751 }
742 if (euid != (uid_t) -1) 752 if (euid != (uid_t) -1)
743 new->euid = euid; 753 new->euid = euid;
@@ -756,7 +766,7 @@ error:
756 return retval; 766 return retval;
757} 767}
758 768
759asmlinkage long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __user *suid) 769SYSCALL_DEFINE3(getresuid, uid_t __user *, ruid, uid_t __user *, euid, uid_t __user *, suid)
760{ 770{
761 const struct cred *cred = current_cred(); 771 const struct cred *cred = current_cred();
762 int retval; 772 int retval;
@@ -771,7 +781,7 @@ asmlinkage long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __us
771/* 781/*
772 * Same as above, but for rgid, egid, sgid. 782 * Same as above, but for rgid, egid, sgid.
773 */ 783 */
774asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid) 784SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
775{ 785{
776 const struct cred *old; 786 const struct cred *old;
777 struct cred *new; 787 struct cred *new;
@@ -814,7 +824,7 @@ error:
814 return retval; 824 return retval;
815} 825}
816 826
817asmlinkage long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __user *sgid) 827SYSCALL_DEFINE3(getresgid, gid_t __user *, rgid, gid_t __user *, egid, gid_t __user *, sgid)
818{ 828{
819 const struct cred *cred = current_cred(); 829 const struct cred *cred = current_cred();
820 int retval; 830 int retval;
@@ -833,7 +843,7 @@ asmlinkage long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __us
833 * whatever uid it wants to). It normally shadows "euid", except when 843 * whatever uid it wants to). It normally shadows "euid", except when
834 * explicitly set by setfsuid() or for access.. 844 * explicitly set by setfsuid() or for access..
835 */ 845 */
836asmlinkage long sys_setfsuid(uid_t uid) 846SYSCALL_DEFINE1(setfsuid, uid_t, uid)
837{ 847{
838 const struct cred *old; 848 const struct cred *old;
839 struct cred *new; 849 struct cred *new;
@@ -870,7 +880,7 @@ change_okay:
870/* 880/*
871 * Samma på svenska.. 881 * Samma på svenska..
872 */ 882 */
873asmlinkage long sys_setfsgid(gid_t gid) 883SYSCALL_DEFINE1(setfsgid, gid_t, gid)
874{ 884{
875 const struct cred *old; 885 const struct cred *old;
876 struct cred *new; 886 struct cred *new;
@@ -919,7 +929,7 @@ void do_sys_times(struct tms *tms)
919 tms->tms_cstime = cputime_to_clock_t(cstime); 929 tms->tms_cstime = cputime_to_clock_t(cstime);
920} 930}
921 931
922asmlinkage long sys_times(struct tms __user * tbuf) 932SYSCALL_DEFINE1(times, struct tms __user *, tbuf)
923{ 933{
924 if (tbuf) { 934 if (tbuf) {
925 struct tms tmp; 935 struct tms tmp;
@@ -944,7 +954,7 @@ asmlinkage long sys_times(struct tms __user * tbuf)
944 * Auch. Had to add the 'did_exec' flag to conform completely to POSIX. 954 * Auch. Had to add the 'did_exec' flag to conform completely to POSIX.
945 * LBT 04.03.94 955 * LBT 04.03.94
946 */ 956 */
947asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) 957SYSCALL_DEFINE2(setpgid, pid_t, pid, pid_t, pgid)
948{ 958{
949 struct task_struct *p; 959 struct task_struct *p;
950 struct task_struct *group_leader = current->group_leader; 960 struct task_struct *group_leader = current->group_leader;
@@ -1015,7 +1025,7 @@ out:
1015 return err; 1025 return err;
1016} 1026}
1017 1027
1018asmlinkage long sys_getpgid(pid_t pid) 1028SYSCALL_DEFINE1(getpgid, pid_t, pid)
1019{ 1029{
1020 struct task_struct *p; 1030 struct task_struct *p;
1021 struct pid *grp; 1031 struct pid *grp;
@@ -1045,14 +1055,14 @@ out:
1045 1055
1046#ifdef __ARCH_WANT_SYS_GETPGRP 1056#ifdef __ARCH_WANT_SYS_GETPGRP
1047 1057
1048asmlinkage long sys_getpgrp(void) 1058SYSCALL_DEFINE0(getpgrp)
1049{ 1059{
1050 return sys_getpgid(0); 1060 return sys_getpgid(0);
1051} 1061}
1052 1062
1053#endif 1063#endif
1054 1064
1055asmlinkage long sys_getsid(pid_t pid) 1065SYSCALL_DEFINE1(getsid, pid_t, pid)
1056{ 1066{
1057 struct task_struct *p; 1067 struct task_struct *p;
1058 struct pid *sid; 1068 struct pid *sid;
@@ -1080,7 +1090,7 @@ out:
1080 return retval; 1090 return retval;
1081} 1091}
1082 1092
1083asmlinkage long sys_setsid(void) 1093SYSCALL_DEFINE0(setsid)
1084{ 1094{
1085 struct task_struct *group_leader = current->group_leader; 1095 struct task_struct *group_leader = current->group_leader;
1086 struct pid *sid = task_pid(group_leader); 1096 struct pid *sid = task_pid(group_leader);
@@ -1311,7 +1321,7 @@ int set_current_groups(struct group_info *group_info)
1311 1321
1312EXPORT_SYMBOL(set_current_groups); 1322EXPORT_SYMBOL(set_current_groups);
1313 1323
1314asmlinkage long sys_getgroups(int gidsetsize, gid_t __user *grouplist) 1324SYSCALL_DEFINE2(getgroups, int, gidsetsize, gid_t __user *, grouplist)
1315{ 1325{
1316 const struct cred *cred = current_cred(); 1326 const struct cred *cred = current_cred();
1317 int i; 1327 int i;
@@ -1340,7 +1350,7 @@ out:
1340 * without another task interfering. 1350 * without another task interfering.
1341 */ 1351 */
1342 1352
1343asmlinkage long sys_setgroups(int gidsetsize, gid_t __user *grouplist) 1353SYSCALL_DEFINE2(setgroups, int, gidsetsize, gid_t __user *, grouplist)
1344{ 1354{
1345 struct group_info *group_info; 1355 struct group_info *group_info;
1346 int retval; 1356 int retval;
@@ -1394,7 +1404,7 @@ EXPORT_SYMBOL(in_egroup_p);
1394 1404
1395DECLARE_RWSEM(uts_sem); 1405DECLARE_RWSEM(uts_sem);
1396 1406
1397asmlinkage long sys_newuname(struct new_utsname __user * name) 1407SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
1398{ 1408{
1399 int errno = 0; 1409 int errno = 0;
1400 1410
@@ -1405,7 +1415,7 @@ asmlinkage long sys_newuname(struct new_utsname __user * name)
1405 return errno; 1415 return errno;
1406} 1416}
1407 1417
1408asmlinkage long sys_sethostname(char __user *name, int len) 1418SYSCALL_DEFINE2(sethostname, char __user *, name, int, len)
1409{ 1419{
1410 int errno; 1420 int errno;
1411 char tmp[__NEW_UTS_LEN]; 1421 char tmp[__NEW_UTS_LEN];
@@ -1429,7 +1439,7 @@ asmlinkage long sys_sethostname(char __user *name, int len)
1429 1439
1430#ifdef __ARCH_WANT_SYS_GETHOSTNAME 1440#ifdef __ARCH_WANT_SYS_GETHOSTNAME
1431 1441
1432asmlinkage long sys_gethostname(char __user *name, int len) 1442SYSCALL_DEFINE2(gethostname, char __user *, name, int, len)
1433{ 1443{
1434 int i, errno; 1444 int i, errno;
1435 struct new_utsname *u; 1445 struct new_utsname *u;
@@ -1454,7 +1464,7 @@ asmlinkage long sys_gethostname(char __user *name, int len)
1454 * Only setdomainname; getdomainname can be implemented by calling 1464 * Only setdomainname; getdomainname can be implemented by calling
1455 * uname() 1465 * uname()
1456 */ 1466 */
1457asmlinkage long sys_setdomainname(char __user *name, int len) 1467SYSCALL_DEFINE2(setdomainname, char __user *, name, int, len)
1458{ 1468{
1459 int errno; 1469 int errno;
1460 char tmp[__NEW_UTS_LEN]; 1470 char tmp[__NEW_UTS_LEN];
@@ -1477,7 +1487,7 @@ asmlinkage long sys_setdomainname(char __user *name, int len)
1477 return errno; 1487 return errno;
1478} 1488}
1479 1489
1480asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit __user *rlim) 1490SYSCALL_DEFINE2(getrlimit, unsigned int, resource, struct rlimit __user *, rlim)
1481{ 1491{
1482 if (resource >= RLIM_NLIMITS) 1492 if (resource >= RLIM_NLIMITS)
1483 return -EINVAL; 1493 return -EINVAL;
@@ -1496,7 +1506,8 @@ asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit __user *rlim)
1496 * Back compatibility for getrlimit. Needed for some apps. 1506 * Back compatibility for getrlimit. Needed for some apps.
1497 */ 1507 */
1498 1508
1499asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *rlim) 1509SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,
1510 struct rlimit __user *, rlim)
1500{ 1511{
1501 struct rlimit x; 1512 struct rlimit x;
1502 if (resource >= RLIM_NLIMITS) 1513 if (resource >= RLIM_NLIMITS)
@@ -1514,7 +1525,7 @@ asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *r
1514 1525
1515#endif 1526#endif
1516 1527
1517asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim) 1528SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim)
1518{ 1529{
1519 struct rlimit new_rlim, *old_rlim; 1530 struct rlimit new_rlim, *old_rlim;
1520 int retval; 1531 int retval;
@@ -1523,22 +1534,14 @@ asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim)
1523 return -EINVAL; 1534 return -EINVAL;
1524 if (copy_from_user(&new_rlim, rlim, sizeof(*rlim))) 1535 if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
1525 return -EFAULT; 1536 return -EFAULT;
1537 if (new_rlim.rlim_cur > new_rlim.rlim_max)
1538 return -EINVAL;
1526 old_rlim = current->signal->rlim + resource; 1539 old_rlim = current->signal->rlim + resource;
1527 if ((new_rlim.rlim_max > old_rlim->rlim_max) && 1540 if ((new_rlim.rlim_max > old_rlim->rlim_max) &&
1528 !capable(CAP_SYS_RESOURCE)) 1541 !capable(CAP_SYS_RESOURCE))
1529 return -EPERM; 1542 return -EPERM;
1530 1543 if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open)
1531 if (resource == RLIMIT_NOFILE) { 1544 return -EPERM;
1532 if (new_rlim.rlim_max == RLIM_INFINITY)
1533 new_rlim.rlim_max = sysctl_nr_open;
1534 if (new_rlim.rlim_cur == RLIM_INFINITY)
1535 new_rlim.rlim_cur = sysctl_nr_open;
1536 if (new_rlim.rlim_max > sysctl_nr_open)
1537 return -EPERM;
1538 }
1539
1540 if (new_rlim.rlim_cur > new_rlim.rlim_max)
1541 return -EINVAL;
1542 1545
1543 retval = security_task_setrlimit(resource, &new_rlim); 1546 retval = security_task_setrlimit(resource, &new_rlim);
1544 if (retval) 1547 if (retval)
@@ -1687,7 +1690,7 @@ int getrusage(struct task_struct *p, int who, struct rusage __user *ru)
1687 return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0; 1690 return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0;
1688} 1691}
1689 1692
1690asmlinkage long sys_getrusage(int who, struct rusage __user *ru) 1693SYSCALL_DEFINE2(getrusage, int, who, struct rusage __user *, ru)
1691{ 1694{
1692 if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN && 1695 if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN &&
1693 who != RUSAGE_THREAD) 1696 who != RUSAGE_THREAD)
@@ -1695,14 +1698,14 @@ asmlinkage long sys_getrusage(int who, struct rusage __user *ru)
1695 return getrusage(current, who, ru); 1698 return getrusage(current, who, ru);
1696} 1699}
1697 1700
1698asmlinkage long sys_umask(int mask) 1701SYSCALL_DEFINE1(umask, int, mask)
1699{ 1702{
1700 mask = xchg(&current->fs->umask, mask & S_IRWXUGO); 1703 mask = xchg(&current->fs->umask, mask & S_IRWXUGO);
1701 return mask; 1704 return mask;
1702} 1705}
1703 1706
1704asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, 1707SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
1705 unsigned long arg4, unsigned long arg5) 1708 unsigned long, arg4, unsigned long, arg5)
1706{ 1709{
1707 struct task_struct *me = current; 1710 struct task_struct *me = current;
1708 unsigned char comm[sizeof(me->comm)]; 1711 unsigned char comm[sizeof(me->comm)];
@@ -1815,8 +1818,8 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
1815 return error; 1818 return error;
1816} 1819}
1817 1820
1818asmlinkage long sys_getcpu(unsigned __user *cpup, unsigned __user *nodep, 1821SYSCALL_DEFINE3(getcpu, unsigned __user *, cpup, unsigned __user *, nodep,
1819 struct getcpu_cache __user *unused) 1822 struct getcpu_cache __user *, unused)
1820{ 1823{
1821 int err = 0; 1824 int err = 0;
1822 int cpu = raw_smp_processor_id(); 1825 int cpu = raw_smp_processor_id();