提交 3bd22997 编写于 作者: F Florian Westphal 提交者: Pablo Neira Ayuso

netfilter: arptables: use percpu jumpstack

commit 482cfc31 ("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: 482cfc31 ("netfilter: xtables: avoid percpu ruleset duplication")
Signed-off-by: NFlorian Westphal <fw@strlen.de>
Signed-off-by: NPablo Neira Ayuso <pablo@netfilter.org>
上级 a1bc1b35
...@@ -254,9 +254,10 @@ unsigned int arpt_do_table(struct sk_buff *skb, ...@@ -254,9 +254,10 @@ unsigned int arpt_do_table(struct sk_buff *skb,
static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
unsigned int verdict = NF_DROP; unsigned int verdict = NF_DROP;
const struct arphdr *arp; const struct arphdr *arp;
struct arpt_entry *e, *back; struct arpt_entry *e, **jumpstack;
const char *indev, *outdev; const char *indev, *outdev;
const void *table_base; const void *table_base;
unsigned int cpu, stackidx = 0;
const struct xt_table_info *private; const struct xt_table_info *private;
struct xt_action_param acpar; struct xt_action_param acpar;
unsigned int addend; unsigned int addend;
...@@ -270,15 +271,16 @@ unsigned int arpt_do_table(struct sk_buff *skb, ...@@ -270,15 +271,16 @@ unsigned int arpt_do_table(struct sk_buff *skb,
local_bh_disable(); local_bh_disable();
addend = xt_write_recseq_begin(); addend = xt_write_recseq_begin();
private = table->private; private = table->private;
cpu = smp_processor_id();
/* /*
* Ensure we load private-> members after we've fetched the base * Ensure we load private-> members after we've fetched the base
* pointer. * pointer.
*/ */
smp_read_barrier_depends(); smp_read_barrier_depends();
table_base = private->entries; table_base = private->entries;
jumpstack = (struct arpt_entry **)private->jumpstack[cpu];
e = get_entry(table_base, private->hook_entry[hook]); e = get_entry(table_base, private->hook_entry[hook]);
back = get_entry(table_base, private->underflow[hook]);
acpar.in = state->in; acpar.in = state->in;
acpar.out = state->out; acpar.out = state->out;
...@@ -312,18 +314,23 @@ unsigned int arpt_do_table(struct sk_buff *skb, ...@@ -312,18 +314,23 @@ unsigned int arpt_do_table(struct sk_buff *skb,
verdict = (unsigned int)(-v) - 1; verdict = (unsigned int)(-v) - 1;
break; break;
} }
e = back; if (stackidx == 0) {
back = get_entry(table_base, back->comefrom); e = get_entry(table_base,
private->underflow[hook]);
} else {
e = jumpstack[--stackidx];
e = arpt_next_entry(e);
}
continue; continue;
} }
if (table_base + v if (table_base + v
!= arpt_next_entry(e)) { != 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 */ if (stackidx >= private->stacksize) {
back = next; verdict = NF_DROP;
break;
}
jumpstack[stackidx++] = e;
} }
e = get_entry(table_base, v); e = get_entry(table_base, v);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册