diff options
| author | Patrick McHardy <kaber@trash.net> | 2010-02-03 07:41:29 -0500 |
|---|---|---|
| committer | Patrick McHardy <kaber@trash.net> | 2010-02-03 07:41:29 -0500 |
| commit | 794e68716bab578ae8f8912dc934496d7c7abc90 (patch) | |
| tree | 22cd94a58059a00711fad3570c92c820665a882b /net/netfilter | |
| parent | 2eff25c18c3d332d3c4dd98f2ac9b7114e9771b0 (diff) | |
netfilter: ctnetlink: only assign helpers for matching protocols
Make sure not to assign a helper for a different network or transport
layer protocol to a connection.
Additionally change expectation deletion by helper to compare the name
directly - there might be multiple helper registrations using the same
name, currently one of them is chosen in an unpredictable manner and
only those expectations are removed.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/netfilter')
| -rw-r--r-- | net/netfilter/nf_conntrack_helper.c | 8 | ||||
| -rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 23 |
2 files changed, 16 insertions, 15 deletions
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 65c2a7bc3afc..c0e461f466ae 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c | |||
| @@ -65,7 +65,7 @@ __nf_ct_helper_find(const struct nf_conntrack_tuple *tuple) | |||
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | struct nf_conntrack_helper * | 67 | struct nf_conntrack_helper * |
| 68 | __nf_conntrack_helper_find_byname(const char *name) | 68 | __nf_conntrack_helper_find(const char *name, u16 l3num, u8 protonum) |
| 69 | { | 69 | { |
| 70 | struct nf_conntrack_helper *h; | 70 | struct nf_conntrack_helper *h; |
| 71 | struct hlist_node *n; | 71 | struct hlist_node *n; |
| @@ -73,13 +73,15 @@ __nf_conntrack_helper_find_byname(const char *name) | |||
| 73 | 73 | ||
| 74 | for (i = 0; i < nf_ct_helper_hsize; i++) { | 74 | for (i = 0; i < nf_ct_helper_hsize; i++) { |
| 75 | hlist_for_each_entry_rcu(h, n, &nf_ct_helper_hash[i], hnode) { | 75 | hlist_for_each_entry_rcu(h, n, &nf_ct_helper_hash[i], hnode) { |
| 76 | if (!strcmp(h->name, name)) | 76 | if (!strcmp(h->name, name) && |
| 77 | h->tuple.src.l3num == l3num && | ||
| 78 | h->tuple.dst.protonum == protonum) | ||
| 77 | return h; | 79 | return h; |
| 78 | } | 80 | } |
| 79 | } | 81 | } |
| 80 | return NULL; | 82 | return NULL; |
| 81 | } | 83 | } |
| 82 | EXPORT_SYMBOL_GPL(__nf_conntrack_helper_find_byname); | 84 | EXPORT_SYMBOL_GPL(__nf_conntrack_helper_find); |
| 83 | 85 | ||
| 84 | struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp) | 86 | struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp) |
| 85 | { | 87 | { |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 79478dfba27e..16f86d61e5d1 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
| @@ -1001,7 +1001,8 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[]) | |||
| 1001 | return 0; | 1001 | return 0; |
| 1002 | } | 1002 | } |
| 1003 | 1003 | ||
| 1004 | helper = __nf_conntrack_helper_find_byname(helpname); | 1004 | helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct), |
| 1005 | nf_ct_protonum(ct)); | ||
| 1005 | if (helper == NULL) { | 1006 | if (helper == NULL) { |
| 1006 | #ifdef CONFIG_MODULES | 1007 | #ifdef CONFIG_MODULES |
| 1007 | spin_unlock_bh(&nf_conntrack_lock); | 1008 | spin_unlock_bh(&nf_conntrack_lock); |
| @@ -1012,7 +1013,8 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[]) | |||
| 1012 | } | 1013 | } |
| 1013 | 1014 | ||
| 1014 | spin_lock_bh(&nf_conntrack_lock); | 1015 | spin_lock_bh(&nf_conntrack_lock); |
| 1015 | helper = __nf_conntrack_helper_find_byname(helpname); | 1016 | helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct), |
| 1017 | nf_ct_protonum(ct)); | ||
| 1016 | if (helper) | 1018 | if (helper) |
| 1017 | return -EAGAIN; | 1019 | return -EAGAIN; |
| 1018 | #endif | 1020 | #endif |
| @@ -1211,7 +1213,8 @@ ctnetlink_create_conntrack(struct net *net, | |||
| 1211 | if (err < 0) | 1213 | if (err < 0) |
| 1212 | goto err2; | 1214 | goto err2; |
| 1213 | 1215 | ||
| 1214 | helper = __nf_conntrack_helper_find_byname(helpname); | 1216 | helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct), |
| 1217 | nf_ct_protonum(ct)); | ||
| 1215 | if (helper == NULL) { | 1218 | if (helper == NULL) { |
| 1216 | rcu_read_unlock(); | 1219 | rcu_read_unlock(); |
| 1217 | #ifdef CONFIG_MODULES | 1220 | #ifdef CONFIG_MODULES |
| @@ -1221,7 +1224,9 @@ ctnetlink_create_conntrack(struct net *net, | |||
| 1221 | } | 1224 | } |
| 1222 | 1225 | ||
| 1223 | rcu_read_lock(); | 1226 | rcu_read_lock(); |
| 1224 | helper = __nf_conntrack_helper_find_byname(helpname); | 1227 | helper = __nf_conntrack_helper_find(helpname, |
| 1228 | nf_ct_l3num(ct), | ||
| 1229 | nf_ct_protonum(ct)); | ||
| 1225 | if (helper) { | 1230 | if (helper) { |
| 1226 | err = -EAGAIN; | 1231 | err = -EAGAIN; |
| 1227 | goto err2; | 1232 | goto err2; |
| @@ -1714,7 +1719,6 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, | |||
| 1714 | struct net *net = sock_net(ctnl); | 1719 | struct net *net = sock_net(ctnl); |
| 1715 | struct nf_conntrack_expect *exp; | 1720 | struct nf_conntrack_expect *exp; |
| 1716 | struct nf_conntrack_tuple tuple; | 1721 | struct nf_conntrack_tuple tuple; |
| 1717 | struct nf_conntrack_helper *h; | ||
| 1718 | struct nfgenmsg *nfmsg = nlmsg_data(nlh); | 1722 | struct nfgenmsg *nfmsg = nlmsg_data(nlh); |
| 1719 | struct hlist_node *n, *next; | 1723 | struct hlist_node *n, *next; |
| 1720 | u_int8_t u3 = nfmsg->nfgen_family; | 1724 | u_int8_t u3 = nfmsg->nfgen_family; |
| @@ -1751,18 +1755,13 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, | |||
| 1751 | 1755 | ||
| 1752 | /* delete all expectations for this helper */ | 1756 | /* delete all expectations for this helper */ |
| 1753 | spin_lock_bh(&nf_conntrack_lock); | 1757 | spin_lock_bh(&nf_conntrack_lock); |
| 1754 | h = __nf_conntrack_helper_find_byname(name); | ||
| 1755 | if (!h) { | ||
| 1756 | spin_unlock_bh(&nf_conntrack_lock); | ||
| 1757 | return -EOPNOTSUPP; | ||
| 1758 | } | ||
| 1759 | for (i = 0; i < nf_ct_expect_hsize; i++) { | 1758 | for (i = 0; i < nf_ct_expect_hsize; i++) { |
| 1760 | hlist_for_each_entry_safe(exp, n, next, | 1759 | hlist_for_each_entry_safe(exp, n, next, |
| 1761 | &net->ct.expect_hash[i], | 1760 | &net->ct.expect_hash[i], |
| 1762 | hnode) { | 1761 | hnode) { |
| 1763 | m_help = nfct_help(exp->master); | 1762 | m_help = nfct_help(exp->master); |
| 1764 | if (m_help->helper == h | 1763 | if (!strcmp(m_help->helper->name, name) && |
| 1765 | && del_timer(&exp->timeout)) { | 1764 | del_timer(&exp->timeout)) { |
| 1766 | nf_ct_unlink_expect(exp); | 1765 | nf_ct_unlink_expect(exp); |
| 1767 | nf_ct_expect_put(exp); | 1766 | nf_ct_expect_put(exp); |
| 1768 | } | 1767 | } |
