History

netfilter: nf_ct_helper: warn when not applying default helper assignment

Commit 3bb398d925 ("netfilter: nf_ct_helper: disable automatic helper assignment") is causing behavior regressions in firewalls, as traffic handled by conntrack helpers is now by default not passed through even though it was before due to missing CT targets (which were not necessary before this commit). The default had to be switched off due to security reasons [1] [2] and therefore should stay the way it is, but let's be friendly to firewall admins and issue a warning the first time we're in situation where packet would be likely passed through with the old default but we're likely going to drop it on the floor now. Rewrite the code a little bit as suggested by Linus, so that we avoid spaghettiing the code even more -- namely the whole decision making process regarding helper selection (either automatic or not) is being separated, so that the whole logic can be simplified and code (condition) duplication reduced. [1] https://cansecwest.com/csw12/conntrack-attack.pdf [2] https://home.regit.org/netfilter-en/secure-use-of-helpers/

Jiri Kosina committed 9 years ago

Commit dfe75ff1 parent cafe8df1 file · +26 −13Browse files

Unified · Split

net/netfilter/nf_conntrack_helper.c+26−13
@@ -188,6 +188,26 @@ nf_ct_helper_ext_add(struct nf_conn *ct, · 187 unmodified lines
188188 }
189189 EXPORT_SYMBOL_GPL(nf_ct_helper_ext_add);
190190
191+static struct nf_conntrack_helper *
192+nf_ct_lookup_helper(struct nf_conn *ct, struct net *net)
193+{
194+ if (!net->ct.sysctl_auto_assign_helper) {
195+ if (net->ct.auto_assign_helper_warned)
196+ return NULL;
197+ if (!__nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple))
198+ return NULL;
199+ pr_info("nf_conntrack: default automatic helper assignment "
200+ "has been turned off for security reasons and CT-based "
201+ " firewall rule not found. Use the iptables CT target "
202+ "to attach helpers instead.\n");
203+ net->ct.auto_assign_helper_warned = 1;
204+ return NULL;
205+ }
206+
207+ return __nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
208+}
209+
210+
191211 int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
192212 gfp_t flags)
193213 {
@@ -213,21 +233,14 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl, · 19 unmodified lines
213233 }
214234
215235 help = nfct_help(ct);
216− if (net->ct.sysctl_auto_assign_helper && helper == NULL) {
217− helper = __nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
218− if (unlikely(!net->ct.auto_assign_helper_warned && helper)) {
219− pr_info("nf_conntrack: automatic helper "
220− "assignment is deprecated and it will "
221− "be removed soon. Use the iptables CT target "
222− "to attach helpers instead.\n");
223− net->ct.auto_assign_helper_warned = true;
224− }
225− }
226236
227237 if (helper == NULL) {
228− if (help)
229− RCU_INIT_POINTER(help->helper, NULL);
230− return 0;
238+ helper = nf_ct_lookup_helper(ct, net);
239+ if (helper == NULL) {
240+ if (help)
241+ RCU_INIT_POINTER(help->helper, NULL);
242+ return 0;
243+ }
231244 }
232245
233246 if (help == NULL) {