[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20190706165201.GA10550@avx2>
Date: Sat, 6 Jul 2019 19:52:02 +0300
From: Alexey Dobriyan <adobriyan@...il.com>
To: davem@...emloft.net
Cc: netdev@...r.kernel.org, Per.Hallsmark@...driver.com
Subject: [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]
Reported-by: "Hallsmark, Per" <Per.Hallsmark@...driver.com>
Signed-off-by: Alexey Dobriyan <adobriyan@...il.com>
---
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(-)
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -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,
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -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);
--- a/fs/proc/proc_net.c
+++ b/fs/proc/proc_net.c
@@ -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;
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -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 mo
int (*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));
Powered by blists - more mailing lists