diff options
Diffstat (limited to 'kernel/sys.c')
-rw-r--r-- | kernel/sys.c | 58 |
1 files changed, 24 insertions, 34 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index 6a0cc71ee88d..e423d0d9e6ff 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -1545,6 +1545,19 @@ out: | |||
1545 | * | 1545 | * |
1546 | */ | 1546 | */ |
1547 | 1547 | ||
1548 | static void accumulate_thread_rusage(struct task_struct *t, struct rusage *r, | ||
1549 | cputime_t *utimep, cputime_t *stimep) | ||
1550 | { | ||
1551 | *utimep = cputime_add(*utimep, t->utime); | ||
1552 | *stimep = cputime_add(*stimep, t->stime); | ||
1553 | r->ru_nvcsw += t->nvcsw; | ||
1554 | r->ru_nivcsw += t->nivcsw; | ||
1555 | r->ru_minflt += t->min_flt; | ||
1556 | r->ru_majflt += t->maj_flt; | ||
1557 | r->ru_inblock += task_io_get_inblock(t); | ||
1558 | r->ru_oublock += task_io_get_oublock(t); | ||
1559 | } | ||
1560 | |||
1548 | static void k_getrusage(struct task_struct *p, int who, struct rusage *r) | 1561 | static void k_getrusage(struct task_struct *p, int who, struct rusage *r) |
1549 | { | 1562 | { |
1550 | struct task_struct *t; | 1563 | struct task_struct *t; |
@@ -1554,6 +1567,11 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r) | |||
1554 | memset((char *) r, 0, sizeof *r); | 1567 | memset((char *) r, 0, sizeof *r); |
1555 | utime = stime = cputime_zero; | 1568 | utime = stime = cputime_zero; |
1556 | 1569 | ||
1570 | if (who == RUSAGE_THREAD) { | ||
1571 | accumulate_thread_rusage(p, r, &utime, &stime); | ||
1572 | goto out; | ||
1573 | } | ||
1574 | |||
1557 | rcu_read_lock(); | 1575 | rcu_read_lock(); |
1558 | if (!lock_task_sighand(p, &flags)) { | 1576 | if (!lock_task_sighand(p, &flags)) { |
1559 | rcu_read_unlock(); | 1577 | rcu_read_unlock(); |
@@ -1586,14 +1604,7 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r) | |||
1586 | r->ru_oublock += p->signal->oublock; | 1604 | r->ru_oublock += p->signal->oublock; |
1587 | t = p; | 1605 | t = p; |
1588 | do { | 1606 | do { |
1589 | utime = cputime_add(utime, t->utime); | 1607 | 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); | 1608 | t = next_thread(t); |
1598 | } while (t != p); | 1609 | } while (t != p); |
1599 | break; | 1610 | break; |
@@ -1605,6 +1616,7 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r) | |||
1605 | unlock_task_sighand(p, &flags); | 1616 | unlock_task_sighand(p, &flags); |
1606 | rcu_read_unlock(); | 1617 | rcu_read_unlock(); |
1607 | 1618 | ||
1619 | out: | ||
1608 | cputime_to_timeval(utime, &r->ru_utime); | 1620 | cputime_to_timeval(utime, &r->ru_utime); |
1609 | cputime_to_timeval(stime, &r->ru_stime); | 1621 | cputime_to_timeval(stime, &r->ru_stime); |
1610 | } | 1622 | } |
@@ -1618,7 +1630,8 @@ int getrusage(struct task_struct *p, int who, struct rusage __user *ru) | |||
1618 | 1630 | ||
1619 | asmlinkage long sys_getrusage(int who, struct rusage __user *ru) | 1631 | asmlinkage long sys_getrusage(int who, struct rusage __user *ru) |
1620 | { | 1632 | { |
1621 | if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN) | 1633 | if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN && |
1634 | who != RUSAGE_THREAD) | ||
1622 | return -EINVAL; | 1635 | return -EINVAL; |
1623 | return getrusage(current, who, ru); | 1636 | return getrusage(current, who, ru); |
1624 | } | 1637 | } |
@@ -1632,10 +1645,9 @@ asmlinkage long sys_umask(int mask) | |||
1632 | asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, | 1645 | asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, |
1633 | unsigned long arg4, unsigned long arg5) | 1646 | unsigned long arg4, unsigned long arg5) |
1634 | { | 1647 | { |
1635 | long error; | 1648 | long uninitialized_var(error); |
1636 | 1649 | ||
1637 | error = security_task_prctl(option, arg2, arg3, arg4, arg5); | 1650 | if (security_task_prctl(option, arg2, arg3, arg4, arg5, &error)) |
1638 | if (error) | ||
1639 | return error; | 1651 | return error; |
1640 | 1652 | ||
1641 | switch (option) { | 1653 | switch (option) { |
@@ -1688,17 +1700,6 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, | |||
1688 | error = -EINVAL; | 1700 | error = -EINVAL; |
1689 | break; | 1701 | break; |
1690 | 1702 | ||
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: { | 1703 | case PR_SET_NAME: { |
1703 | struct task_struct *me = current; | 1704 | struct task_struct *me = current; |
1704 | unsigned char ncomm[sizeof(me->comm)]; | 1705 | unsigned char ncomm[sizeof(me->comm)]; |
@@ -1732,17 +1733,6 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, | |||
1732 | case PR_SET_SECCOMP: | 1733 | case PR_SET_SECCOMP: |
1733 | error = prctl_set_seccomp(arg2); | 1734 | error = prctl_set_seccomp(arg2); |
1734 | break; | 1735 | 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: | 1736 | case PR_GET_TSC: |
1747 | error = GET_TSC_CTL(arg2); | 1737 | error = GET_TSC_CTL(arg2); |
1748 | break; | 1738 | break; |