aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink/af_netlink.c
diff options
context:
space:
mode:
authorGao feng <gaofeng@cn.fujitsu.com>2012-10-04 16:15:48 -0400
committerDavid S. Miller <davem@davemloft.net>2012-10-07 00:30:56 -0400
commit6dc878a8ca39e93f70c42f3dd7260bde10c1e0f1 (patch)
tree2549dc75d29ea1975611775b05921482caf75c04 /net/netlink/af_netlink.c
parented5062ddaa71e9f8b2b3aacc264428ce6da93d9e (diff)
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>
Diffstat (limited to 'net/netlink/af_netlink.c')
-rw-r--r--net/netlink/af_netlink.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 0f2e3ad69c47..01e944a017a4 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -169,6 +169,8 @@ static void netlink_sock_destruct(struct sock *sk)
169 if (nlk->cb) { 169 if (nlk->cb) {
170 if (nlk->cb->done) 170 if (nlk->cb->done)
171 nlk->cb->done(nlk->cb); 171 nlk->cb->done(nlk->cb);
172
173 module_put(nlk->cb->module);
172 netlink_destroy_callback(nlk->cb); 174 netlink_destroy_callback(nlk->cb);
173 } 175 }
174 176
@@ -1758,6 +1760,7 @@ static int netlink_dump(struct sock *sk)
1758 nlk->cb = NULL; 1760 nlk->cb = NULL;
1759 mutex_unlock(nlk->cb_mutex); 1761 mutex_unlock(nlk->cb_mutex);
1760 1762
1763 module_put(cb->module);
1761 netlink_consume_callback(cb); 1764 netlink_consume_callback(cb);
1762 return 0; 1765 return 0;
1763 1766
@@ -1767,9 +1770,9 @@ errout_skb:
1767 return err; 1770 return err;
1768} 1771}
1769 1772
1770int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, 1773int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
1771 const struct nlmsghdr *nlh, 1774 const struct nlmsghdr *nlh,
1772 struct netlink_dump_control *control) 1775 struct netlink_dump_control *control)
1773{ 1776{
1774 struct netlink_callback *cb; 1777 struct netlink_callback *cb;
1775 struct sock *sk; 1778 struct sock *sk;
@@ -1784,6 +1787,7 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
1784 cb->done = control->done; 1787 cb->done = control->done;
1785 cb->nlh = nlh; 1788 cb->nlh = nlh;
1786 cb->data = control->data; 1789 cb->data = control->data;
1790 cb->module = control->module;
1787 cb->min_dump_alloc = control->min_dump_alloc; 1791 cb->min_dump_alloc = control->min_dump_alloc;
1788 atomic_inc(&skb->users); 1792 atomic_inc(&skb->users);
1789 cb->skb = skb; 1793 cb->skb = skb;
@@ -1794,19 +1798,28 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
1794 return -ECONNREFUSED; 1798 return -ECONNREFUSED;
1795 } 1799 }
1796 nlk = nlk_sk(sk); 1800 nlk = nlk_sk(sk);
1797 /* A dump is in progress... */ 1801
1798 mutex_lock(nlk->cb_mutex); 1802 mutex_lock(nlk->cb_mutex);
1803 /* A dump is in progress... */
1799 if (nlk->cb) { 1804 if (nlk->cb) {
1800 mutex_unlock(nlk->cb_mutex); 1805 mutex_unlock(nlk->cb_mutex);
1801 netlink_destroy_callback(cb); 1806 netlink_destroy_callback(cb);
1802 sock_put(sk); 1807 ret = -EBUSY;
1803 return -EBUSY; 1808 goto out;
1804 } 1809 }
1810 /* add reference of module which cb->dump belongs to */
1811 if (!try_module_get(cb->module)) {
1812 mutex_unlock(nlk->cb_mutex);
1813 netlink_destroy_callback(cb);
1814 ret = -EPROTONOSUPPORT;
1815 goto out;
1816 }
1817
1805 nlk->cb = cb; 1818 nlk->cb = cb;
1806 mutex_unlock(nlk->cb_mutex); 1819 mutex_unlock(nlk->cb_mutex);
1807 1820
1808 ret = netlink_dump(sk); 1821 ret = netlink_dump(sk);
1809 1822out:
1810 sock_put(sk); 1823 sock_put(sk);
1811 1824
1812 if (ret) 1825 if (ret)
@@ -1817,7 +1830,7 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
1817 */ 1830 */
1818 return -EINTR; 1831 return -EINTR;
1819} 1832}
1820EXPORT_SYMBOL(netlink_dump_start); 1833EXPORT_SYMBOL(__netlink_dump_start);
1821 1834
1822void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err) 1835void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
1823{ 1836{