Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Browse files Browse the repository at this point in the history
Pablo Neira Ayuso says:

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

The following patchset contains large batch with Netfilter fixes for
your net tree, mostly due to syzbot report fixups and pr_err()
ratelimiting, more specifically, they are:

1) Get rid of superfluous unnecessary check in x_tables before vmalloc(),
   we don't hit BUG there anymore, patch from Michal Hock, suggested by
   Andrew Morton.

2) Race condition in proc file creation in ipt_CLUSTERIP, from Cong Wang.

3) Drop socket lock that results in circular locking dependency, patch
   from Paolo Abeni.

4) Drop packet if case of malformed blob that makes backpointer jump
   in x_tables, from Florian Westphal.

5) Fix refcount leak due to race in ipt_CLUSTERIP in
   clusterip_config_find_get(), from Cong Wang.

6) Several patches to ratelimit pr_err() for x_tables since this can be
   a problem where CAP_NET_ADMIN semantics can protect us in untrusted
   namespace, from Florian Westphal.

7) Missing .gitignore update for new autogenerated asn1 state machine
   for the SNMP NAT helper, from Zhu Lingshan.

8) Missing timer initialization in xt_LED, from Paolo Abeni.

9) Do not allow negative port range in NAT, also from Paolo.

10) Lock imbalance in the xt_hashlimit rate match mode, patch from
    Eric Dumazet.

11) Initialize workqueue before timer in the idletimer match,
    from Eric Dumazet.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Feb 21, 2018
2 parents 5ae437a + cfc2c74 commit 943a0d4
Show file tree
Hide file tree
Showing 55 changed files with 314 additions and 300 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,7 @@ all.config

# Kdevelop4
*.kdev4

#Automatically generated by ASN.1 compiler
net/ipv4/netfilter/nf_nat_snmp_basic-asn1.c
net/ipv4/netfilter/nf_nat_snmp_basic-asn1.h
10 changes: 5 additions & 5 deletions net/bridge/netfilter/ebt_among.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,17 +187,17 @@ static int ebt_among_mt_check(const struct xt_mtchk_param *par)
expected_length += ebt_mac_wormhash_size(wh_src);

if (em->match_size != EBT_ALIGN(expected_length)) {
pr_info("wrong size: %d against expected %d, rounded to %zd\n",
em->match_size, expected_length,
EBT_ALIGN(expected_length));
pr_err_ratelimited("wrong size: %d against expected %d, rounded to %zd\n",
em->match_size, expected_length,
EBT_ALIGN(expected_length));
return -EINVAL;
}
if (wh_dst && (err = ebt_mac_wormhash_check_integrity(wh_dst))) {
pr_info("dst integrity fail: %x\n", -err);
pr_err_ratelimited("dst integrity fail: %x\n", -err);
return -EINVAL;
}
if (wh_src && (err = ebt_mac_wormhash_check_integrity(wh_src))) {
pr_info("src integrity fail: %x\n", -err);
pr_err_ratelimited("src integrity fail: %x\n", -err);
return -EINVAL;
}
return 0;
Expand Down
4 changes: 2 additions & 2 deletions net/bridge/netfilter/ebt_limit.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ static int ebt_limit_mt_check(const struct xt_mtchk_param *par)
/* Check for overflow. */
if (info->burst == 0 ||
user2credits(info->avg * info->burst) < user2credits(info->avg)) {
pr_info("overflow, try lower: %u/%u\n",
info->avg, info->burst);
pr_info_ratelimited("overflow, try lower: %u/%u\n",
info->avg, info->burst);
return -EINVAL;
}

Expand Down
7 changes: 1 addition & 6 deletions net/ipv4/ip_sockglue.c
Original file line number Diff line number Diff line change
Expand Up @@ -1567,10 +1567,7 @@ int ip_getsockopt(struct sock *sk, int level,
if (get_user(len, optlen))
return -EFAULT;

lock_sock(sk);
err = nf_getsockopt(sk, PF_INET, optname, optval,
&len);
release_sock(sk);
err = nf_getsockopt(sk, PF_INET, optname, optval, &len);
if (err >= 0)
err = put_user(len, optlen);
return err;
Expand Down Expand Up @@ -1602,9 +1599,7 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname,
if (get_user(len, optlen))
return -EFAULT;

lock_sock(sk);
err = compat_nf_getsockopt(sk, PF_INET, optname, optval, &len);
release_sock(sk);
if (err >= 0)
err = put_user(len, optlen);
return err;
Expand Down
4 changes: 4 additions & 0 deletions net/ipv4/netfilter/arp_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,10 @@ unsigned int arpt_do_table(struct sk_buff *skb,
}
if (table_base + v
!= arpt_next_entry(e)) {
if (unlikely(stackidx >= private->stacksize)) {
verdict = NF_DROP;
break;
}
jumpstack[stackidx++] = e;
}

Expand Down
7 changes: 6 additions & 1 deletion net/ipv4/netfilter/ip_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,13 @@ ipt_do_table(struct sk_buff *skb,
continue;
}
if (table_base + v != ipt_next_entry(e) &&
!(e->ip.flags & IPT_F_GOTO))
!(e->ip.flags & IPT_F_GOTO)) {
if (unlikely(stackidx >= private->stacksize)) {
verdict = NF_DROP;
break;
}
jumpstack[stackidx++] = e;
}

