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

This is the first batch of Netfilter fixes for your net tree:

1) Fix endless loop in nf_tables rules netlink dump, from Phil Sutter.

2) Reference counter leak in object from the error path, from Taehee Yoo.

3) Selective rule dump requires table and chain.

4) Fix DNAT with nft_flow_offload reverse route lookup, from wenxu.

5) Use GFP_KERNEL_ACCOUNT in vmalloc allocation from ebtables, from
   Shakeel Butt.

6) Set ifindex from route to fix interaction with VRF slave device,
   also from wenxu.

7) Use nfct_help() to check for conntrack helper, IPS_HELPER status
   flag is only set from explicit helpers via -j CT, from Henry Yen.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jan 15, 2019
2 parents 7939f8b + 2314e87 commit 72f6d4d
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 17 deletions.
1 change: 0 additions & 1 deletion include/net/netfilter/nf_flow_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ struct flow_offload {
struct nf_flow_route {
struct {
struct dst_entry *dst;
int ifindex;
} tuple[FLOW_OFFLOAD_DIR_MAX];
};

Expand Down
6 changes: 4 additions & 2 deletions net/bridge/netfilter/ebtables.c
Original file line number Diff line number Diff line change
Expand Up @@ -1137,14 +1137,16 @@ static int do_replace(struct net *net, const void __user *user,
tmp.name[sizeof(tmp.name) - 1] = 0;

countersize = COUNTER_OFFSET(tmp.nentries) * nr_cpu_ids;
newinfo = vmalloc(sizeof(*newinfo) + countersize);
newinfo = __vmalloc(sizeof(*newinfo) + countersize, GFP_KERNEL_ACCOUNT,
PAGE_KERNEL);
if (!newinfo)
return -ENOMEM;

if (countersize)
memset(newinfo->counters, 0, countersize);

newinfo->entries = vmalloc(tmp.entries_size);
newinfo->entries = __vmalloc(tmp.entries_size, GFP_KERNEL_ACCOUNT,
PAGE_KERNEL);
if (!newinfo->entries) {
ret = -ENOMEM;
goto free_newinfo;
Expand Down
5 changes: 3 additions & 2 deletions net/netfilter/nf_flow_table_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ flow_offload_fill_dir(struct flow_offload *flow, struct nf_conn *ct,
{
struct flow_offload_tuple *ft = &flow->tuplehash[dir].tuple;
struct nf_conntrack_tuple *ctt = &ct->tuplehash[dir].tuple;
struct dst_entry *other_dst = route->tuple[!dir].dst;
struct dst_entry *dst = route->tuple[dir].dst;

ft->dir = dir;
Expand All @@ -50,8 +51,8 @@ flow_offload_fill_dir(struct flow_offload *flow, struct nf_conn *ct,
ft->src_port = ctt->src.u.tcp.port;
ft->dst_port = ctt->dst.u.tcp.port;

ft->iifidx = route->tuple[dir].ifindex;
ft->oifidx = route->tuple[!dir].ifindex;
ft->iifidx = other_dst->dev->ifindex;
ft->oifidx = dst->dev->ifindex;
ft->dst_cache = dst;
}

Expand Down
14 changes: 7 additions & 7 deletions net/netfilter/nf_tables_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -2304,7 +2304,6 @@ static int __nf_tables_dump_rules(struct sk_buff *skb,
struct net *net = sock_net(skb->sk);
unsigned int s_idx = cb->args[0];
const struct nft_rule *rule;
int rc = 1;

list_for_each_entry_rcu(rule, &chain->rules, list) {
if (!nft_is_active(net, rule))
Expand All @@ -2321,16 +2320,13 @@ static int __nf_tables_dump_rules(struct sk_buff *skb,
NLM_F_MULTI | NLM_F_APPEND,
table->family,
table, chain, rule) < 0)
goto out_unfinished;
return 1;

nl_dump_check_consistent(cb, nlmsg_hdr(skb));
cont:
(*idx)++;
}
rc = 0;
out_unfinished:
cb->args[0] = *idx;
return rc;
return 0;
}

static int nf_tables_dump_rules(struct sk_buff *skb,
Expand All @@ -2354,7 +2350,7 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
if (ctx && ctx->table && strcmp(ctx->table, table->name) != 0)
continue;

if (ctx && ctx->chain) {
if (ctx && ctx->table && ctx->chain) {
struct rhlist_head *list, *tmp;

list = rhltable_lookup(&table->chains_ht, ctx->chain,
Expand Down Expand Up @@ -2382,6 +2378,8 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
}
done:
rcu_read_unlock();

cb->args[0] = idx;
return skb->len;
}

Expand Down Expand Up @@ -4508,6 +4506,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
err5:
kfree(trans);
err4:
if (obj)
obj->use--;
kfree(elem.priv);
err3:
if (nla[NFTA_SET_ELEM_DATA] != NULL)
Expand Down
13 changes: 8 additions & 5 deletions net/netfilter/nft_flow_offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <net/netfilter/nf_conntrack_core.h>
#include <linux/netfilter/nf_conntrack_common.h>
#include <net/netfilter/nf_flow_table.h>
#include <net/netfilter/nf_conntrack_helper.h>

struct nft_flow_offload {
struct nft_flowtable *flowtable;
Expand All @@ -29,10 +30,12 @@ static int nft_flow_route(const struct nft_pktinfo *pkt,
memset(&fl, 0, sizeof(fl));
switch (nft_pf(pkt)) {
case NFPROTO_IPV4:
fl.u.ip4.daddr = ct->tuplehash[!dir].tuple.dst.u3.ip;
fl.u.ip4.daddr = ct->tuplehash[dir].tuple.src.u3.ip;
fl.u.ip4.flowi4_oif = nft_in(pkt)->ifindex;
break;
case NFPROTO_IPV6:
fl.u.ip6.daddr = ct->tuplehash[!dir].tuple.dst.u3.in6;
fl.u.ip6.daddr = ct->tuplehash[dir].tuple.src.u3.in6;
fl.u.ip6.flowi6_oif = nft_in(pkt)->ifindex;
break;
}

Expand All @@ -41,9 +44,7 @@ static int nft_flow_route(const struct nft_pktinfo *pkt,
return -ENOENT;

route->tuple[dir].dst = this_dst;
route->tuple[dir].ifindex = nft_in(pkt)->ifindex;
route->tuple[!dir].dst = other_dst;
route->tuple[!dir].ifindex = nft_out(pkt)->ifindex;

return 0;
}
Expand All @@ -66,6 +67,7 @@ static void nft_flow_offload_eval(const struct nft_expr *expr,
{
struct nft_flow_offload *priv = nft_expr_priv(expr);
struct nf_flowtable *flowtable = &priv->flowtable->data;
const struct nf_conn_help *help;
enum ip_conntrack_info ctinfo;
struct nf_flow_route route;
struct flow_offload *flow;
Expand All @@ -88,7 +90,8 @@ static void nft_flow_offload_eval(const struct nft_expr *expr,
goto out;
}

if (test_bit(IPS_HELPER_BIT, &ct->status))
help = nfct_help(ct);
if (help)
goto out;

if (ctinfo == IP_CT_NEW ||
Expand Down

0 comments on commit 72f6d4d

Please sign in to comment.