aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-12-29 20:35:33 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-12-29 20:35:33 -0500
commit50b2abed6b0812cbeda9f6dd48cc4c247be80643 (patch)
tree43da2b779fafe2d86c63ae1db4725db84b148588
parent7578ed02e4b08c9b7b07443b44cf0ccfdf55c91e (diff)
parentaef950b4ba3196622a5bd5e21ab1d63f30658285 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: packet: fix possible dev refcnt leak when bind fail netem: dont call vfree() under spinlock and BH disabled netfilter: ctnetlink: fix scheduling while atomic if helper is autoloaded netfilter: ctnetlink: fix return value of ctnetlink_get_expect()
-rw-r--r--net/netfilter/nf_conntrack_netlink.c18
-rw-r--r--net/packet/af_packet.c6
-rw-r--r--net/sched/sch_netem.c7
3 files changed, 22 insertions, 9 deletions
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index ef21b221f03..b6977776d71 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1358,12 +1358,15 @@ ctnetlink_create_conntrack(struct net *net, u16 zone,
1358 nf_ct_protonum(ct)); 1358 nf_ct_protonum(ct));
1359 if (helper == NULL) { 1359 if (helper == NULL) {
1360 rcu_read_unlock(); 1360 rcu_read_unlock();
1361 spin_unlock_bh(&nf_conntrack_lock);
1361#ifdef CONFIG_MODULES 1362#ifdef CONFIG_MODULES
1362 if (request_module("nfct-helper-%s", helpname) < 0) { 1363 if (request_module("nfct-helper-%s", helpname) < 0) {
1364 spin_lock_bh(&nf_conntrack_lock);
1363 err = -EOPNOTSUPP; 1365 err = -EOPNOTSUPP;
1364 goto err1; 1366 goto err1;
1365 } 1367 }
1366 1368
1369 spin_lock_bh(&nf_conntrack_lock);
1367 rcu_read_lock(); 1370 rcu_read_lock();
1368 helper = __nf_conntrack_helper_find(helpname, 1371 helper = __nf_conntrack_helper_find(helpname,
1369 nf_ct_l3num(ct), 1372 nf_ct_l3num(ct),
@@ -1869,25 +1872,30 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1869 1872
1870 err = -ENOMEM; 1873 err = -ENOMEM;
1871 skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1874 skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1872 if (skb2 == NULL) 1875 if (skb2 == NULL) {
1876 nf_ct_expect_put(exp);
1873 goto out; 1877 goto out;
1878 }
1874 1879
1875 rcu_read_lock(); 1880 rcu_read_lock();
1876 err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid, 1881 err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid,
1877 nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW, exp); 1882 nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW, exp);
1878 rcu_read_unlock(); 1883 rcu_read_unlock();
1884 nf_ct_expect_put(exp);
1879 if (err <= 0) 1885 if (err <= 0)
1880 goto free; 1886 goto free;
1881 1887
1882 nf_ct_expect_put(exp); 1888 err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
1889 if (err < 0)
1890 goto out;
1883 1891
1884 return netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT); 1892 return 0;
1885 1893
1886free: 1894free:
1887 kfree_skb(skb2); 1895 kfree_skb(skb2);
1888out: 1896out:
1889 nf_ct_expect_put(exp); 1897 /* this avoids a loop in nfnetlink. */
1890 return err; 1898 return err == -EAGAIN ? -ENOBUFS : err;
1891} 1899}
1892 1900
1893static int 1901static int
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 3891702b81d..d9d4970b9b0 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2448,8 +2448,12 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protoc
2448{ 2448{
2449 struct packet_sock *po = pkt_sk(sk); 2449 struct packet_sock *po = pkt_sk(sk);
2450 2450
2451 if (po->fanout) 2451 if (po->fanout) {
2452 if (dev)
2453 dev_put(dev);
2454
2452 return -EINVAL; 2455 return -EINVAL;
2456 }
2453 2457
2454 lock_sock(sk); 2458 lock_sock(sk);
2455 2459
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index eb3b9a86c6e..a4ab207cdc5 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -488,7 +488,7 @@ static int get_dist_table(struct Qdisc *sch, const struct nlattr *attr)
488 return -EINVAL; 488 return -EINVAL;
489 489
490 s = sizeof(struct disttable) + n * sizeof(s16); 490 s = sizeof(struct disttable) + n * sizeof(s16);
491 d = kmalloc(s, GFP_KERNEL); 491 d = kmalloc(s, GFP_KERNEL | __GFP_NOWARN);
492 if (!d) 492 if (!d)
493 d = vmalloc(s); 493 d = vmalloc(s);
494 if (!d) 494 if (!d)
@@ -501,9 +501,10 @@ static int get_dist_table(struct Qdisc *sch, const struct nlattr *attr)
501 root_lock = qdisc_root_sleeping_lock(sch); 501 root_lock = qdisc_root_sleeping_lock(sch);
502 502
503 spin_lock_bh(root_lock); 503 spin_lock_bh(root_lock);
504 dist_free(q->delay_dist); 504 swap(q->delay_dist, d);
505 q->delay_dist = d;
506 spin_unlock_bh(root_lock); 505 spin_unlock_bh(root_lock);
506
507 dist_free(d);
507 return 0; 508 return 0;
508} 509}
509 510