e = get_entry(table_base, v);
continue;
Expand Down
20 changes: 12 additions & 8 deletions net/ipv4/netfilter/ipt_CLUSTERIP.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,19 +107,19 @@ clusterip_config_entry_put(struct net *net, struct clusterip_config *c)

local_bh_disable();
if (refcount_dec_and_lock(&c->entries, &cn->lock)) {
list_del_rcu(&c->list);
spin_unlock(&cn->lock);
local_bh_enable();

unregister_netdevice_notifier(&c->notifier);

/* In case anyone still accesses the file, the open/close
* functions are also incrementing the refcount on their own,
* so it's safe to remove the entry even if it's in use. */
#ifdef CONFIG_PROC_FS
if (cn->procdir)
proc_remove(c->pde);
#endif
list_del_rcu(&c->list);
spin_unlock(&cn->lock);
local_bh_enable();

unregister_netdevice_notifier(&c->notifier);

return;
}
local_bh_enable();
Expand Down Expand Up @@ -154,8 +154,12 @@ clusterip_config_find_get(struct net *net, __be32 clusterip, int entry)
#endif
if (unlikely(!refcount_inc_not_zero(&c->refcount)))
c = NULL;
else if (entry)
refcount_inc(&c->entries);
else if (entry) {
if (unlikely(!refcount_inc_not_zero(&c->entries))) {
clusterip_config_put(c);
c = NULL;
}
}
}
rcu_read_unlock_bh();

Expand Down
12 changes: 5 additions & 7 deletions net/ipv4/netfilter/ipt_ECN.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,15 @@ static int ecn_tg_check(const struct xt_tgchk_param *par)
const struct ipt_ECN_info *einfo = par->targinfo;
const struct ipt_entry *e = par->entryinfo;

if (einfo->operation & IPT_ECN_OP_MASK) {
pr_info("unsupported ECN operation %x\n", einfo->operation);
if (einfo->operation & IPT_ECN_OP_MASK)
return -EINVAL;
}
if (einfo->ip_ect & ~IPT_ECN_IP_MASK) {
pr_info("new ECT codepoint %x out of mask\n", einfo->ip_ect);

if (einfo->ip_ect & ~IPT_ECN_IP_MASK)
return -EINVAL;
}

if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR)) &&
(e->ip.proto != IPPROTO_TCP || (e->ip.invflags & XT_INV_PROTO))) {
pr_info("cannot use TCP operations on a non-tcp rule\n");
pr_info_ratelimited("cannot use operation on non-tcp rule\n");
return -EINVAL;
}
return 0;
Expand Down
4 changes: 2 additions & 2 deletions net/ipv4/netfilter/ipt_REJECT.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@ static int reject_tg_check(const struct xt_tgchk_param *par)
const struct ipt_entry *e = par->entryinfo;

if (rejinfo->with == IPT_ICMP_ECHOREPLY) {
pr_info("ECHOREPLY no longer supported.\n");
pr_info_ratelimited("ECHOREPLY no longer supported.\n");
return -EINVAL;
} else if (rejinfo->with == IPT_TCP_RESET) {
/* Must specify that it's a TCP packet */
if (e->ip.proto != IPPROTO_TCP ||
(e->ip.invflags & XT_INV_PROTO)) {
pr_info("TCP_RESET invalid for non-tcp\n");
pr_info_ratelimited("TCP_RESET invalid for non-tcp\n");
return -EINVAL;
}
}
Expand Down
6 changes: 3 additions & 3 deletions net/ipv4/netfilter/ipt_rpfilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,14 @@ static int rpfilter_check(const struct xt_mtchk_param *par)
const struct xt_rpfilter_info *info = par->matchinfo;
unsigned int options = ~XT_RPFILTER_OPTION_MASK;
if (info->flags & options) {
pr_info("unknown options encountered");
pr_info_ratelimited("unknown options\n");
return -EINVAL;
}

if (strcmp(par->table, "mangle") != 0 &&
strcmp(par->table, "raw") != 0) {
pr_info("match only valid in the \'raw\' "
"or \'mangle\' tables, not \'%s\'.\n", par->table);
pr_info_ratelimited("only valid in \'raw\' or \'mangle\' table, not \'%s\'\n",
par->table);
return -EINVAL;
}

