diff options
-rw-r--r-- | include/linux/tsacct_kern.h | 8 | ||||
-rw-r--r-- | init/Kconfig | 1 | ||||
-rw-r--r-- | kernel/taskstats.c | 23 | ||||
-rw-r--r-- | kernel/tsacct.c | 12 |
4 files changed, 30 insertions, 14 deletions
diff --git a/include/linux/tsacct_kern.h b/include/linux/tsacct_kern.h index 7e50ac795b0b..44893e5ec8f7 100644 --- a/include/linux/tsacct_kern.h +++ b/include/linux/tsacct_kern.h | |||
@@ -10,9 +10,13 @@ | |||
10 | #include <linux/taskstats.h> | 10 | #include <linux/taskstats.h> |
11 | 11 | ||
12 | #ifdef CONFIG_TASKSTATS | 12 | #ifdef CONFIG_TASKSTATS |
13 | extern void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk); | 13 | extern void bacct_add_tsk(struct user_namespace *user_ns, |
14 | struct pid_namespace *pid_ns, | ||
15 | struct taskstats *stats, struct task_struct *tsk); | ||
14 | #else | 16 | #else |
15 | static inline void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) | 17 | static inline void bacct_add_tsk(struct user_namespace *user_ns, |
18 | struct pid_namespace *pid_ns, | ||
19 | struct taskstats *stats, struct task_struct *tsk) | ||
16 | {} | 20 | {} |
17 | #endif /* CONFIG_TASKSTATS */ | 21 | #endif /* CONFIG_TASKSTATS */ |
18 | 22 | ||
diff --git a/init/Kconfig b/init/Kconfig index b5ecb4e75518..f0f636cf0ce7 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -927,7 +927,6 @@ config UIDGID_CONVERTED | |||
927 | # Features | 927 | # Features |
928 | depends on IMA = n | 928 | depends on IMA = n |
929 | depends on EVM = n | 929 | depends on EVM = n |
930 | depends on TASKSTATS = n | ||
931 | depends on TRACING = n | 930 | depends on TRACING = n |
932 | depends on FS_POSIX_ACL = n | 931 | depends on FS_POSIX_ACL = n |
933 | depends on QUOTA = n | 932 | depends on QUOTA = n |
diff --git a/kernel/taskstats.c b/kernel/taskstats.c index d0a32796550f..3880df2acf05 100644 --- a/kernel/taskstats.c +++ b/kernel/taskstats.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/cgroup.h> | 27 | #include <linux/cgroup.h> |
28 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
29 | #include <linux/file.h> | 29 | #include <linux/file.h> |
30 | #include <linux/pid_namespace.h> | ||
30 | #include <net/genetlink.h> | 31 | #include <net/genetlink.h> |
31 | #include <linux/atomic.h> | 32 | #include <linux/atomic.h> |
32 | 33 | ||
@@ -174,7 +175,9 @@ static void send_cpu_listeners(struct sk_buff *skb, | |||
174 | up_write(&listeners->sem); | 175 | up_write(&listeners->sem); |
175 | } | 176 | } |
176 | 177 | ||
177 | static void fill_stats(struct task_struct *tsk, struct taskstats *stats) | 178 | static void fill_stats(struct user_namespace *user_ns, |
179 | struct pid_namespace *pid_ns, | ||
180 | struct task_struct *tsk, struct taskstats *stats) | ||
178 | { | 181 | { |
179 | memset(stats, 0, sizeof(*stats)); | 182 | memset(stats, 0, sizeof(*stats)); |
180 | /* | 183 | /* |
@@ -190,7 +193,7 @@ static void fill_stats(struct task_struct *tsk, struct taskstats *stats) | |||
190 | stats->version = TASKSTATS_VERSION; | 193 | stats->version = TASKSTATS_VERSION; |
191 | stats->nvcsw = tsk->nvcsw; | 194 | stats->nvcsw = tsk->nvcsw; |
192 | stats->nivcsw = tsk->nivcsw; | 195 | stats->nivcsw = tsk->nivcsw; |
193 | bacct_add_tsk(stats, tsk); | 196 | bacct_add_tsk(user_ns, pid_ns, stats, tsk); |
194 | 197 | ||
195 | /* fill in extended acct fields */ | 198 | /* fill in extended acct fields */ |
196 | xacct_add_tsk(stats, tsk); | 199 | xacct_add_tsk(stats, tsk); |
@@ -207,7 +210,7 @@ static int fill_stats_for_pid(pid_t pid, struct taskstats *stats) | |||
207 | rcu_read_unlock(); | 210 | rcu_read_unlock(); |
208 | if (!tsk) | 211 | if (!tsk) |
209 | return -ESRCH; | 212 | return -ESRCH; |
210 | fill_stats(tsk, stats); | 213 | fill_stats(current_user_ns(), task_active_pid_ns(current), tsk, stats); |
211 | put_task_struct(tsk); | 214 | put_task_struct(tsk); |
212 | return 0; | 215 | return 0; |
213 | } | 216 | } |
@@ -291,6 +294,12 @@ static int add_del_listener(pid_t pid, const struct cpumask *mask, int isadd) | |||
291 | if (!cpumask_subset(mask, cpu_possible_mask)) | 294 | if (!cpumask_subset(mask, cpu_possible_mask)) |
292 | return -EINVAL; | 295 | return -EINVAL; |
293 | 296 | ||
297 | if (current_user_ns() != &init_user_ns) | ||
298 | return -EINVAL; | ||
299 | |||
300 | if (task_active_pid_ns(current) != &init_pid_ns) | ||
301 | return -EINVAL; | ||
302 | |||
294 | if (isadd == REGISTER) { | 303 | if (isadd == REGISTER) { |
295 | for_each_cpu(cpu, mask) { | 304 | for_each_cpu(cpu, mask) { |
296 | s = kmalloc_node(sizeof(struct listener), | 305 | s = kmalloc_node(sizeof(struct listener), |
@@ -631,11 +640,12 @@ void taskstats_exit(struct task_struct *tsk, int group_dead) | |||
631 | if (rc < 0) | 640 | if (rc < 0) |
632 | return; | 641 | return; |
633 | 642 | ||
634 | stats = mk_reply(rep_skb, TASKSTATS_TYPE_PID, tsk->pid); | 643 | stats = mk_reply(rep_skb, TASKSTATS_TYPE_PID, |
644 | task_pid_nr_ns(tsk, &init_pid_ns)); | ||
635 | if (!stats) | 645 | if (!stats) |
636 | goto err; | 646 | goto err; |
637 | 647 | ||
638 | fill_stats(tsk, stats); | 648 | fill_stats(&init_user_ns, &init_pid_ns, tsk, stats); |
639 | 649 | ||
640 | /* | 650 | /* |
641 | * Doesn't matter if tsk is the leader or the last group member leaving | 651 | * Doesn't matter if tsk is the leader or the last group member leaving |
@@ -643,7 +653,8 @@ void taskstats_exit(struct task_struct *tsk, int group_dead) | |||
643 | if (!is_thread_group || !group_dead) | 653 | if (!is_thread_group || !group_dead) |
644 | goto send; | 654 | goto send; |
645 | 655 | ||
646 | stats = mk_reply(rep_skb, TASKSTATS_TYPE_TGID, tsk->tgid); | 656 | stats = mk_reply(rep_skb, TASKSTATS_TYPE_TGID, |
657 | task_tgid_nr_ns(tsk, &init_pid_ns)); | ||
647 | if (!stats) | 658 | if (!stats) |
648 | goto err; | 659 | goto err; |
649 | 660 | ||
diff --git a/kernel/tsacct.c b/kernel/tsacct.c index 23b4d784ebdd..625df0b44690 100644 --- a/kernel/tsacct.c +++ b/kernel/tsacct.c | |||
@@ -26,7 +26,9 @@ | |||
26 | /* | 26 | /* |
27 | * fill in basic accounting fields | 27 | * fill in basic accounting fields |
28 | */ | 28 | */ |
29 | void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) | 29 | void bacct_add_tsk(struct user_namespace *user_ns, |
30 | struct pid_namespace *pid_ns, | ||
31 | struct taskstats *stats, struct task_struct *tsk) | ||
30 | { | 32 | { |
31 | const struct cred *tcred; | 33 | const struct cred *tcred; |
32 | struct timespec uptime, ts; | 34 | struct timespec uptime, ts; |
@@ -55,13 +57,13 @@ void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) | |||
55 | stats->ac_flag |= AXSIG; | 57 | stats->ac_flag |= AXSIG; |
56 | stats->ac_nice = task_nice(tsk); | 58 | stats->ac_nice = task_nice(tsk); |
57 | stats->ac_sched = tsk->policy; | 59 | stats->ac_sched = tsk->policy; |
58 | stats->ac_pid = tsk->pid; | 60 | stats->ac_pid = task_pid_nr_ns(tsk, pid_ns); |
59 | rcu_read_lock(); | 61 | rcu_read_lock(); |
60 | tcred = __task_cred(tsk); | 62 | tcred = __task_cred(tsk); |
61 | stats->ac_uid = tcred->uid; | 63 | stats->ac_uid = from_kuid_munged(user_ns, tcred->uid); |
62 | stats->ac_gid = tcred->gid; | 64 | stats->ac_gid = from_kgid_munged(user_ns, tcred->gid); |
63 | stats->ac_ppid = pid_alive(tsk) ? | 65 | stats->ac_ppid = pid_alive(tsk) ? |
64 | rcu_dereference(tsk->real_parent)->tgid : 0; | 66 | task_tgid_nr_ns(rcu_dereference(tsk->real_parent), pid_ns) : 0; |
65 | rcu_read_unlock(); | 67 | rcu_read_unlock(); |
66 | stats->ac_utime = cputime_to_usecs(tsk->utime); | 68 | stats->ac_utime = cputime_to_usecs(tsk->utime); |
67 | stats->ac_stime = cputime_to_usecs(tsk->stime); | 69 | stats->ac_stime = cputime_to_usecs(tsk->stime); |