aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/proc/base.c4
-rw-r--r--fs/proc/root.c16
-rw-r--r--include/linux/proc_fs.h12
-rw-r--r--kernel/fork.c7
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
2280static struct dentry *proc_pid_instantiate(struct inode *dir, 2284static 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
215int 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
226void pid_ns_release_proc(struct pid_namespace *ns)
227{
228 mntput(ns->proc_mnt);
229}
230
215EXPORT_SYMBOL(proc_symlink); 231EXPORT_SYMBOL(proc_symlink);
216EXPORT_SYMBOL(proc_mkdir); 232EXPORT_SYMBOL(proc_mkdir);
217EXPORT_SYMBOL(create_proc_entry); 233EXPORT_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;
143extern const struct file_operations proc_kmsg_operations; 143extern const struct file_operations proc_kmsg_operations;
144extern const struct file_operations ppc_htab_operations; 144extern const struct file_operations ppc_htab_operations;
145 145
146extern int pid_ns_prepare_proc(struct pid_namespace *ns);
147extern 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
236extern struct proc_dir_entry proc_root; 239extern struct proc_dir_entry proc_root;
237 240
241static inline int pid_ns_prepare_proc(struct pid_namespace *ns)
242{
243 return 0;
244}
245
246static 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);