netlink: add reference of module in netlink_dump_start
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>
This commit is contained in:

committed by
David S. Miller

parent
ed5062ddaa
commit
6dc878a8ca
@@ -245,6 +245,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;
|
||||
@@ -262,14 +264,24 @@ __nlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, int type, int len, int fla
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
Reference in New Issue
Block a user