Commit 4acf6c0b authored by Brenden Blanco's avatar Brenden Blanco Committed by David S. Miller

bpf: enable direct packet data write for xdp progs

For forwarding to be effective, XDP programs should be allowed to
rewrite packet data.

This requires that the drivers supporting XDP must all map the packet
memory as TODEVICE or BIDIRECTIONAL before invoking the program.
Signed-off-by: default avatarBrenden Blanco <bblanco@plumgrid.com>
Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9ecc2d86
...@@ -653,6 +653,16 @@ static int check_map_access(struct verifier_env *env, u32 regno, int off, ...@@ -653,6 +653,16 @@ static int check_map_access(struct verifier_env *env, u32 regno, int off,
#define MAX_PACKET_OFF 0xffff #define MAX_PACKET_OFF 0xffff
static bool may_write_pkt_data(enum bpf_prog_type type)
{
switch (type) {
case BPF_PROG_TYPE_XDP:
return true;
default:
return false;
}
}
static int check_packet_access(struct verifier_env *env, u32 regno, int off, static int check_packet_access(struct verifier_env *env, u32 regno, int off,
int size) int size)
{ {
...@@ -806,10 +816,15 @@ static int check_mem_access(struct verifier_env *env, u32 regno, int off, ...@@ -806,10 +816,15 @@ static int check_mem_access(struct verifier_env *env, u32 regno, int off,
err = check_stack_read(state, off, size, value_regno); err = check_stack_read(state, off, size, value_regno);
} }
} else if (state->regs[regno].type == PTR_TO_PACKET) { } else if (state->regs[regno].type == PTR_TO_PACKET) {
if (t == BPF_WRITE) { if (t == BPF_WRITE && !may_write_pkt_data(env->prog->type)) {
verbose("cannot write into packet\n"); verbose("cannot write into packet\n");
return -EACCES; return -EACCES;
} }
if (t == BPF_WRITE && value_regno >= 0 &&
is_pointer_value(env, value_regno)) {
verbose("R%d leaks addr into packet\n", value_regno);
return -EACCES;
}
err = check_packet_access(env, regno, off, size); err = check_packet_access(env, regno, off, size);
if (!err && t == BPF_READ && value_regno >= 0) if (!err && t == BPF_READ && value_regno >= 0)
mark_reg_unknown_value(state->regs, value_regno); mark_reg_unknown_value(state->regs, value_regno);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment