Skip to content

Commit

Permalink
netfilter: arptables: use percpu jumpstack
Browse files Browse the repository at this point in the history
commit 482cfc3 ("netfilter: xtables: avoid percpu ruleset duplication")

Unlike ip and ip6tables, arp tables were never converted to use the percpu
jump stack.

It still uses the rule blob to store return address, which isn't safe
anymore since we now share this blob among all processors.

Because there is no TEE support for arptables, we don't need to cope
with reentrancy, so we can use loocal variable to hold stack offset.

Fixes: 482cfc3 ("netfilter: xtables: avoid percpu ruleset duplication")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  • Loading branch information
Florian Westphal authored and Pablo Neira Ayuso committed Jul 2, 2015
1 parent a1bc1b3 commit 3bd2299
Showing 1 changed file with 16 additions and 9 deletions.
25 changes: 16 additions & 9 deletions net/ipv4/netfilter/arp_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,10 @@ unsigned int arpt_do_table(struct sk_buff *skb,
static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
unsigned int verdict = NF_DROP;
const struct arphdr *arp;
struct arpt_entry *e, *back;
struct arpt_entry *e, **jumpstack;
const char *indev, *outdev;
const void *table_base;
unsigned int cpu, stackidx = 0;
const struct xt_table_info *private;
struct xt_action_param acpar;
unsigned int addend;
Expand All @@ -270,15 +271,16 @@ unsigned int arpt_do_table(struct sk_buff *skb,
local_bh_disable();
addend = xt_write_recseq_begin();
private = table->private;
cpu = smp_processor_id();
/*
* Ensure we load private-> members after we've fetched the base
* pointer.
*/
smp_read_barrier_depends();
table_base = private->entries;
jumpstack = (struct arpt_entry **)private->jumpstack[cpu];

e = get_entry(table_base, private->hook_entry[hook]);
back = get_entry(table_base, private->underflow[hook]);

acpar.in = state->in;
acpar.out = state->out;
Expand Down Expand Up @@ -312,18 +314,23 @@ unsigned int arpt_do_table(struct sk_buff *skb,
verdict = (unsigned int)(-v) - 1;
break;
}
e = back;
back = get_entry(table_base, back->comefrom);
if (stackidx == 0) {
e = get_entry(table_base,
private->underflow[hook]);
} else {
e = jumpstack[--stackidx];
e = arpt_next_entry(e);
}
continue;
}
if (table_base + v
!= arpt_next_entry(e)) {
/* Save old back ptr in next entry */
struct arpt_entry *next = arpt_next_entry(e);
next->comefrom = (void *)back - table_base;

/* set back pointer to next entry */
back = next;
if (stackidx >= private->stacksize) {
verdict = NF_DROP;
break;
}
jumpstack[stackidx++] = e;
}

e = get_entry(table_base, v);
Expand Down

0 comments on commit 3bd2299

Please sign in to comment.