aboutsummaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorGao feng <gaofeng@cn.fujitsu.com>2012-10-04 20:15:48 +0000
committerHerton Ronaldo Krzesinski <herton.krzesinski@canonical.com>2012-12-11 14:54:22 -0200
commit2436c3f7f726357d99a0191ad8d49baba90e4b84 (patch)
treea35ea71987a418b4cea206edf0cdd3c80a2d9252 /include/linux
parent05e6abd9140d96e762480bbe61bf2740524dfe77 (diff)
netlink: add reference of module in netlink_dump_start
commit 6dc878a8ca39e93f70c42f3dd7260bde10c1e0f1 upstream. I get a panic when I use ss -a and rmmod inet_diag at the same time. It's because netlink_dump uses inet_diag_dump which belongs to module inet_diag. I search the codes and find many modules have the same problem. We need to add a reference to the module which the cb->dump belongs to. Thanks for all help from Stephen,Jan,Eric,Steffen and Pablo. Change From v3: change netlink_dump_start to inline,suggestion from Pablo and Eric. Change From v2: delete netlink_dump_done,and call module_put in netlink_dump and netlink_sock_destruct. Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Herton Ronaldo Krzesinski <herton.krzesinski@canonical.com>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/netlink.h21
1 files changed, 17 insertions, 4 deletions
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index 0f628ffa420c..6f393c2f43eb 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -153,6 +153,7 @@ struct nlattr {
#include <linux/capability.h>
#include <linux/skbuff.h>
+#include <linux/export.h>
struct net;
@@ -226,6 +227,8 @@ struct netlink_callback {
struct netlink_callback *cb);
int (*done)(struct netlink_callback *cb);
void *data;
+ /* the module that dump function belong to */
+ struct module *module;
u16 family;
u16 min_dump_alloc;
unsigned int prev_seq, seq;
@@ -251,14 +254,24 @@ __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags)
struct netlink_dump_control {
int (*dump)(struct sk_buff *skb, struct netlink_callback *);
- int (*done)(struct netlink_callback*);
+ int (*done)(struct netlink_callback *);
void *data;
+ struct module *module;
u16 min_dump_alloc;
};
-extern int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
- const struct nlmsghdr *nlh,
- struct netlink_dump_control *control);
+extern int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
+ const struct nlmsghdr *nlh,
+ struct netlink_dump_control *control);
+static inline int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
+ const struct nlmsghdr *nlh,
+ struct netlink_dump_control *control)
+{
+ if (!control->module)
+ control->module = THIS_MODULE;
+
+ return __netlink_dump_start(ssk, skb, nlh, control);
+}
#define NL_NONROOT_RECV 0x1