diff options
Diffstat (limited to 'kernel/sys.c')
-rw-r--r-- | kernel/sys.c | 90 |
1 files changed, 44 insertions, 46 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index d356d79e84ac..f145c415bc16 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/task_io_accounting_ops.h> | 33 | #include <linux/task_io_accounting_ops.h> |
34 | #include <linux/seccomp.h> | 34 | #include <linux/seccomp.h> |
35 | #include <linux/cpu.h> | 35 | #include <linux/cpu.h> |
36 | #include <linux/ptrace.h> | ||
36 | 37 | ||
37 | #include <linux/compat.h> | 38 | #include <linux/compat.h> |
38 | #include <linux/syscalls.h> | 39 | #include <linux/syscalls.h> |
@@ -142,7 +143,7 @@ out: | |||
142 | return error; | 143 | return error; |
143 | } | 144 | } |
144 | 145 | ||
145 | asmlinkage long sys_setpriority(int which, int who, int niceval) | 146 | SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval) |
146 | { | 147 | { |
147 | struct task_struct *g, *p; | 148 | struct task_struct *g, *p; |
148 | struct user_struct *user; | 149 | struct user_struct *user; |
@@ -207,7 +208,7 @@ out: | |||
207 | * 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) |
208 | * to stay compatible. | 209 | * to stay compatible. |
209 | */ | 210 | */ |
210 | asmlinkage long sys_getpriority(int which, int who) | 211 | SYSCALL_DEFINE2(getpriority, int, which, int, who) |
211 | { | 212 | { |
212 | struct task_struct *g, *p; | 213 | struct task_struct *g, *p; |
213 | struct user_struct *user; | 214 | struct user_struct *user; |
@@ -354,7 +355,8 @@ EXPORT_SYMBOL_GPL(kernel_power_off); | |||
354 | * | 355 | * |
355 | * reboot doesn't sync: do that yourself before calling this. | 356 | * reboot doesn't sync: do that yourself before calling this. |
356 | */ | 357 | */ |
357 | asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user * arg) | 358 | SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, |
359 | void __user *, arg) | ||
358 | { | 360 | { |
359 | char buffer[256]; | 361 | char buffer[256]; |
360 | 362 | ||
@@ -477,7 +479,7 @@ void ctrl_alt_del(void) | |||
477 | * 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 |
478 | * operations (as far as semantic preservation is concerned). | 480 | * operations (as far as semantic preservation is concerned). |
479 | */ | 481 | */ |
480 | asmlinkage long sys_setregid(gid_t rgid, gid_t egid) | 482 | SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid) |
481 | { | 483 | { |
482 | const struct cred *old; | 484 | const struct cred *old; |
483 | struct cred *new; | 485 | struct cred *new; |
@@ -528,7 +530,7 @@ error: | |||
528 | * | 530 | * |
529 | * SMP: Same implicit races as above. | 531 | * SMP: Same implicit races as above. |
530 | */ | 532 | */ |
531 | asmlinkage long sys_setgid(gid_t gid) | 533 | SYSCALL_DEFINE1(setgid, gid_t, gid) |
532 | { | 534 | { |
533 | const struct cred *old; | 535 | const struct cred *old; |
534 | struct cred *new; | 536 | struct cred *new; |
@@ -596,7 +598,7 @@ static int set_user(struct cred *new) | |||
596 | * 100% compatible with BSD. A program which uses just setuid() will be | 598 | * 100% compatible with BSD. A program which uses just setuid() will be |
597 | * 100% compatible with POSIX with saved IDs. | 599 | * 100% compatible with POSIX with saved IDs. |
598 | */ | 600 | */ |
599 | asmlinkage long sys_setreuid(uid_t ruid, uid_t euid) | 601 | SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid) |
600 | { | 602 | { |
601 | const struct cred *old; | 603 | const struct cred *old; |
602 | struct cred *new; | 604 | struct cred *new; |
@@ -660,7 +662,7 @@ error: | |||
660 | * will allow a root program to temporarily drop privileges and be able to | 662 | * will allow a root program to temporarily drop privileges and be able to |
661 | * regain them by swapping the real and effective uid. | 663 | * regain them by swapping the real and effective uid. |
662 | */ | 664 | */ |
663 | asmlinkage long sys_setuid(uid_t uid) | 665 | SYSCALL_DEFINE1(setuid, uid_t, uid) |
664 | { | 666 | { |
665 | const struct cred *old; | 667 | const struct cred *old; |
666 | struct cred *new; | 668 | struct cred *new; |
@@ -704,7 +706,7 @@ error: | |||
704 | * This function implements a generic ability to update ruid, euid, | 706 | * This function implements a generic ability to update ruid, euid, |
705 | * and suid. This allows you to implement the 4.4 compatible seteuid(). | 707 | * and suid. This allows you to implement the 4.4 compatible seteuid(). |
706 | */ | 708 | */ |
707 | asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid) | 709 | SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid) |
708 | { | 710 | { |
709 | const struct cred *old; | 711 | const struct cred *old; |
710 | struct cred *new; | 712 | struct cred *new; |
@@ -755,7 +757,7 @@ error: | |||
755 | return retval; | 757 | return retval; |
756 | } | 758 | } |
757 | 759 | ||
758 | asmlinkage long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __user *suid) | 760 | SYSCALL_DEFINE3(getresuid, uid_t __user *, ruid, uid_t __user *, euid, uid_t __user *, suid) |
759 | { | 761 | { |
760 | const struct cred *cred = current_cred(); | 762 | const struct cred *cred = current_cred(); |
761 | int retval; | 763 | int retval; |
@@ -770,7 +772,7 @@ asmlinkage long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __us | |||
770 | /* | 772 | /* |
771 | * Same as above, but for rgid, egid, sgid. | 773 | * Same as above, but for rgid, egid, sgid. |
772 | */ | 774 | */ |
773 | asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid) | 775 | SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid) |
774 | { | 776 | { |
775 | const struct cred *old; | 777 | const struct cred *old; |
776 | struct cred *new; | 778 | struct cred *new; |
@@ -813,7 +815,7 @@ error: | |||
813 | return retval; | 815 | return retval; |
814 | } | 816 | } |
815 | 817 | ||
816 | asmlinkage long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __user *sgid) | 818 | SYSCALL_DEFINE3(getresgid, gid_t __user *, rgid, gid_t __user *, egid, gid_t __user *, sgid) |
817 | { | 819 | { |
818 | const struct cred *cred = current_cred(); | 820 | const struct cred *cred = current_cred(); |
819 | int retval; | 821 | int retval; |
@@ -832,7 +834,7 @@ asmlinkage long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __us | |||
832 | * whatever uid it wants to). It normally shadows "euid", except when | 834 | * whatever uid it wants to). It normally shadows "euid", except when |
833 | * explicitly set by setfsuid() or for access.. | 835 | * explicitly set by setfsuid() or for access.. |
834 | */ | 836 | */ |
835 | asmlinkage long sys_setfsuid(uid_t uid) | 837 | SYSCALL_DEFINE1(setfsuid, uid_t, uid) |
836 | { | 838 | { |
837 | const struct cred *old; | 839 | const struct cred *old; |
838 | struct cred *new; | 840 | struct cred *new; |
@@ -869,7 +871,7 @@ change_okay: | |||
869 | /* | 871 | /* |
870 | * Samma på svenska.. | 872 | * Samma på svenska.. |
871 | */ | 873 | */ |
872 | asmlinkage long sys_setfsgid(gid_t gid) | 874 | SYSCALL_DEFINE1(setfsgid, gid_t, gid) |
873 | { | 875 | { |
874 | const struct cred *old; | 876 | const struct cred *old; |
875 | struct cred *new; | 877 | struct cred *new; |
@@ -918,7 +920,7 @@ void do_sys_times(struct tms *tms) | |||
918 | tms->tms_cstime = cputime_to_clock_t(cstime); | 920 | tms->tms_cstime = cputime_to_clock_t(cstime); |
919 | } | 921 | } |
920 | 922 | ||
921 | asmlinkage long sys_times(struct tms __user * tbuf) | 923 | SYSCALL_DEFINE1(times, struct tms __user *, tbuf) |
922 | { | 924 | { |
923 | if (tbuf) { | 925 | if (tbuf) { |
924 | struct tms tmp; | 926 | struct tms tmp; |
@@ -927,6 +929,7 @@ asmlinkage long sys_times(struct tms __user * tbuf) | |||
927 | if (copy_to_user(tbuf, &tmp, sizeof(struct tms))) | 929 | if (copy_to_user(tbuf, &tmp, sizeof(struct tms))) |
928 | return -EFAULT; | 930 | return -EFAULT; |
929 | } | 931 | } |
932 | force_successful_syscall_return(); | ||
930 | return (long) jiffies_64_to_clock_t(get_jiffies_64()); | 933 | return (long) jiffies_64_to_clock_t(get_jiffies_64()); |
931 | } | 934 | } |
932 | 935 | ||
@@ -942,7 +945,7 @@ asmlinkage long sys_times(struct tms __user * tbuf) | |||
942 | * Auch. Had to add the 'did_exec' flag to conform completely to POSIX. | 945 | * Auch. Had to add the 'did_exec' flag to conform completely to POSIX. |
943 | * LBT 04.03.94 | 946 | * LBT 04.03.94 |
944 | */ | 947 | */ |
945 | asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) | 948 | SYSCALL_DEFINE2(setpgid, pid_t, pid, pid_t, pgid) |
946 | { | 949 | { |
947 | struct task_struct *p; | 950 | struct task_struct *p; |
948 | struct task_struct *group_leader = current->group_leader; | 951 | struct task_struct *group_leader = current->group_leader; |
@@ -1013,7 +1016,7 @@ out: | |||
1013 | return err; | 1016 | return err; |
1014 | } | 1017 | } |
1015 | 1018 | ||
1016 | asmlinkage long sys_getpgid(pid_t pid) | 1019 | SYSCALL_DEFINE1(getpgid, pid_t, pid) |
1017 | { | 1020 | { |
1018 | struct task_struct *p; | 1021 | struct task_struct *p; |
1019 | struct pid *grp; | 1022 | struct pid *grp; |
@@ -1043,14 +1046,14 @@ out: | |||
1043 | 1046 | ||
1044 | #ifdef __ARCH_WANT_SYS_GETPGRP | 1047 | #ifdef __ARCH_WANT_SYS_GETPGRP |
1045 | 1048 | ||
1046 | asmlinkage long sys_getpgrp(void) | 1049 | SYSCALL_DEFINE0(getpgrp) |
1047 | { | 1050 | { |
1048 | return sys_getpgid(0); | 1051 | return sys_getpgid(0); |
1049 | } | 1052 | } |
1050 | 1053 | ||
1051 | #endif | 1054 | #endif |
1052 | 1055 | ||
1053 | asmlinkage long sys_getsid(pid_t pid) | 1056 | SYSCALL_DEFINE1(getsid, pid_t, pid) |
1054 | { | 1057 | { |
1055 | struct task_struct *p; | 1058 | struct task_struct *p; |
1056 | struct pid *sid; | 1059 | struct pid *sid; |
@@ -1078,7 +1081,7 @@ out: | |||
1078 | return retval; | 1081 | return retval; |
1079 | } | 1082 | } |
1080 | 1083 | ||
1081 | asmlinkage long sys_setsid(void) | 1084 | SYSCALL_DEFINE0(setsid) |
1082 | { | 1085 | { |
1083 | struct task_struct *group_leader = current->group_leader; | 1086 | struct task_struct *group_leader = current->group_leader; |
1084 | struct pid *sid = task_pid(group_leader); | 1087 | struct pid *sid = task_pid(group_leader); |
@@ -1309,7 +1312,7 @@ int set_current_groups(struct group_info *group_info) | |||
1309 | 1312 | ||
1310 | EXPORT_SYMBOL(set_current_groups); | 1313 | EXPORT_SYMBOL(set_current_groups); |
1311 | 1314 | ||
1312 | asmlinkage long sys_getgroups(int gidsetsize, gid_t __user *grouplist) | 1315 | SYSCALL_DEFINE2(getgroups, int, gidsetsize, gid_t __user *, grouplist) |
1313 | { | 1316 | { |
1314 | const struct cred *cred = current_cred(); | 1317 | const struct cred *cred = current_cred(); |
1315 | int i; | 1318 | int i; |
@@ -1338,7 +1341,7 @@ out: | |||
1338 | * without another task interfering. | 1341 | * without another task interfering. |
1339 | */ | 1342 | */ |
1340 | 1343 | ||
1341 | asmlinkage long sys_setgroups(int gidsetsize, gid_t __user *grouplist) | 1344 | SYSCALL_DEFINE2(setgroups, int, gidsetsize, gid_t __user *, grouplist) |
1342 | { | 1345 | { |
1343 | struct group_info *group_info; | 1346 | struct group_info *group_info; |
1344 | int retval; | 1347 | int retval; |
@@ -1392,7 +1395,7 @@ EXPORT_SYMBOL(in_egroup_p); | |||
1392 | 1395 | ||
1393 | DECLARE_RWSEM(uts_sem); | 1396 | DECLARE_RWSEM(uts_sem); |
1394 | 1397 | ||
1395 | asmlinkage long sys_newuname(struct new_utsname __user * name) | 1398 | SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name) |
1396 | { | 1399 | { |
1397 | int errno = 0; | 1400 | int errno = 0; |
1398 | 1401 | ||
@@ -1403,7 +1406,7 @@ asmlinkage long sys_newuname(struct new_utsname __user * name) | |||
1403 | return errno; | 1406 | return errno; |
1404 | } | 1407 | } |
1405 | 1408 | ||
1406 | asmlinkage long sys_sethostname(char __user *name, int len) | 1409 | SYSCALL_DEFINE2(sethostname, char __user *, name, int, len) |
1407 | { | 1410 | { |
1408 | int errno; | 1411 | int errno; |
1409 | char tmp[__NEW_UTS_LEN]; | 1412 | char tmp[__NEW_UTS_LEN]; |
@@ -1427,7 +1430,7 @@ asmlinkage long sys_sethostname(char __user *name, int len) | |||
1427 | 1430 | ||
1428 | #ifdef __ARCH_WANT_SYS_GETHOSTNAME | 1431 | #ifdef __ARCH_WANT_SYS_GETHOSTNAME |
1429 | 1432 | ||
1430 | asmlinkage long sys_gethostname(char __user *name, int len) | 1433 | SYSCALL_DEFINE2(gethostname, char __user *, name, int, len) |
1431 | { | 1434 | { |
1432 | int i, errno; | 1435 | int i, errno; |
1433 | struct new_utsname *u; | 1436 | struct new_utsname *u; |
@@ -1452,7 +1455,7 @@ asmlinkage long sys_gethostname(char __user *name, int len) | |||
1452 | * Only setdomainname; getdomainname can be implemented by calling | 1455 | * Only setdomainname; getdomainname can be implemented by calling |
1453 | * uname() | 1456 | * uname() |
1454 | */ | 1457 | */ |
1455 | asmlinkage long sys_setdomainname(char __user *name, int len) | 1458 | SYSCALL_DEFINE2(setdomainname, char __user *, name, int, len) |
1456 | { | 1459 | { |
1457 | int errno; | 1460 | int errno; |
1458 | char tmp[__NEW_UTS_LEN]; | 1461 | char tmp[__NEW_UTS_LEN]; |
@@ -1475,7 +1478,7 @@ asmlinkage long sys_setdomainname(char __user *name, int len) | |||
1475 | return errno; | 1478 | return errno; |
1476 | } | 1479 | } |
1477 | 1480 | ||
1478 | asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit __user *rlim) | 1481 | SYSCALL_DEFINE2(getrlimit, unsigned int, resource, struct rlimit __user *, rlim) |
1479 | { | 1482 | { |
1480 | if (resource >= RLIM_NLIMITS) | 1483 | if (resource >= RLIM_NLIMITS) |
1481 | return -EINVAL; | 1484 | return -EINVAL; |
@@ -1494,7 +1497,8 @@ asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit __user *rlim) | |||
1494 | * Back compatibility for getrlimit. Needed for some apps. | 1497 | * Back compatibility for getrlimit. Needed for some apps. |
1495 | */ | 1498 | */ |
1496 | 1499 | ||
1497 | asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *rlim) | 1500 | SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource, |
1501 | struct rlimit __user *, rlim) | ||
1498 | { | 1502 | { |
1499 | struct rlimit x; | 1503 | struct rlimit x; |
1500 | if (resource >= RLIM_NLIMITS) | 1504 | if (resource >= RLIM_NLIMITS) |
@@ -1512,7 +1516,7 @@ asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *r | |||
1512 | 1516 | ||
1513 | #endif | 1517 | #endif |
1514 | 1518 | ||
1515 | asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim) | 1519 | SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim) |
1516 | { | 1520 | { |
1517 | struct rlimit new_rlim, *old_rlim; | 1521 | struct rlimit new_rlim, *old_rlim; |
1518 | int retval; | 1522 | int retval; |
@@ -1521,22 +1525,14 @@ asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim) | |||
1521 | return -EINVAL; | 1525 | return -EINVAL; |
1522 | if (copy_from_user(&new_rlim, rlim, sizeof(*rlim))) | 1526 | if (copy_from_user(&new_rlim, rlim, sizeof(*rlim))) |
1523 | return -EFAULT; | 1527 | return -EFAULT; |
1528 | if (new_rlim.rlim_cur > new_rlim.rlim_max) | ||
1529 | return -EINVAL; | ||
1524 | old_rlim = current->signal->rlim + resource; | 1530 | old_rlim = current->signal->rlim + resource; |
1525 | if ((new_rlim.rlim_max > old_rlim->rlim_max) && | 1531 | if ((new_rlim.rlim_max > old_rlim->rlim_max) && |
1526 | !capable(CAP_SYS_RESOURCE)) | 1532 | !capable(CAP_SYS_RESOURCE)) |
1527 | return -EPERM; | 1533 | return -EPERM; |
1528 | 1534 | if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open) | |
1529 | if (resource == RLIMIT_NOFILE) { | 1535 | return -EPERM; |
1530 | if (new_rlim.rlim_max == RLIM_INFINITY) | ||
1531 | new_rlim.rlim_max = sysctl_nr_open; | ||
1532 | if (new_rlim.rlim_cur == RLIM_INFINITY) | ||
1533 | new_rlim.rlim_cur = sysctl_nr_open; | ||
1534 | if (new_rlim.rlim_max > sysctl_nr_open) | ||
1535 | return -EPERM; | ||
1536 | } | ||
1537 | |||
1538 | if (new_rlim.rlim_cur > new_rlim.rlim_max) | ||
1539 | return -EINVAL; | ||
1540 | 1536 | ||
1541 | retval = security_task_setrlimit(resource, &new_rlim); | 1537 | retval = security_task_setrlimit(resource, &new_rlim); |
1542 | if (retval) | 1538 | if (retval) |
@@ -1627,6 +1623,8 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r) | |||
1627 | utime = stime = cputime_zero; | 1623 | utime = stime = cputime_zero; |
1628 | 1624 | ||
1629 | if (who == RUSAGE_THREAD) { | 1625 | if (who == RUSAGE_THREAD) { |
1626 | utime = task_utime(current); | ||
1627 | stime = task_stime(current); | ||
1630 | accumulate_thread_rusage(p, r); | 1628 | accumulate_thread_rusage(p, r); |
1631 | goto out; | 1629 | goto out; |
1632 | } | 1630 | } |
@@ -1683,7 +1681,7 @@ int getrusage(struct task_struct *p, int who, struct rusage __user *ru) | |||
1683 | return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0; | 1681 | return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0; |
1684 | } | 1682 | } |
1685 | 1683 | ||
1686 | asmlinkage long sys_getrusage(int who, struct rusage __user *ru) | 1684 | SYSCALL_DEFINE2(getrusage, int, who, struct rusage __user *, ru) |
1687 | { | 1685 | { |
1688 | if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN && | 1686 | if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN && |
1689 | who != RUSAGE_THREAD) | 1687 | who != RUSAGE_THREAD) |
@@ -1691,14 +1689,14 @@ asmlinkage long sys_getrusage(int who, struct rusage __user *ru) | |||
1691 | return getrusage(current, who, ru); | 1689 | return getrusage(current, who, ru); |
1692 | } | 1690 | } |
1693 | 1691 | ||
1694 | asmlinkage long sys_umask(int mask) | 1692 | SYSCALL_DEFINE1(umask, int, mask) |
1695 | { | 1693 | { |
1696 | mask = xchg(¤t->fs->umask, mask & S_IRWXUGO); | 1694 | mask = xchg(¤t->fs->umask, mask & S_IRWXUGO); |
1697 | return mask; | 1695 | return mask; |
1698 | } | 1696 | } |
1699 | 1697 | ||
1700 | asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, | 1698 | SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, |
1701 | unsigned long arg4, unsigned long arg5) | 1699 | unsigned long, arg4, unsigned long, arg5) |
1702 | { | 1700 | { |
1703 | struct task_struct *me = current; | 1701 | struct task_struct *me = current; |
1704 | unsigned char comm[sizeof(me->comm)]; | 1702 | unsigned char comm[sizeof(me->comm)]; |
@@ -1811,8 +1809,8 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, | |||
1811 | return error; | 1809 | return error; |
1812 | } | 1810 | } |
1813 | 1811 | ||
1814 | asmlinkage long sys_getcpu(unsigned __user *cpup, unsigned __user *nodep, | 1812 | SYSCALL_DEFINE3(getcpu, unsigned __user *, cpup, unsigned __user *, nodep, |
1815 | struct getcpu_cache __user *unused) | 1813 | struct getcpu_cache __user *, unused) |
1816 | { | 1814 | { |
1817 | int err = 0; | 1815 | int err = 0; |
1818 | int cpu = raw_smp_processor_id(); | 1816 | int cpu = raw_smp_processor_id(); |