Expand Down
10 changes: 2 additions & 8 deletions net/ipv6/ipv6_sockglue.c
Original file line number Diff line number Diff line change
Expand Up @@ -1367,10 +1367,7 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
if (get_user(len, optlen))
return -EFAULT;

lock_sock(sk);
err = nf_getsockopt(sk, PF_INET6, optname, optval,
&len);
release_sock(sk);
err = nf_getsockopt(sk, PF_INET6, optname, optval, &len);
if (err >= 0)
err = put_user(len, optlen);
}
Expand Down Expand Up @@ -1409,10 +1406,7 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
if (get_user(len, optlen))
return -EFAULT;

lock_sock(sk);
err = compat_nf_getsockopt(sk, PF_INET6,
optname, optval, &len);
release_sock(sk);
err = compat_nf_getsockopt(sk, PF_INET6, optname, optval, &len);
if (err >= 0)
err = put_user(len, optlen);
}
Expand Down
4 changes: 4 additions & 0 deletions net/ipv6/netfilter/ip6_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,10 @@ ip6t_do_table(struct sk_buff *skb,
}
if (table_base + v != ip6t_next_entry(e) &&
!(e->ipv6.flags & IP6T_F_GOTO)) {
if (unlikely(stackidx >= private->stacksize)) {
verdict = NF_DROP;
break;
}
jumpstack[stackidx++] = e;
}

Expand Down
4 changes: 2 additions & 2 deletions net/ipv6/netfilter/ip6t_REJECT.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,14 @@ static int reject_tg6_check(const struct xt_tgchk_param *par)
const struct ip6t_entry *e = par->entryinfo;

if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
pr_info("ECHOREPLY is not supported.\n");
pr_info_ratelimited("ECHOREPLY is not supported\n");
return -EINVAL;
} else if (rejinfo->with == IP6T_TCP_RESET) {
/* Must specify that it's a TCP packet */
if (!(e->ipv6.flags & IP6T_F_PROTO) ||
e->ipv6.proto != IPPROTO_TCP ||
(e->ipv6.invflags & XT_INV_PROTO)) {
pr_info("TCP_RESET illegal for non-tcp\n");
pr_info_ratelimited("TCP_RESET illegal for non-tcp\n");
return -EINVAL;
}
}
Expand Down
6 changes: 3 additions & 3 deletions net/ipv6/netfilter/ip6t_rpfilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,14 @@ static int rpfilter_check(const struct xt_mtchk_param *par)
unsigned int options = ~XT_RPFILTER_OPTION_MASK;

if (info->flags & options) {
pr_info("unknown options encountered");
pr_info_ratelimited("unknown options\n");
return -EINVAL;
}

if (strcmp(par->table, "mangle") != 0 &&
strcmp(par->table, "raw") != 0) {
pr_info("match only valid in the \'raw\' "
"or \'mangle\' tables, not \'%s\'.\n", par->table);
pr_info_ratelimited("only valid in \'raw\' or \'mangle\' table, not \'%s\'\n",
par->table);
return -EINVAL;
}

Expand Down
6 changes: 4 additions & 2 deletions net/ipv6/netfilter/ip6t_srh.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,14 @@ static int srh_mt6_check(const struct xt_mtchk_param *par)
const struct ip6t_srh *srhinfo = par->matchinfo;

if (srhinfo->mt_flags & ~IP6T_SRH_MASK) {
pr_err("unknown srh match flags %X\n", srhinfo->mt_flags);
pr_info_ratelimited("unknown srh match flags %X\n",
srhinfo->mt_flags);
return -EINVAL;
}

if (srhinfo->mt_invflags & ~IP6T_SRH_INV_MASK) {
pr_err("unknown srh invflags %X\n", srhinfo->mt_invflags);
pr_info_ratelimited("unknown srh invflags %X\n",
srhinfo->mt_invflags);
return -EINVAL;
}

Expand Down
7 changes: 5 additions & 2 deletions net/netfilter/nf_nat_proto_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto,
const struct nf_conn *ct,
u16 *rover)
{
unsigned int range_size, min, i;
unsigned int range_size, min, max, i;
__be16 *portptr;
u_int16_t off;

Expand Down Expand Up @@ -71,7 +71,10 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto,
}
} else {
min = ntohs(range->min_proto.all);
range_size = ntohs(range->max_proto.all) - min + 1;
max = ntohs(range->max_proto.all);
if (unlikely(max < min))
swap(max, min);
range_size = max - min + 1;
}

if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) {
Expand Down
Loading

0 comments on commit 943a0d4

Please sign in to comment.