diff options
author | Jiri Kosina <jkosina@suse.cz> | 2008-05-06 10:57:55 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2008-05-06 10:57:55 -0400 |
commit | 7022b15e2a9f878fd5184586064c63352c3dd225 (patch) | |
tree | 5365c2f5bc82ae1946636ee8d5cd5d3b7e804f1b /kernel/sys.c | |
parent | aaad2b0c757f3e6e02552cb0bdcd91a5ec0d6305 (diff) | |
parent | a15306365a16380f3bafee9e181ba01231d4acd7 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'kernel/sys.c')
-rw-r--r-- | kernel/sys.c | 137 |
1 files changed, 67 insertions, 70 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index 6a0cc71ee88d..895d2d4c9493 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -978,8 +978,7 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) | |||
978 | goto out; | 978 | goto out; |
979 | 979 | ||
980 | if (task_pgrp(p) != pgrp) { | 980 | if (task_pgrp(p) != pgrp) { |
981 | detach_pid(p, PIDTYPE_PGID); | 981 | change_pid(p, PIDTYPE_PGID, pgrp); |
982 | attach_pid(p, PIDTYPE_PGID, pgrp); | ||
983 | set_task_pgrp(p, pid_nr(pgrp)); | 982 | set_task_pgrp(p, pid_nr(pgrp)); |
984 | } | 983 | } |
985 | 984 | ||
@@ -992,54 +991,67 @@ out: | |||
992 | 991 | ||
993 | asmlinkage long sys_getpgid(pid_t pid) | 992 | asmlinkage long sys_getpgid(pid_t pid) |
994 | { | 993 | { |
994 | struct task_struct *p; | ||
995 | struct pid *grp; | ||
996 | int retval; | ||
997 | |||
998 | rcu_read_lock(); | ||
995 | if (!pid) | 999 | if (!pid) |
996 | return task_pgrp_vnr(current); | 1000 | grp = task_pgrp(current); |
997 | else { | 1001 | else { |
998 | int retval; | ||
999 | struct task_struct *p; | ||
1000 | |||
1001 | read_lock(&tasklist_lock); | ||
1002 | p = find_task_by_vpid(pid); | ||
1003 | retval = -ESRCH; | 1002 | retval = -ESRCH; |
1004 | if (p) { | 1003 | p = find_task_by_vpid(pid); |
1005 | retval = security_task_getpgid(p); | 1004 | if (!p) |
1006 | if (!retval) | 1005 | goto out; |
1007 | retval = task_pgrp_vnr(p); | 1006 | grp = task_pgrp(p); |
1008 | } | 1007 | if (!grp) |
1009 | read_unlock(&tasklist_lock); | 1008 | goto out; |
1010 | return retval; | 1009 | |
1010 | retval = security_task_getpgid(p); | ||
1011 | if (retval) | ||
1012 | goto out; | ||
1011 | } | 1013 | } |
1014 | retval = pid_vnr(grp); | ||
1015 | out: | ||
1016 | rcu_read_unlock(); | ||
1017 | return retval; | ||
1012 | } | 1018 | } |
1013 | 1019 | ||
1014 | #ifdef __ARCH_WANT_SYS_GETPGRP | 1020 | #ifdef __ARCH_WANT_SYS_GETPGRP |
1015 | 1021 | ||
1016 | asmlinkage long sys_getpgrp(void) | 1022 | asmlinkage long sys_getpgrp(void) |
1017 | { | 1023 | { |
1018 | /* SMP - assuming writes are word atomic this is fine */ | 1024 | return sys_getpgid(0); |
1019 | return task_pgrp_vnr(current); | ||
1020 | } | 1025 | } |
1021 | 1026 | ||
1022 | #endif | 1027 | #endif |
1023 | 1028 | ||
1024 | asmlinkage long sys_getsid(pid_t pid) | 1029 | asmlinkage long sys_getsid(pid_t pid) |
1025 | { | 1030 | { |
1031 | struct task_struct *p; | ||
1032 | struct pid *sid; | ||
1033 | int retval; | ||
1034 | |||
1035 | rcu_read_lock(); | ||
1026 | if (!pid) | 1036 | if (!pid) |
1027 | return task_session_vnr(current); | 1037 | sid = task_session(current); |
1028 | else { | 1038 | else { |
1029 | int retval; | ||
1030 | struct task_struct *p; | ||
1031 | |||
1032 | rcu_read_lock(); | ||
1033 | p = find_task_by_vpid(pid); | ||
1034 | retval = -ESRCH; | 1039 | retval = -ESRCH; |
1035 | if (p) { | 1040 | p = find_task_by_vpid(pid); |
1036 | retval = security_task_getsid(p); | 1041 | if (!p) |
1037 | if (!retval) | 1042 | goto out; |
1038 | retval = task_session_vnr(p); | 1043 | sid = task_session(p); |
1039 | } | 1044 | if (!sid) |
1040 | rcu_read_unlock(); | 1045 | goto out; |
1041 | return retval; | 1046 | |
1047 | retval = security_task_getsid(p); | ||
1048 | if (retval) | ||
1049 | goto out; | ||
1042 | } | 1050 | } |
1051 | retval = pid_vnr(sid); | ||
1052 | out: | ||
1053 | rcu_read_unlock(); | ||
1054 | return retval; | ||
1043 | } | 1055 | } |
1044 | 1056 | ||
1045 | asmlinkage long sys_setsid(void) | 1057 | asmlinkage long sys_setsid(void) |
@@ -1545,6 +1557,19 @@ out: | |||
1545 | * | 1557 | * |
1546 | */ | 1558 | */ |
1547 | 1559 | ||
1560 | static void accumulate_thread_rusage(struct task_struct *t, struct rusage *r, | ||
1561 | cputime_t *utimep, cputime_t *stimep) | ||
1562 | { | ||
1563 | *utimep = cputime_add(*utimep, t->utime); | ||
1564 | *stimep = cputime_add(*stimep, t->stime); | ||
1565 | r->ru_nvcsw += t->nvcsw; | ||
1566 | r->ru_nivcsw += t->nivcsw; | ||
1567 | r->ru_minflt += t->min_flt; | ||
1568 | r->ru_majflt += t->maj_flt; | ||
1569 | r->ru_inblock += task_io_get_inblock(t); | ||
1570 | r->ru_oublock += task_io_get_oublock(t); | ||
1571 | } | ||
1572 | |||
1548 | static void k_getrusage(struct task_struct *p, int who, struct rusage *r) | 1573 | static void k_getrusage(struct task_struct *p, int who, struct rusage *r) |
1549 | { | 1574 | { |
1550 | struct task_struct *t; | 1575 | struct task_struct *t; |
@@ -1554,12 +1579,14 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r) | |||
1554 | memset((char *) r, 0, sizeof *r); | 1579 | memset((char *) r, 0, sizeof *r); |
1555 | utime = stime = cputime_zero; | 1580 | utime = stime = cputime_zero; |
1556 | 1581 | ||
1557 | rcu_read_lock(); | 1582 | if (who == RUSAGE_THREAD) { |
1558 | if (!lock_task_sighand(p, &flags)) { | 1583 | accumulate_thread_rusage(p, r, &utime, &stime); |
1559 | rcu_read_unlock(); | 1584 | goto out; |
1560 | return; | ||
1561 | } | 1585 | } |
1562 | 1586 | ||
1587 | if (!lock_task_sighand(p, &flags)) | ||
1588 | return; | ||
1589 | |||
1563 | switch (who) { | 1590 | switch (who) { |
1564 | case RUSAGE_BOTH: | 1591 | case RUSAGE_BOTH: |
1565 | case RUSAGE_CHILDREN: | 1592 | case RUSAGE_CHILDREN: |
@@ -1586,14 +1613,7 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r) | |||
1586 | r->ru_oublock += p->signal->oublock; | 1613 | r->ru_oublock += p->signal->oublock; |
1587 | t = p; | 1614 | t = p; |
1588 | do { | 1615 | do { |
1589 | utime = cputime_add(utime, t->utime); | 1616 | accumulate_thread_rusage(t, r, &utime, &stime); |
1590 | stime = cputime_add(stime, t->stime); | ||
1591 | r->ru_nvcsw += t->nvcsw; | ||
1592 | r->ru_nivcsw += t->nivcsw; | ||
1593 | r->ru_minflt += t->min_flt; | ||
1594 | r->ru_majflt += t->maj_flt; | ||
1595 | r->ru_inblock += task_io_get_inblock(t); | ||
1596 | r->ru_oublock += task_io_get_oublock(t); | ||
1597 | t = next_thread(t); | 1617 | t = next_thread(t); |
1598 | } while (t != p); | 1618 | } while (t != p); |
1599 | break; | 1619 | break; |
@@ -1601,10 +1621,9 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r) | |||
1601 | default: | 1621 | default: |
1602 | BUG(); | 1622 | BUG(); |
1603 | } | 1623 | } |
1604 | |||
1605 | unlock_task_sighand(p, &flags); | 1624 | unlock_task_sighand(p, &flags); |
1606 | rcu_read_unlock(); | ||
1607 | 1625 | ||
1626 | out: | ||
1608 | cputime_to_timeval(utime, &r->ru_utime); | 1627 | cputime_to_timeval(utime, &r->ru_utime); |
1609 | cputime_to_timeval(stime, &r->ru_stime); | 1628 | cputime_to_timeval(stime, &r->ru_stime); |
1610 | } | 1629 | } |
@@ -1618,7 +1637,8 @@ int getrusage(struct task_struct *p, int who, struct rusage __user *ru) | |||
1618 | 1637 | ||
1619 | asmlinkage long sys_getrusage(int who, struct rusage __user *ru) | 1638 | asmlinkage long sys_getrusage(int who, struct rusage __user *ru) |
1620 | { | 1639 | { |
1621 | if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN) | 1640 | if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN && |
1641 | who != RUSAGE_THREAD) | ||
1622 | return -EINVAL; | 1642 | return -EINVAL; |
1623 | return getrusage(current, who, ru); | 1643 | return getrusage(current, who, ru); |
1624 | } | 1644 | } |
@@ -1632,10 +1652,9 @@ asmlinkage long sys_umask(int mask) | |||
1632 | asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, | 1652 | asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, |
1633 | unsigned long arg4, unsigned long arg5) | 1653 | unsigned long arg4, unsigned long arg5) |
1634 | { | 1654 | { |
1635 | long error; | 1655 | long uninitialized_var(error); |
1636 | 1656 | ||
1637 | error = security_task_prctl(option, arg2, arg3, arg4, arg5); | 1657 | if (security_task_prctl(option, arg2, arg3, arg4, arg5, &error)) |
1638 | if (error) | ||
1639 | return error; | 1658 | return error; |
1640 | 1659 | ||
1641 | switch (option) { | 1660 | switch (option) { |
@@ -1688,17 +1707,6 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, | |||
1688 | error = -EINVAL; | 1707 | error = -EINVAL; |
1689 | break; | 1708 | break; |
1690 | 1709 | ||
1691 | case PR_GET_KEEPCAPS: | ||
1692 | if (current->keep_capabilities) | ||
1693 | error = 1; | ||
1694 | break; | ||
1695 | case PR_SET_KEEPCAPS: | ||
1696 | if (arg2 != 0 && arg2 != 1) { | ||
1697 | error = -EINVAL; | ||
1698 | break; | ||
1699 | } | ||
1700 | current->keep_capabilities = arg2; | ||
1701 | break; | ||
1702 | case PR_SET_NAME: { | 1710 | case PR_SET_NAME: { |
1703 | struct task_struct *me = current; | 1711 | struct task_struct *me = current; |
1704 | unsigned char ncomm[sizeof(me->comm)]; | 1712 | unsigned char ncomm[sizeof(me->comm)]; |
@@ -1732,17 +1740,6 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, | |||
1732 | case PR_SET_SECCOMP: | 1740 | case PR_SET_SECCOMP: |
1733 | error = prctl_set_seccomp(arg2); | 1741 | error = prctl_set_seccomp(arg2); |
1734 | break; | 1742 | break; |
1735 | |||
1736 | case PR_CAPBSET_READ: | ||
1737 | if (!cap_valid(arg2)) | ||
1738 | return -EINVAL; | ||
1739 | return !!cap_raised(current->cap_bset, arg2); | ||
1740 | case PR_CAPBSET_DROP: | ||
1741 | #ifdef CONFIG_SECURITY_FILE_CAPABILITIES | ||
1742 | return cap_prctl_drop(arg2); | ||
1743 | #else | ||
1744 | return -EINVAL; | ||
1745 | #endif | ||
1746 | case PR_GET_TSC: | 1743 | case PR_GET_TSC: |
1747 | error = GET_TSC_CTL(arg2); | 1744 | error = GET_TSC_CTL(arg2); |
1748 | break; | 1745 | break; |