[dpdk-dev] [PATCH 1/2] bpf: fix validate for function return value

Konstantin Ananyev konstantin.ananyev at intel.com
Wed Jul 3 15:40:34 CEST 2019


eval_call() blindly calls eval_max_bound() for external function
return value for all return types.
That causes wrong estimation for returned pointer min and max boundaries.
So any attempt to dereference that pointer value causes verifier to fail
with error message: "memory boundary violation at pc: ...".
To fix - estimate min/max boundaries based on the return value type.

For more details please refer to:
https://bugs.dpdk.org/show_bug.cgi?id=298

Fixes: 8021917293d0 ("bpf: add extra validation for input BPF program")
Cc: stable at dpdk.org

Reported-by: Michel Machado <michel at digirati.com.br>
Suggested-by: Michel Machado <michel at digirati.com.br>
Signed-off-by: Konstantin Ananyev <konstantin.ananyev at intel.com>
---
 lib/librte_bpf/bpf_validate.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/lib/librte_bpf/bpf_validate.c b/lib/librte_bpf/bpf_validate.c
index d0e683b5b..0cf41fa27 100644
--- a/lib/librte_bpf/bpf_validate.c
+++ b/lib/librte_bpf/bpf_validate.c
@@ -925,7 +925,6 @@ eval_func_arg(struct bpf_verifier *bvf, const struct rte_bpf_arg *arg,
 static const char *
 eval_call(struct bpf_verifier *bvf, const struct ebpf_insn *ins)
 {
-	uint64_t msk;
 	uint32_t i, idx;
 	struct bpf_reg_val *rv;
 	const struct rte_bpf_xsym *xsym;
@@ -958,10 +957,11 @@ eval_call(struct bpf_verifier *bvf, const struct ebpf_insn *ins)
 
 	rv = bvf->evst->rv + EBPF_REG_0;
 	rv->v = xsym->func.ret;
-	msk = (rv->v.type == RTE_BPF_ARG_RAW) ?
-		RTE_LEN2MASK(rv->v.size * CHAR_BIT, uint64_t) : UINTPTR_MAX;
-	eval_max_bound(rv, msk);
-	rv->mask = msk;
+	if (rv->v.type == RTE_BPF_ARG_RAW)
+		eval_fill_max_bound(rv,
+			RTE_LEN2MASK(rv->v.size * CHAR_BIT, uint64_t));
+	else if (RTE_BPF_ARG_PTR_TYPE(rv->v.type) != 0)
+		eval_fill_imm64(rv, UINTPTR_MAX, 0);
 
 	return err;
 }
-- 
2.17.1



More information about the dev mailing list