diff options
author | Dan Murphy | 2013-05-13 08:24:43 -0500 |
---|---|---|
committer | Dan Murphy | 2013-05-13 08:24:43 -0500 |
commit | f393eafdf4cf08f3d405457684ccea9e2ae48ea5 (patch) | |
tree | e3dda87208a0ee25dbc79c70a656c45597c9a8ed /net | |
parent | 1c1c1e66b5dc8ae89a416d1da5118900cd15219f (diff) | |
parent | dbf932a9b316d5b29b3e220e5a30e7a165ad2992 (diff) | |
download | kernel-video-f393eafdf4cf08f3d405457684ccea9e2ae48ea5.tar.gz kernel-video-f393eafdf4cf08f3d405457684ccea9e2ae48ea5.tar.xz kernel-video-f393eafdf4cf08f3d405457684ccea9e2ae48ea5.zip |
Merge tag 'v3.8.13' of http://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable into ti-linux-3.8.y
* tag 'v3.8.13' of http://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable: (74 commits)
Linux 3.8.13
x86/mm: account for PGDIR_SIZE alignment
kernel/audit_tree.c: tree will leak memory when failure occurs in audit_trim_trees()
NFSv4.x: Fix handling of partially delegated locks
EDAC: Don't give write permission to read-only files
Btrfs: fix extent logging with O_DIRECT into prealloc
Btrfs: compare relevant parts of delayed tree refs
tracing: Fix ftrace_dump()
drm/radeon: fix handling of v6 power tables
drm/radeon: add new richland pci ids
drm/radeon: fix possible segfault when parsing pm tables
drm/radeon: fix endian bugs in atom_allocate_fb_scratch()
drm/radeon: disable the crtcs in mc_stop (r5xx-r7xx) (v2)
drm/radeon: Always flush the VM
drm/radeon: fix typo in si_select_se_sh()
drm/radeon: fix hdmi mode enable on RS600/RS690/RS740
drm/radeon: cleanup properly if mmio mapping fails
drm/radeon/evergreen+: don't enable HPD interrupts on eDP/LVDS
drm/radeon: add some new SI PCI ids
drm/radeon: disable the crtcs in mc_stop (evergreen+) (v2)
...
Signed-off-by: Dan Murphy <dmurphy@ti.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/netfilter/ipt_rpfilter.c | 8 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_NPT.c | 2 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_rpfilter.c | 8 | ||||
-rw-r--r-- | net/netfilter/ipset/ip_set_core.c | 3 | ||||
-rw-r--r-- | net/netfilter/ipset/ip_set_list_set.c | 10 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_pe_sip.c | 6 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_helper.c | 4 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 3 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_sip.c | 2 | ||||
-rw-r--r-- | net/netfilter/nf_nat_core.c | 40 |
10 files changed, 39 insertions, 47 deletions
diff --git a/net/ipv4/netfilter/ipt_rpfilter.c b/net/ipv4/netfilter/ipt_rpfilter.c index c30130062cd..c49dcd0284a 100644 --- a/net/ipv4/netfilter/ipt_rpfilter.c +++ b/net/ipv4/netfilter/ipt_rpfilter.c | |||
@@ -66,6 +66,12 @@ static bool rpfilter_lookup_reverse(struct flowi4 *fl4, | |||
66 | return dev_match; | 66 | return dev_match; |
67 | } | 67 | } |
68 | 68 | ||
69 | static bool rpfilter_is_local(const struct sk_buff *skb) | ||
70 | { | ||
71 | const struct rtable *rt = skb_rtable(skb); | ||
72 | return rt && (rt->rt_flags & RTCF_LOCAL); | ||
73 | } | ||
74 | |||
69 | static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) | 75 | static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) |
70 | { | 76 | { |
71 | const struct xt_rpfilter_info *info; | 77 | const struct xt_rpfilter_info *info; |
@@ -76,7 +82,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
76 | info = par->matchinfo; | 82 | info = par->matchinfo; |
77 | invert = info->flags & XT_RPFILTER_INVERT; | 83 | invert = info->flags & XT_RPFILTER_INVERT; |
78 | 84 | ||
79 | if (par->in->flags & IFF_LOOPBACK) | 85 | if (rpfilter_is_local(skb)) |
80 | return true ^ invert; | 86 | return true ^ invert; |
81 | 87 | ||
82 | iph = ip_hdr(skb); | 88 | iph = ip_hdr(skb); |
diff --git a/net/ipv6/netfilter/ip6t_NPT.c b/net/ipv6/netfilter/ip6t_NPT.c index 83acc1405a1..0ea43c7024d 100644 --- a/net/ipv6/netfilter/ip6t_NPT.c +++ b/net/ipv6/netfilter/ip6t_NPT.c | |||
@@ -57,7 +57,7 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt, | |||
57 | if (pfx_len - i >= 32) | 57 | if (pfx_len - i >= 32) |
58 | mask = 0; | 58 | mask = 0; |
59 | else | 59 | else |
60 | mask = htonl(~((1 << (pfx_len - i)) - 1)); | 60 | mask = htonl((1 << (i - pfx_len + 32)) - 1); |
61 | 61 | ||
62 | idx = i / 32; | 62 | idx = i / 32; |
63 | addr->s6_addr32[idx] &= mask; | 63 | addr->s6_addr32[idx] &= mask; |
diff --git a/net/ipv6/netfilter/ip6t_rpfilter.c b/net/ipv6/netfilter/ip6t_rpfilter.c index 5060d54199a..e0983f3648a 100644 --- a/net/ipv6/netfilter/ip6t_rpfilter.c +++ b/net/ipv6/netfilter/ip6t_rpfilter.c | |||
@@ -71,6 +71,12 @@ static bool rpfilter_lookup_reverse6(const struct sk_buff *skb, | |||
71 | return ret; | 71 | return ret; |
72 | } | 72 | } |
73 | 73 | ||
74 | static bool rpfilter_is_local(const struct sk_buff *skb) | ||
75 | { | ||
76 | const struct rt6_info *rt = (const void *) skb_dst(skb); | ||
77 | return rt && (rt->rt6i_flags & RTF_LOCAL); | ||
78 | } | ||
79 | |||
74 | static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) | 80 | static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) |
75 | { | 81 | { |
76 | const struct xt_rpfilter_info *info = par->matchinfo; | 82 | const struct xt_rpfilter_info *info = par->matchinfo; |
@@ -78,7 +84,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
78 | struct ipv6hdr *iph; | 84 | struct ipv6hdr *iph; |
79 | bool invert = info->flags & XT_RPFILTER_INVERT; | 85 | bool invert = info->flags & XT_RPFILTER_INVERT; |
80 | 86 | ||
81 | if (par->in->flags & IFF_LOOPBACK) | 87 | if (rpfilter_is_local(skb)) |
82 | return true ^ invert; | 88 | return true ^ invert; |
83 | 89 | ||
84 | iph = ipv6_hdr(skb); | 90 | iph = ipv6_hdr(skb); |
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index 6d6d8f2b033..38ca630eeeb 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c | |||
@@ -1470,7 +1470,8 @@ ip_set_utest(struct sock *ctnl, struct sk_buff *skb, | |||
1470 | if (ret == -EAGAIN) | 1470 | if (ret == -EAGAIN) |
1471 | ret = 1; | 1471 | ret = 1; |
1472 | 1472 | ||
1473 | return ret < 0 ? ret : ret > 0 ? 0 : -IPSET_ERR_EXIST; | 1473 | return (ret < 0 && ret != -ENOTEMPTY) ? ret : |
1474 | ret > 0 ? 0 : -IPSET_ERR_EXIST; | ||
1474 | } | 1475 | } |
1475 | 1476 | ||
1476 | /* Get headed data of a set */ | 1477 | /* Get headed data of a set */ |
diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c index 8371c2bac2e..09c744aa898 100644 --- a/net/netfilter/ipset/ip_set_list_set.c +++ b/net/netfilter/ipset/ip_set_list_set.c | |||
@@ -174,9 +174,13 @@ list_set_add(struct list_set *map, u32 i, ip_set_id_t id, | |||
174 | { | 174 | { |
175 | const struct set_elem *e = list_set_elem(map, i); | 175 | const struct set_elem *e = list_set_elem(map, i); |
176 | 176 | ||
177 | if (i == map->size - 1 && e->id != IPSET_INVALID_ID) | 177 | if (e->id != IPSET_INVALID_ID) { |
178 | /* Last element replaced: e.g. add new,before,last */ | 178 | const struct set_elem *x = list_set_elem(map, map->size - 1); |
179 | ip_set_put_byindex(e->id); | 179 | |
180 | /* Last element replaced or pushed off */ | ||
181 | if (x->id != IPSET_INVALID_ID) | ||
182 | ip_set_put_byindex(x->id); | ||
183 | } | ||
180 | if (with_timeout(map->timeout)) | 184 | if (with_timeout(map->timeout)) |
181 | list_elem_tadd(map, i, id, ip_set_timeout_set(timeout)); | 185 | list_elem_tadd(map, i, id, ip_set_timeout_set(timeout)); |
182 | else | 186 | else |
diff --git a/net/netfilter/ipvs/ip_vs_pe_sip.c b/net/netfilter/ipvs/ip_vs_pe_sip.c index 12475ef88da..e5920fb7ad0 100644 --- a/net/netfilter/ipvs/ip_vs_pe_sip.c +++ b/net/netfilter/ipvs/ip_vs_pe_sip.c | |||
@@ -37,14 +37,10 @@ static int get_callid(const char *dptr, unsigned int dataoff, | |||
37 | if (ret > 0) | 37 | if (ret > 0) |
38 | break; | 38 | break; |
39 | if (!ret) | 39 | if (!ret) |
40 | return 0; | 40 | return -EINVAL; |
41 | dataoff += *matchoff; | 41 | dataoff += *matchoff; |
42 | } | 42 | } |
43 | 43 | ||
44 | /* Empty callid is useless */ | ||
45 | if (!*matchlen) | ||
46 | return -EINVAL; | ||
47 | |||
48 | /* Too large is useless */ | 44 | /* Too large is useless */ |
49 | if (*matchlen > IP_VS_PEDATA_MAXLEN) | 45 | if (*matchlen > IP_VS_PEDATA_MAXLEN) |
50 | return -EINVAL; | 46 | return -EINVAL; |
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 884f2b39319..91527d5ba01 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c | |||
@@ -236,7 +236,9 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl, | |||
236 | /* We only allow helper re-assignment of the same sort since | 236 | /* We only allow helper re-assignment of the same sort since |
237 | * we cannot reallocate the helper extension area. | 237 | * we cannot reallocate the helper extension area. |
238 | */ | 238 | */ |
239 | if (help->helper != helper) { | 239 | struct nf_conntrack_helper *tmp = rcu_dereference(help->helper); |
240 | |||
241 | if (tmp && tmp->help != helper->help) { | ||
240 | RCU_INIT_POINTER(help->helper, NULL); | 242 | RCU_INIT_POINTER(help->helper, NULL); |
241 | goto out; | 243 | goto out; |
242 | } | 244 | } |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 627b0e50b23..a081915e053 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -1705,6 +1705,9 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
1705 | if (nlh->nlmsg_flags & NLM_F_CREATE) { | 1705 | if (nlh->nlmsg_flags & NLM_F_CREATE) { |
1706 | enum ip_conntrack_events events; | 1706 | enum ip_conntrack_events events; |
1707 | 1707 | ||
1708 | if (!cda[CTA_TUPLE_ORIG] || !cda[CTA_TUPLE_REPLY]) | ||
1709 | return -EINVAL; | ||
1710 | |||
1708 | ct = ctnetlink_create_conntrack(net, zone, cda, &otuple, | 1711 | ct = ctnetlink_create_conntrack(net, zone, cda, &otuple, |
1709 | &rtuple, u3); | 1712 | &rtuple, u3); |
1710 | if (IS_ERR(ct)) | 1713 | if (IS_ERR(ct)) |
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index df8f4f28448..b4e0d1c23cd 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c | |||
@@ -1547,7 +1547,7 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff, | |||
1547 | 1547 | ||
1548 | msglen = origlen = end - dptr; | 1548 | msglen = origlen = end - dptr; |
1549 | if (msglen > datalen) | 1549 | if (msglen > datalen) |
1550 | return NF_DROP; | 1550 | return NF_ACCEPT; |
1551 | 1551 | ||
1552 | ret = process_sip_msg(skb, ct, protoff, dataoff, | 1552 | ret = process_sip_msg(skb, ct, protoff, dataoff, |
1553 | &dptr, &msglen); | 1553 | &dptr, &msglen); |
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c index 5f2f9109f46..4bc2aafcd41 100644 --- a/net/netfilter/nf_nat_core.c +++ b/net/netfilter/nf_nat_core.c | |||
@@ -468,33 +468,22 @@ EXPORT_SYMBOL_GPL(nf_nat_packet); | |||
468 | struct nf_nat_proto_clean { | 468 | struct nf_nat_proto_clean { |
469 | u8 l3proto; | 469 | u8 l3proto; |
470 | u8 l4proto; | 470 | u8 l4proto; |
471 | bool hash; | ||
472 | }; | 471 | }; |
473 | 472 | ||
474 | /* Clear NAT section of all conntracks, in case we're loaded again. */ | 473 | /* kill conntracks with affected NAT section */ |
475 | static int nf_nat_proto_clean(struct nf_conn *i, void *data) | 474 | static int nf_nat_proto_remove(struct nf_conn *i, void *data) |
476 | { | 475 | { |
477 | const struct nf_nat_proto_clean *clean = data; | 476 | const struct nf_nat_proto_clean *clean = data; |
478 | struct nf_conn_nat *nat = nfct_nat(i); | 477 | struct nf_conn_nat *nat = nfct_nat(i); |
479 | 478 | ||
480 | if (!nat) | 479 | if (!nat) |
481 | return 0; | 480 | return 0; |
482 | if (!(i->status & IPS_SRC_NAT_DONE)) | 481 | |
483 | return 0; | ||
484 | if ((clean->l3proto && nf_ct_l3num(i) != clean->l3proto) || | 482 | if ((clean->l3proto && nf_ct_l3num(i) != clean->l3proto) || |
485 | (clean->l4proto && nf_ct_protonum(i) != clean->l4proto)) | 483 | (clean->l4proto && nf_ct_protonum(i) != clean->l4proto)) |
486 | return 0; | 484 | return 0; |
487 | 485 | ||
488 | if (clean->hash) { | 486 | return i->status & IPS_NAT_MASK ? 1 : 0; |
489 | spin_lock_bh(&nf_nat_lock); | ||
490 | hlist_del_rcu(&nat->bysource); | ||
491 | spin_unlock_bh(&nf_nat_lock); | ||
492 | } else { | ||
493 | memset(nat, 0, sizeof(*nat)); | ||
494 | i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | | ||
495 | IPS_SEQ_ADJUST); | ||
496 | } | ||
497 | return 0; | ||
498 | } | 487 | } |
499 | 488 | ||
500 | static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto) | 489 | static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto) |
@@ -506,16 +495,8 @@ static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto) | |||
506 | struct net *net; | 495 | struct net *net; |
507 | 496 | ||
508 | rtnl_lock(); | 497 | rtnl_lock(); |
509 | /* Step 1 - remove from bysource hash */ | ||
510 | clean.hash = true; | ||
511 | for_each_net(net) | 498 | for_each_net(net) |
512 | nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean); | 499 | nf_ct_iterate_cleanup(net, nf_nat_proto_remove, &clean); |
513 | synchronize_rcu(); | ||
514 | |||
515 | /* Step 2 - clean NAT section */ | ||
516 | clean.hash = false; | ||
517 | for_each_net(net) | ||
518 | nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean); | ||
519 | rtnl_unlock(); | 500 | rtnl_unlock(); |
520 | } | 501 | } |
521 | 502 | ||
@@ -527,16 +508,9 @@ static void nf_nat_l3proto_clean(u8 l3proto) | |||
527 | struct net *net; | 508 | struct net *net; |
528 | 509 | ||
529 | rtnl_lock(); | 510 | rtnl_lock(); |
530 | /* Step 1 - remove from bysource hash */ | ||
531 | clean.hash = true; | ||
532 | for_each_net(net) | ||
533 | nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean); | ||
534 | synchronize_rcu(); | ||
535 | 511 | ||
536 | /* Step 2 - clean NAT section */ | ||
537 | clean.hash = false; | ||
538 | for_each_net(net) | 512 | for_each_net(net) |
539 | nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean); | 513 | nf_ct_iterate_cleanup(net, nf_nat_proto_remove, &clean); |
540 | rtnl_unlock(); | 514 | rtnl_unlock(); |
541 | } | 515 | } |
542 | 516 | ||
@@ -774,7 +748,7 @@ static void __net_exit nf_nat_net_exit(struct net *net) | |||
774 | { | 748 | { |
775 | struct nf_nat_proto_clean clean = {}; | 749 | struct nf_nat_proto_clean clean = {}; |
776 | 750 | ||
777 | nf_ct_iterate_cleanup(net, &nf_nat_proto_clean, &clean); | 751 | nf_ct_iterate_cleanup(net, &nf_nat_proto_remove, &clean); |
778 | synchronize_rcu(); | 752 | synchronize_rcu(); |
779 | nf_ct_free_hashtable(net->ct.nat_bysource, net->ct.nat_htable_size); | 753 | nf_ct_free_hashtable(net->ct.nat_bysource, net->ct.nat_htable_size); |
780 | } | 754 | } |