Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf

Pablo Neira Ayuso says:

====================
Netfilter fixes for net

The following patchset contains Netfilter fixes for your net tree,
they are:

1) Revisit warning logic when not applying default helper assignment.
Jiri Kosina considers we are breaking existing setups and not warning
our users accordinly now that automatic helper assignment has been
turned off by default. So let's make him happy by spotting the warning
by when we find a helper but we cannot attach, instead of warning on the
former deprecated behaviour. Patch from Jiri Kosina.

2) Two patches to fix regression in ctnetlink interfaces with
nfnetlink_queue. Specifically, perform more relaxed in CTA_STATUS
and do not bail out if CTA_HELP indicates the same helper that we
already have. Patches from Kevin Cernekee.

3) A couple of bugfixes for ipset via Jozsef Kadlecsik. Due to wrong
index logic in hash set types and null pointer exception in the
list:set type.

4) hashlimit bails out with correct userspace parameters due to wrong
arithmetics in the code that avoids "divide by zero" when
transforming the userspace timing in milliseconds to token credits.
Patch from Alban Browaeys.

5) Fix incorrect NFQA_VLAN_MAX definition, patch from
Ken-ichirou MATSUZAWA.

6) Don't not declare nfnetlink batch error list as static, since this
may be used by several subsystems at the same time. Patch from
Liping Zhang.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+85 -39
+4
include/uapi/linux/netfilter/nf_conntrack_common.h
··· 82 82 IPS_DYING_BIT = 9, 83 83 IPS_DYING = (1 << IPS_DYING_BIT), 84 84 85 + /* Bits that cannot be altered from userland. */ 86 + IPS_UNCHANGEABLE_MASK = (IPS_NAT_DONE_MASK | IPS_NAT_MASK | 87 + IPS_EXPECTED | IPS_CONFIRMED | IPS_DYING), 88 + 85 89 /* Connection has fixed timeout. */ 86 90 IPS_FIXED_TIMEOUT_BIT = 10, 87 91 IPS_FIXED_TIMEOUT = (1 << IPS_FIXED_TIMEOUT_BIT),
+1 -1
net/netfilter/ipset/ip_set_hash_gen.h
··· 897 897 continue; 898 898 data = ahash_data(n, j, dsize); 899 899 memcpy(tmp->value + k * dsize, data, dsize); 900 - set_bit(j, tmp->used); 900 + set_bit(k, tmp->used); 901 901 k++; 902 902 } 903 903 tmp->pos = k;
+6 -3
net/netfilter/ipset/ip_set_list_set.c
··· 260 260 else 261 261 prev = e; 262 262 } 263 + 264 + /* If before/after is used on an empty set */ 265 + if ((d->before > 0 && !next) || 266 + (d->before < 0 && !prev)) 267 + return -IPSET_ERR_REF_EXIST; 268 + 263 269 /* Re-add already existing element */ 264 270 if (n) { 265 - if ((d->before > 0 && !next) || 266 - (d->before < 0 && !prev)) 267 - return -IPSET_ERR_REF_EXIST; 268 271 if (!flag_exist) 269 272 return -IPSET_ERR_EXIST; 270 273 /* Update extensions */
+26 -13
net/netfilter/nf_conntrack_helper.c
··· 188 188 } 189 189 EXPORT_SYMBOL_GPL(nf_ct_helper_ext_add); 190 190 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 + 191 211 int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl, 192 212 gfp_t flags) 193 213 { ··· 233 213 } 234 214 235 215 help = nfct_help(ct); 236 - if (net->ct.sysctl_auto_assign_helper && helper == NULL) { 237 - helper = __nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); 238 - if (unlikely(!net->ct.auto_assign_helper_warned && helper)) { 239 - pr_info("nf_conntrack: automatic helper " 240 - "assignment is deprecated and it will " 241 - "be removed soon. Use the iptables CT target " 242 - "to attach helpers instead.\n"); 243 - net->ct.auto_assign_helper_warned = true; 244 - } 245 - } 246 216 247 217 if (helper == NULL) { 248 - if (help) 249 - RCU_INIT_POINTER(help->helper, NULL); 250 - return 0; 218 + helper = nf_ct_lookup_helper(ct, net); 219 + if (helper == NULL) { 220 + if (help) 221 + RCU_INIT_POINTER(help->helper, NULL); 222 + return 0; 223 + } 251 224 } 252 225 253 226 if (help == NULL) {
+38 -5
net/netfilter/nf_conntrack_netlink.c
··· 1478 1478 struct nlattr *helpinfo = NULL; 1479 1479 int err; 1480 1480 1481 - /* don't change helper of sibling connections */ 1482 - if (ct->master) 1483 - return -EBUSY; 1484 - 1485 1481 err = ctnetlink_parse_help(cda[CTA_HELP], &helpname, &helpinfo); 1486 1482 if (err < 0) 1487 1483 return err; 1484 + 1485 + /* don't change helper of sibling connections */ 1486 + if (ct->master) { 1487 + /* If we try to change the helper to the same thing twice, 1488 + * treat the second attempt as a no-op instead of returning 1489 + * an error. 1490 + */ 1491 + if (help && help->helper && 1492 + !strcmp(help->helper->name, helpname)) 1493 + return 0; 1494 + else 1495 + return -EBUSY; 1496 + } 1488 1497 1489 1498 if (!strcmp(helpname, "")) { 1490 1499 if (help && help->helper) { ··· 2279 2270 } 2280 2271 2281 2272 static int 2273 + ctnetlink_update_status(struct nf_conn *ct, const struct nlattr * const cda[]) 2274 + { 2275 + unsigned int status = ntohl(nla_get_be32(cda[CTA_STATUS])); 2276 + unsigned long d = ct->status ^ status; 2277 + 2278 + if (d & IPS_SEEN_REPLY && !(status & IPS_SEEN_REPLY)) 2279 + /* SEEN_REPLY bit can only be set */ 2280 + return -EBUSY; 2281 + 2282 + if (d & IPS_ASSURED && !(status & IPS_ASSURED)) 2283 + /* ASSURED bit can only be set */ 2284 + return -EBUSY; 2285 + 2286 + /* This check is less strict than ctnetlink_change_status() 2287 + * because callers often flip IPS_EXPECTED bits when sending 2288 + * an NFQA_CT attribute to the kernel. So ignore the 2289 + * unchangeable bits but do not error out. 2290 + */ 2291 + ct->status = (status & ~IPS_UNCHANGEABLE_MASK) | 2292 + (ct->status & IPS_UNCHANGEABLE_MASK); 2293 + return 0; 2294 + } 2295 + 2296 + static int 2282 2297 ctnetlink_glue_parse_ct(const struct nlattr *cda[], struct nf_conn *ct) 2283 2298 { 2284 2299 int err; ··· 2313 2280 return err; 2314 2281 } 2315 2282 if (cda[CTA_STATUS]) { 2316 - err = ctnetlink_change_status(ct, cda); 2283 + err = ctnetlink_update_status(ct, cda); 2317 2284 if (err < 0) 2318 2285 return err; 2319 2286 }
+1 -1
net/netfilter/nfnetlink.c
··· 279 279 struct net *net = sock_net(skb->sk); 280 280 const struct nfnetlink_subsystem *ss; 281 281 const struct nfnl_callback *nc; 282 - static LIST_HEAD(err_list); 282 + LIST_HEAD(err_list); 283 283 u32 status; 284 284 int err; 285 285
+8 -15
net/netfilter/xt_hashlimit.c
··· 463 463 /* Precision saver. */ 464 464 static u64 user2credits(u64 user, int revision) 465 465 { 466 - if (revision == 1) { 467 - /* If multiplying would overflow... */ 468 - if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY_v1)) 469 - /* Divide first. */ 470 - return div64_u64(user, XT_HASHLIMIT_SCALE) 471 - * HZ * CREDITS_PER_JIFFY_v1; 466 + u64 scale = (revision == 1) ? 467 + XT_HASHLIMIT_SCALE : XT_HASHLIMIT_SCALE_v2; 468 + u64 cpj = (revision == 1) ? 469 + CREDITS_PER_JIFFY_v1 : CREDITS_PER_JIFFY; 472 470 473 - return div64_u64(user * HZ * CREDITS_PER_JIFFY_v1, 474 - XT_HASHLIMIT_SCALE); 475 - } else { 476 - if (user > 0xFFFFFFFFFFFFFFFFULL / (HZ*CREDITS_PER_JIFFY)) 477 - return div64_u64(user, XT_HASHLIMIT_SCALE_v2) 478 - * HZ * CREDITS_PER_JIFFY; 471 + /* Avoid overflow: divide the constant operands first */ 472 + if (scale >= HZ * cpj) 473 + return div64_u64(user, div64_u64(scale, HZ * cpj)); 479 474 480 - return div64_u64(user * HZ * CREDITS_PER_JIFFY, 481 - XT_HASHLIMIT_SCALE_v2); 482 - } 475 + return user * div64_u64(HZ * cpj, scale); 483 476 } 484 477 485 478 static u32 user2credits_byte(u32 user)