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
188}188}
189EXPORT_SYMBOL_GPL(nf_ct_helper_ext_add);189EXPORT_SYMBOL_GPL(nf_ct_helper_ext_add);
190 190
191static struct nf_conntrack_helper *
192nf_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
191int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,211int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
192 gfp_t flags)212 gfp_t flags)
193{213{
@@ -213,21 +233,14 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl, · 19 unmodified lines
213 }233 }
214 234
215 help = nfct_help(ct);235 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 }
226 236
227 if (helper == NULL) {237 if (helper == NULL) {
228 if (help)238 helper = nf_ct_lookup_helper(ct, net);
229 RCU_INIT_POINTER(help->helper, NULL);239 if (helper == NULL) {
230 return 0;240 if (help)
241 RCU_INIT_POINTER(help->helper, NULL);
242 return 0;
243 }
231 }244 }
232 245
233 if (help == NULL) {246 if (help == NULL) {