Commit 4bd6e32acec66c55c6c1af4672f3216b2ac88e35

Authored by Eric W. Biederman
1 parent cca080d9b6

userns: Convert taskstats to handle the user and pid namespaces.

- Explicitly limit exit task stat broadcast to the initial user and
  pid namespaces, as it is already limited to the initial network
  namespace.

- For broadcast task stats explicitly generate all of the idenitiers
  in terms of the initial user namespace and the initial pid
  namespace.

- For request stats report them in terms of the current user namespace
  and the current pid namespace.  Netlink messages are delivered
  syncrhonously to the kernel allowing us to get the user namespace
  and the pid namespace from the current task.

- Pass the namespaces for representing pids and uids and gids
  into bacct_add_task.

Cc: Balbir Singh <bsingharora@gmail.com>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>

Showing 4 changed files with 30 additions and 14 deletions Side-by-side Diff

include/linux/tsacct_kern.h
... ... @@ -10,9 +10,13 @@
10 10 #include <linux/taskstats.h>
11 11  
12 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 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 21 #endif /* CONFIG_TASKSTATS */
18 22  
... ... @@ -927,7 +927,6 @@
927 927 # Features
928 928 depends on IMA = n
929 929 depends on EVM = n
930   - depends on TASKSTATS = n
931 930 depends on TRACING = n
932 931 depends on FS_POSIX_ACL = n
933 932 depends on QUOTA = n
... ... @@ -27,6 +27,7 @@
27 27 #include <linux/cgroup.h>
28 28 #include <linux/fs.h>
29 29 #include <linux/file.h>
  30 +#include <linux/pid_namespace.h>
30 31 #include <net/genetlink.h>
31 32 #include <linux/atomic.h>
32 33  
... ... @@ -174,7 +175,9 @@
174 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 182 memset(stats, 0, sizeof(*stats));
180 183 /*
... ... @@ -190,7 +193,7 @@
190 193 stats->version = TASKSTATS_VERSION;
191 194 stats->nvcsw = tsk->nvcsw;
192 195 stats->nivcsw = tsk->nivcsw;
193   - bacct_add_tsk(stats, tsk);
  196 + bacct_add_tsk(user_ns, pid_ns, stats, tsk);
194 197  
195 198 /* fill in extended acct fields */
196 199 xacct_add_tsk(stats, tsk);
... ... @@ -207,7 +210,7 @@
207 210 rcu_read_unlock();
208 211 if (!tsk)
209 212 return -ESRCH;
210   - fill_stats(tsk, stats);
  213 + fill_stats(current_user_ns(), task_active_pid_ns(current), tsk, stats);
211 214 put_task_struct(tsk);
212 215 return 0;
213 216 }
... ... @@ -291,6 +294,12 @@
291 294 if (!cpumask_subset(mask, cpu_possible_mask))
292 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 303 if (isadd == REGISTER) {
295 304 for_each_cpu(cpu, mask) {
296 305 s = kmalloc_node(sizeof(struct listener),
297 306  
... ... @@ -631,11 +640,12 @@
631 640 if (rc < 0)
632 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 645 if (!stats)
636 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 651 * Doesn't matter if tsk is the leader or the last group member leaving
... ... @@ -643,7 +653,8 @@
643 653 if (!is_thread_group || !group_dead)
644 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 658 if (!stats)
648 659 goto err;
649 660  
... ... @@ -26,7 +26,9 @@
26 26 /*
27 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 33 const struct cred *tcred;
32 34 struct timespec uptime, ts;
33 35  
34 36  
... ... @@ -55,13 +57,13 @@
55 57 stats->ac_flag |= AXSIG;
56 58 stats->ac_nice = task_nice(tsk);
57 59 stats->ac_sched = tsk->policy;
58   - stats->ac_pid = tsk->pid;
  60 + stats->ac_pid = task_pid_nr_ns(tsk, pid_ns);
59 61 rcu_read_lock();
60 62 tcred = __task_cred(tsk);
61   - stats->ac_uid = tcred->uid;
62   - stats->ac_gid = tcred->gid;
  63 + stats->ac_uid = from_kuid_munged(user_ns, tcred->uid);
  64 + stats->ac_gid = from_kgid_munged(user_ns, tcred->gid);
63 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 67 rcu_read_unlock();
66 68 stats->ac_utime = cputime_to_usecs(tsk->utime);
67 69 stats->ac_stime = cputime_to_usecs(tsk->stime);