|
8 | 8 | #include <linux/magic.h>
|
9 | 9 | #include <linux/ktime.h>
|
10 | 10 | #include <linux/seq_file.h>
|
| 11 | +#include <linux/pid_namespace.h> |
11 | 12 | #include <linux/user_namespace.h>
|
12 | 13 | #include <linux/nsfs.h>
|
13 | 14 | #include <linux/uaccess.h>
|
@@ -124,9 +125,12 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,
|
124 | 125 | unsigned long arg)
|
125 | 126 | {
|
126 | 127 | struct user_namespace *user_ns;
|
| 128 | + struct pid_namespace *pid_ns; |
| 129 | + struct task_struct *tsk; |
127 | 130 | struct ns_common *ns = get_proc_ns(file_inode(filp));
|
128 | 131 | uid_t __user *argp;
|
129 | 132 | uid_t uid;
|
| 133 | + int ret; |
130 | 134 |
|
131 | 135 | switch (ioctl) {
|
132 | 136 | case NS_GET_USERNS:
|
@@ -157,9 +161,56 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,
|
157 | 161 | id = mnt_ns->seq;
|
158 | 162 | return put_user(id, idp);
|
159 | 163 | }
|
| 164 | + case NS_GET_PID_FROM_PIDNS: |
| 165 | + fallthrough; |
| 166 | + case NS_GET_TGID_FROM_PIDNS: |
| 167 | + fallthrough; |
| 168 | + case NS_GET_PID_IN_PIDNS: |
| 169 | + fallthrough; |
| 170 | + case NS_GET_TGID_IN_PIDNS: |
| 171 | + if (ns->ops->type != CLONE_NEWPID) |
| 172 | + return -EINVAL; |
| 173 | + |
| 174 | + ret = -ESRCH; |
| 175 | + pid_ns = container_of(ns, struct pid_namespace, ns); |
| 176 | + |
| 177 | + rcu_read_lock(); |
| 178 | + |
| 179 | + if (ioctl == NS_GET_PID_IN_PIDNS || |
| 180 | + ioctl == NS_GET_TGID_IN_PIDNS) |
| 181 | + tsk = find_task_by_vpid(arg); |
| 182 | + else |
| 183 | + tsk = find_task_by_pid_ns(arg, pid_ns); |
| 184 | + if (!tsk) |
| 185 | + break; |
| 186 | + |
| 187 | + switch (ioctl) { |
| 188 | + case NS_GET_PID_FROM_PIDNS: |
| 189 | + ret = task_pid_vnr(tsk); |
| 190 | + break; |
| 191 | + case NS_GET_TGID_FROM_PIDNS: |
| 192 | + ret = task_tgid_vnr(tsk); |
| 193 | + break; |
| 194 | + case NS_GET_PID_IN_PIDNS: |
| 195 | + ret = task_pid_nr_ns(tsk, pid_ns); |
| 196 | + break; |
| 197 | + case NS_GET_TGID_IN_PIDNS: |
| 198 | + ret = task_tgid_nr_ns(tsk, pid_ns); |
| 199 | + break; |
| 200 | + default: |
| 201 | + ret = 0; |
| 202 | + break; |
| 203 | + } |
| 204 | + rcu_read_unlock(); |
| 205 | + |
| 206 | + if (!ret) |
| 207 | + ret = -ESRCH; |
| 208 | + break; |
160 | 209 | default:
|
161 |
| - return -ENOTTY; |
| 210 | + ret = -ENOTTY; |
162 | 211 | }
|
| 212 | + |
| 213 | + return ret; |
163 | 214 | }
|
164 | 215 |
|
165 | 216 | int ns_get_name(char *buf, size_t size, struct task_struct *task,
|
|
0 commit comments