diff options
-rw-r--r-- | fs/proc/base.c | 4 | ||||
-rw-r--r-- | fs/proc/root.c | 16 | ||||
-rw-r--r-- | include/linux/proc_fs.h | 12 | ||||
-rw-r--r-- | kernel/fork.c | 7 |
4 files changed, 39 insertions, 0 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index 5e0c6a1ce8b3..21510c9aa89c 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -2275,6 +2275,10 @@ void proc_flush_task(struct task_struct *task) | |||
2275 | proc_flush_task_mnt(upid->ns->proc_mnt, upid->nr, | 2275 | proc_flush_task_mnt(upid->ns->proc_mnt, upid->nr, |
2276 | leader ? 0 : tgid->numbers[i].nr); | 2276 | leader ? 0 : tgid->numbers[i].nr); |
2277 | } | 2277 | } |
2278 | |||
2279 | upid = &pid->numbers[pid->level]; | ||
2280 | if (upid->nr == 1) | ||
2281 | pid_ns_release_proc(upid->ns); | ||
2278 | } | 2282 | } |
2279 | 2283 | ||
2280 | static struct dentry *proc_pid_instantiate(struct inode *dir, | 2284 | static struct dentry *proc_pid_instantiate(struct inode *dir, |
diff --git a/fs/proc/root.c b/fs/proc/root.c index 94e9d734384e..ec9cb3b6c93b 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c | |||
@@ -212,6 +212,22 @@ struct proc_dir_entry proc_root = { | |||
212 | .parent = &proc_root, | 212 | .parent = &proc_root, |
213 | }; | 213 | }; |
214 | 214 | ||
215 | int pid_ns_prepare_proc(struct pid_namespace *ns) | ||
216 | { | ||
217 | struct vfsmount *mnt; | ||
218 | |||
219 | mnt = kern_mount_data(&proc_fs_type, ns); | ||
220 | if (IS_ERR(mnt)) | ||
221 | return PTR_ERR(mnt); | ||
222 | |||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | void pid_ns_release_proc(struct pid_namespace *ns) | ||
227 | { | ||
228 | mntput(ns->proc_mnt); | ||
229 | } | ||
230 | |||
215 | EXPORT_SYMBOL(proc_symlink); | 231 | EXPORT_SYMBOL(proc_symlink); |
216 | EXPORT_SYMBOL(proc_mkdir); | 232 | EXPORT_SYMBOL(proc_mkdir); |
217 | EXPORT_SYMBOL(create_proc_entry); | 233 | EXPORT_SYMBOL(create_proc_entry); |
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index cbc1038c7900..1ff461672060 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h | |||
@@ -143,6 +143,9 @@ extern const struct file_operations proc_kcore_operations; | |||
143 | extern const struct file_operations proc_kmsg_operations; | 143 | extern const struct file_operations proc_kmsg_operations; |
144 | extern const struct file_operations ppc_htab_operations; | 144 | extern const struct file_operations ppc_htab_operations; |
145 | 145 | ||
146 | extern int pid_ns_prepare_proc(struct pid_namespace *ns); | ||
147 | extern void pid_ns_release_proc(struct pid_namespace *ns); | ||
148 | |||
146 | /* | 149 | /* |
147 | * proc_tty.c | 150 | * proc_tty.c |
148 | */ | 151 | */ |
@@ -235,6 +238,15 @@ static inline void proc_tty_unregister_driver(struct tty_driver *driver) {}; | |||
235 | 238 | ||
236 | extern struct proc_dir_entry proc_root; | 239 | extern struct proc_dir_entry proc_root; |
237 | 240 | ||
241 | static inline int pid_ns_prepare_proc(struct pid_namespace *ns) | ||
242 | { | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | static inline void pid_ns_release_proc(struct pid_namespace *ns) | ||
247 | { | ||
248 | } | ||
249 | |||
238 | #endif /* CONFIG_PROC_FS */ | 250 | #endif /* CONFIG_PROC_FS */ |
239 | 251 | ||
240 | #if !defined(CONFIG_PROC_KCORE) | 252 | #if !defined(CONFIG_PROC_KCORE) |
diff --git a/kernel/fork.c b/kernel/fork.c index f252784f9330..ce9297e4e7d4 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <linux/taskstats_kern.h> | 50 | #include <linux/taskstats_kern.h> |
51 | #include <linux/random.h> | 51 | #include <linux/random.h> |
52 | #include <linux/tty.h> | 52 | #include <linux/tty.h> |
53 | #include <linux/proc_fs.h> | ||
53 | 54 | ||
54 | #include <asm/pgtable.h> | 55 | #include <asm/pgtable.h> |
55 | #include <asm/pgalloc.h> | 56 | #include <asm/pgalloc.h> |
@@ -1150,6 +1151,12 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1150 | pid = alloc_pid(task_active_pid_ns(p)); | 1151 | pid = alloc_pid(task_active_pid_ns(p)); |
1151 | if (!pid) | 1152 | if (!pid) |
1152 | goto bad_fork_cleanup_namespaces; | 1153 | goto bad_fork_cleanup_namespaces; |
1154 | |||
1155 | if (clone_flags & CLONE_NEWPID) { | ||
1156 | retval = pid_ns_prepare_proc(task_active_pid_ns(p)); | ||
1157 | if (retval < 0) | ||
1158 | goto bad_fork_free_pid; | ||
1159 | } | ||
1153 | } | 1160 | } |
1154 | 1161 | ||
1155 | p->pid = pid_nr(pid); | 1162 | p->pid = pid_nr(pid); |