proc: revalidate directories created with proc_net_mkdir()
Subsystems (3)
PATCH 1/2 proc: revalidate directories created with proc_net_mkdir()
/proc/net directories may contain content which depends on net namespace. Such dentries should be revalidated after setns(CLONE_NEWNET).
See
commit 1fde6f21d90f8ba5da3cb9c54ca991ed72696c43 proc: fix /proc/net/* after setns(2)
The patch is all about "pde_force_lookup()" line.
[redid original patch --adobriyan]
---
fs/proc/generic.c | 25 ++++++++++++++++++------- fs/proc/internal.h | 3 +++ fs/proc/proc_net.c | 17 +++++++++++++++++ include/linux/proc_fs.h | 16 ++++++++-------- 4 files changed, 46 insertions(+), 15 deletions(-)
fs/proc/generic.c +18 -7
@@ -459,26 +459,37 @@ struct proc_dir_entry *proc_symlink(const char *name, }EXPORT_SYMBOL (proc_symlink); -struct proc_dir_entry *proc_mkdir_data (const char *name,umode_t mode, -struct proc_dir_entry *parent,void *data) +struct proc_dir_entry *_proc_mkdir (const char *name,umode_t mode, +struct proc_dir_entry **parent,void *data) {struct proc_dir_entry *ent;if (mode ==0 ) mode =S_IRUGO |S_IXUGO ; - ent =__proc_create (&parent, name,S_IFDIR | mode,2 ); + ent =__proc_create (parent, name,S_IFDIR | mode,2 );if (ent) { ent->data = data; ent->proc_fops = &proc_dir_operations; ent->proc_iops = &proc_dir_inode_operations; - parent->nlink++; - ent =proc_register (parent, ent); -if (!ent) - parent->nlink--; }return ent; } + +struct proc_dir_entry *proc_mkdir_data (const char *name,umode_t mode, +struct proc_dir_entry *parent,void *data) +{ +struct proc_dir_entry *pde; + + pde =_proc_mkdir (name, mode, &parent, data); +if (!pde) +return NULL ; + parent->nlink++; + pde =proc_register (parent, pde); +if (!pde) + parent->nlink--; +return pde; +}EXPORT_SYMBOL_GPL (proc_mkdir_data); struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode,
fs/proc/internal.h +3 -0
@@ -299,3 +299,6 @@ extern unsigned long task_statm(struct mm_struct *, unsigned long *, unsigned long *, unsigned long *, unsigned long *);extern void task_mem (struct seq_file *,struct mm_struct *); + +struct proc_dir_entry *_proc_mkdir (const char *name,umode_t mode, +struct proc_dir_entry **parent,void *data);
fs/proc/proc_net.c +17 -0
@@ -251,6 +251,23 @@ struct proc_dir_entry *proc_create_net_single_write(const char *name, umode_t mo }EXPORT_SYMBOL_GPL (proc_create_net_single_write); +struct proc_dir_entry *proc_net_mkdir (struct net *net,const char *name, +struct proc_dir_entry *parent) +{ +struct proc_dir_entry *pde; + + pde =_proc_mkdir (name,0 , &parent, net); +if (!pde) +return NULL ; +pde_force_lookup (pde); + parent->nlink++; + pde =proc_register (parent, pde); +if (!pde) + parent->nlink++; +return pde; +} +EXPORT_SYMBOL_GPL (proc_net_mkdir); +static struct net *get_proc_task_net (struct inode *dir) {struct task_struct *task;
include/linux/proc_fs.h +8 -8
@@ -8,6 +8,7 @@#include <linux/types.h> #include <linux/fs.h> +struct net ;struct proc_dir_entry ;struct seq_file ;struct seq_operations ;
@@ -73,6 +74,8 @@ struct proc_dir_entry *proc_create_net_single_write(const char *name, umode_t moint (*show)(struct seq_file *,void *), proc_write_t write, void *data); +struct proc_dir_entry *proc_net_mkdir (struct net *net,const char *name,struct proc_dir_entry *parent); +extern struct pid *tgid_pidfd_to_pid (const struct file *file);#else /* CONFIG_PROC_FS */
@@ -115,6 +118,11 @@ static inline int remove_proc_subtree(const char *name, struct proc_dir_entry *p#define proc_create_net (name, mode, parent, state_size, ops) ({NULL;})#define proc_create_net_single (name, mode, parent, show, data) ({NULL;}) +static inline struct proc_dir_entry *proc_net_mkdir (struct net *net,const char *name,struct proc_dir_entry *parent) +{ +return NULL ; +} +static inline struct pid *tgid_pidfd_to_pid (const struct file *file) {return ERR_PTR (-EBADF );
@@ -122,14 +130,6 @@ static inline struct pid *tgid_pidfd_to_pid(const struct file *file)#endif /* CONFIG_PROC_FS */ -struct net ; - -static inline struct proc_dir_entry *proc_net_mkdir ( -struct net *net,const char *name,struct proc_dir_entry *parent) -{ -return proc_mkdir_data (name,0 , parent, net); -} -struct ns_common ;int open_related_ns (struct ns_common *ns,struct ns_common *(*get_ns)(struct ns_common *ns));
fs/proc/generic.c struct proc_dir_entry *proc_symlink(const char *name, · line 463
Quoted 2 lines · Alexey Dobriyan
fs/proc/generic.c +2
-0+struct proc_dir_entry *_proc_mkdir (const char *name,umode_t mode, +struct proc_dir_entry **parent,void *data)
Two underscores, please...
fs/proc/proc_net.c struct proc_dir_entry *proc_create_net_single_write(const char *name, umode_t mo · line 266
Quoted 4 lines
fs/proc/proc_net.c +4
-0+ parent->nlink++; + pde =proc_register (parent, pde); +if (!pde) + parent->nlink++;
Really?
Quoted 5 lines · Al Viro
fs/proc/generic.c struct proc_dir_entry *proc_symlink(const char *name, · line 463
Quoted 2 lines · Alexey Dobriyan
fs/proc/generic.c +2
-0+struct proc_dir_entry *_proc_mkdir (const char *name,umode_t mode, +struct proc_dir_entry **parent,void *data)Two underscores, please...
Second underscore is more typing, I never understood it.
Quoted 6 lines
fs/proc/proc_net.c struct proc_dir_entry *proc_create_net_single_write(const char *name, umode_t mo · line 266
Quoted 4 lines
fs/proc/proc_net.c +4
-0+ parent->nlink++; + pde =proc_register (parent, pde); +if (!pde) + parent->nlink++;Really?
And ->nlink is a separate bug.
David Miller
maintainerFrom: Alexey Dobriyan <[email protected]>
Date: Sun, 7 Jul 2019 11:03:51 +0300
Quoted 8 lines · Al Viro
Quoted 5 lines · Alexey Dobriyan
fs/proc/generic.c struct proc_dir_entry *proc_symlink(const char *name, · line 463
Quoted 2 lines
fs/proc/generic.c +2
-0+struct proc_dir_entry *_proc_mkdir (const char *name,umode_t mode, +struct proc_dir_entry **parent,void *data)Two underscores, please...
Second underscore is more typing, I never understood it.
Canonicalness is not about understanding, it's about being consistent with the rest of the tree.
Just do it please...