]>
Commit | Line | Data |
---|---|---|
850550b6 GKH |
1 | From dfe75ff8ca74f54b0fa5a326a1aa9afa485ed802 Mon Sep 17 00:00:00 2001 |
2 | From: Jiri Kosina <jkosina@suse.cz> | |
3 | Date: Wed, 1 Feb 2017 21:01:54 +0100 | |
4 | Subject: netfilter: nf_ct_helper: warn when not applying default helper assignment | |
5 | ||
6 | From: Jiri Kosina <jkosina@suse.cz> | |
7 | ||
8 | commit dfe75ff8ca74f54b0fa5a326a1aa9afa485ed802 upstream. | |
9 | ||
10 | Commit 3bb398d925 ("netfilter: nf_ct_helper: disable automatic helper | |
11 | assignment") is causing behavior regressions in firewalls, as traffic | |
12 | handled by conntrack helpers is now by default not passed through even | |
13 | though it was before due to missing CT targets (which were not necessary | |
14 | before this commit). | |
15 | ||
16 | The default had to be switched off due to security reasons [1] [2] and | |
17 | therefore should stay the way it is, but let's be friendly to firewall | |
18 | admins and issue a warning the first time we're in situation where packet | |
19 | would be likely passed through with the old default but we're likely going | |
20 | to drop it on the floor now. | |
21 | ||
22 | Rewrite the code a little bit as suggested by Linus, so that we avoid | |
23 | spaghettiing the code even more -- namely the whole decision making | |
24 | process regarding helper selection (either automatic or not) is being | |
25 | separated, so that the whole logic can be simplified and code (condition) | |
26 | duplication reduced. | |
27 | ||
28 | [1] https://cansecwest.com/csw12/conntrack-attack.pdf | |
29 | [2] https://home.regit.org/netfilter-en/secure-use-of-helpers/ | |
30 | ||
31 | Signed-off-by: Jiri Kosina <jkosina@suse.cz> | |
32 | Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | |
33 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
34 | ||
35 | --- | |
36 | net/netfilter/nf_conntrack_helper.c | 39 ++++++++++++++++++++++++------------ | |
37 | 1 file changed, 26 insertions(+), 13 deletions(-) | |
38 | ||
39 | --- a/net/netfilter/nf_conntrack_helper.c | |
40 | +++ b/net/netfilter/nf_conntrack_helper.c | |
41 | @@ -188,6 +188,26 @@ nf_ct_helper_ext_add(struct nf_conn *ct, | |
42 | } | |
43 | EXPORT_SYMBOL_GPL(nf_ct_helper_ext_add); | |
44 | ||
45 | +static struct nf_conntrack_helper * | |
46 | +nf_ct_lookup_helper(struct nf_conn *ct, struct net *net) | |
47 | +{ | |
48 | + if (!net->ct.sysctl_auto_assign_helper) { | |
49 | + if (net->ct.auto_assign_helper_warned) | |
50 | + return NULL; | |
51 | + if (!__nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple)) | |
52 | + return NULL; | |
53 | + pr_info("nf_conntrack: default automatic helper assignment " | |
54 | + "has been turned off for security reasons and CT-based " | |
55 | + " firewall rule not found. Use the iptables CT target " | |
56 | + "to attach helpers instead.\n"); | |
57 | + net->ct.auto_assign_helper_warned = 1; | |
58 | + return NULL; | |
59 | + } | |
60 | + | |
61 | + return __nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); | |
62 | +} | |
63 | + | |
64 | + | |
65 | int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl, | |
66 | gfp_t flags) | |
67 | { | |
68 | @@ -213,21 +233,14 @@ int __nf_ct_try_assign_helper(struct nf_ | |
69 | } | |
70 | ||
71 | help = nfct_help(ct); | |
72 | - if (net->ct.sysctl_auto_assign_helper && helper == NULL) { | |
73 | - helper = __nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); | |
74 | - if (unlikely(!net->ct.auto_assign_helper_warned && helper)) { | |
75 | - pr_info("nf_conntrack: automatic helper " | |
76 | - "assignment is deprecated and it will " | |
77 | - "be removed soon. Use the iptables CT target " | |
78 | - "to attach helpers instead.\n"); | |
79 | - net->ct.auto_assign_helper_warned = true; | |
80 | - } | |
81 | - } | |
82 | ||
83 | if (helper == NULL) { | |
84 | - if (help) | |
85 | - RCU_INIT_POINTER(help->helper, NULL); | |
86 | - return 0; | |
87 | + helper = nf_ct_lookup_helper(ct, net); | |
88 | + if (helper == NULL) { | |
89 | + if (help) | |
90 | + RCU_INIT_POINTER(help->helper, NULL); | |
91 | + return 0; | |
92 | + } | |
93 | } | |
94 | ||
95 | if (help == NULL) { |