summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrenden Blanco <bblanco@plumgrid.com>2016-07-19 15:16:56 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-20 00:46:33 -0400
commit4acf6c0b84c91243c705303cd9ff16421914150d (patch)
tree1fc015113abd682af506b436bb3788d1cc28a760
parent9ecc2d86171adf23796133c89610987a14624875 (diff)
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: Brenden Blanco <bblanco@plumgrid.com> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--kernel/bpf/verifier.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index a8d67d097b0d..f72f23b8fdab 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -653,6 +653,16 @@ static int check_map_access(struct verifier_env *env, u32 regno, int off,
653 653
654#define MAX_PACKET_OFF 0xffff 654#define MAX_PACKET_OFF 0xffff
655 655
656static bool may_write_pkt_data(enum bpf_prog_type type)
657{
658 switch (type) {
659 case BPF_PROG_TYPE_XDP:
660 return true;
661 default:
662 return false;
663 }
664}
665
656static int check_packet_access(struct verifier_env *env, u32 regno, int off, 666static int check_packet_access(struct verifier_env *env, u32 regno, int off,
657 int size) 667 int size)
658{ 668{
@@ -806,10 +816,15 @@ static int check_mem_access(struct verifier_env *env, u32 regno, int off,
806 err = check_stack_read(state, off, size, value_regno); 816 err = check_stack_read(state, off, size, value_regno);
807 } 817 }
808 } else if (state->regs[regno].type == PTR_TO_PACKET) { 818 } else if (state->regs[regno].type == PTR_TO_PACKET) {
809 if (t == BPF_WRITE) { 819 if (t == BPF_WRITE && !may_write_pkt_data(env->prog->type)) {
810 verbose("cannot write into packet\n"); 820 verbose("cannot write into packet\n");
811 return -EACCES; 821 return -EACCES;
812 } 822 }
823 if (t == BPF_WRITE && value_regno >= 0 &&
824 is_pointer_value(env, value_regno)) {
825 verbose("R%d leaks addr into packet\n", value_regno);
826 return -EACCES;
827 }
813 err = check_packet_access(env, regno, off, size); 828 err = check_packet_access(env, regno, off, size);
814 if (!err && t == BPF_READ && value_regno >= 0) 829 if (!err && t == BPF_READ && value_regno >= 0)
815 mark_reg_unknown_value(state->regs, value_regno); 830 mark_reg_unknown_value(state->regs, value_regno);