DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/2] bpf: fix and new test-case
@ 2019-07-03 13:40 Konstantin Ananyev
  2019-07-03 13:40 ` [dpdk-dev] [PATCH 1/2] bpf: fix validate for function return value Konstantin Ananyev
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Konstantin Ananyev @ 2019-07-03 13:40 UTC (permalink / raw)
  To: dev; +Cc: michel, Konstantin Ananyev

Fixes problem in validate part for function return value checking
and adds new test-case to cover that.

Konstantin Ananyev (2):
  bpf: fix validate for function return value
  test/bpf: add test-case for function return value

 app/test/test_bpf.c           | 130 ++++++++++++++++++++++++++++++++++
 lib/librte_bpf/bpf_validate.c |  10 +--
 2 files changed, 135 insertions(+), 5 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [dpdk-dev] [PATCH 1/2] bpf: fix validate for function return value
  2019-07-03 13:40 [dpdk-dev] [PATCH 0/2] bpf: fix and new test-case Konstantin Ananyev
@ 2019-07-03 13:40 ` Konstantin Ananyev
  2019-07-03 13:40 ` [dpdk-dev] [PATCH 2/2] test/bpf: add test-case " Konstantin Ananyev
  2019-07-04  9:07 ` [dpdk-dev] [PATCH 0/2] bpf: fix and new test-case Thomas Monjalon
  2 siblings, 0 replies; 4+ messages in thread
From: Konstantin Ananyev @ 2019-07-03 13:40 UTC (permalink / raw)
  To: dev; +Cc: michel, Konstantin Ananyev, stable

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@dpdk.org

Reported-by: Michel Machado <michel@digirati.com.br>
Suggested-by: Michel Machado <michel@digirati.com.br>
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@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


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [dpdk-dev] [PATCH 2/2] test/bpf: add test-case for function return value
  2019-07-03 13:40 [dpdk-dev] [PATCH 0/2] bpf: fix and new test-case Konstantin Ananyev
  2019-07-03 13:40 ` [dpdk-dev] [PATCH 1/2] bpf: fix validate for function return value Konstantin Ananyev
@ 2019-07-03 13:40 ` Konstantin Ananyev
  2019-07-04  9:07 ` [dpdk-dev] [PATCH 0/2] bpf: fix and new test-case Thomas Monjalon
  2 siblings, 0 replies; 4+ messages in thread
From: Konstantin Ananyev @ 2019-07-03 13:40 UTC (permalink / raw)
  To: dev; +Cc: michel, Konstantin Ananyev

New test-case to cover situation when external function returns a
pointer the data.

Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
 app/test/test_bpf.c | 130 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 130 insertions(+)

diff --git a/app/test/test_bpf.c b/app/test/test_bpf.c
index 1d50401aa..e8841800a 100644
--- a/app/test/test_bpf.c
+++ b/app/test/test_bpf.c
@@ -1777,6 +1777,118 @@ static const struct rte_bpf_xsym test_call2_xsym[] = {
 	},
 };
 
+static const struct ebpf_insn test_call3_prog[] = {
+
+	{
+		.code = (BPF_JMP | EBPF_CALL),
+		.imm = 0,
+	},
+	{
+		.code = (BPF_LDX | BPF_MEM | BPF_B),
+		.dst_reg = EBPF_REG_2,
+		.src_reg = EBPF_REG_0,
+		.off = offsetof(struct dummy_offset, u8),
+	},
+	{
+		.code = (BPF_LDX | BPF_MEM | BPF_H),
+		.dst_reg = EBPF_REG_3,
+		.src_reg = EBPF_REG_0,
+		.off = offsetof(struct dummy_offset, u16),
+	},
+	{
+		.code = (BPF_LDX | BPF_MEM | BPF_W),
+		.dst_reg = EBPF_REG_4,
+		.src_reg = EBPF_REG_0,
+		.off = offsetof(struct dummy_offset, u32),
+	},
+	{
+		.code = (BPF_LDX | BPF_MEM | EBPF_DW),
+		.dst_reg = EBPF_REG_0,
+		.src_reg = EBPF_REG_0,
+		.off = offsetof(struct dummy_offset, u64),
+	},
+	/* return sum */
+	{
+		.code = (EBPF_ALU64 | BPF_ADD | BPF_X),
+		.dst_reg = EBPF_REG_0,
+		.src_reg = EBPF_REG_4,
+	},
+	{
+		.code = (EBPF_ALU64 | BPF_ADD | BPF_X),
+		.dst_reg = EBPF_REG_0,
+		.src_reg = EBPF_REG_3,
+	},
+	{
+		.code = (EBPF_ALU64 | BPF_ADD | BPF_X),
+		.dst_reg = EBPF_REG_0,
+		.src_reg = EBPF_REG_2,
+	},
+	{
+		.code = (BPF_JMP | EBPF_EXIT),
+	},
+};
+
+static const struct dummy_offset *
+dummy_func3(const struct dummy_vect8 *p)
+{
+	return &p->in[RTE_DIM(p->in) - 1];
+}
+
+static void
+test_call3_prepare(void *arg)
+{
+	struct dummy_vect8 *pv;
+	struct dummy_offset *df;
+
+	pv = arg;
+	df = (struct dummy_offset *)(uintptr_t)dummy_func3(pv);
+
+	memset(pv, 0, sizeof(*pv));
+	df->u64 = (int32_t)TEST_FILL_1;
+	df->u32 = df->u64;
+	df->u16 = df->u64;
+	df->u8 = df->u64;
+}
+
+static int
+test_call3_check(uint64_t rc, const void *arg)
+{
+	uint64_t v;
+	const struct dummy_vect8 *pv;
+	const struct dummy_offset *dft;
+
+	pv = arg;
+	dft = dummy_func3(pv);
+
+	v = dft->u64;
+	v += dft->u32;
+	v += dft->u16;
+	v += dft->u8;
+
+	return cmp_res(__func__, v, rc, pv, pv, sizeof(*pv));
+}
+
+static const struct rte_bpf_xsym test_call3_xsym[] = {
+	{
+		.name = RTE_STR(dummy_func3),
+		.type = RTE_BPF_XTYPE_FUNC,
+		.func = {
+			.val = (void *)dummy_func3,
+			.nb_args = 1,
+			.args = {
+				[0] = {
+					.type = RTE_BPF_ARG_PTR,
+					.size = sizeof(struct dummy_vect8),
+				},
+			},
+			.ret = {
+				.type = RTE_BPF_ARG_PTR,
+				.size = sizeof(struct dummy_offset),
+			},
+		},
+	},
+};
+
 static const struct bpf_test tests[] = {
 	{
 		.name = "test_store1",
@@ -1968,6 +2080,24 @@ static const struct bpf_test tests[] = {
 		/* for now don't support function calls on 32 bit platform */
 		.allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)),
 	},
+	{
+		.name = "test_call3",
+		.arg_sz = sizeof(struct dummy_vect8),
+		.prm = {
+			.ins = test_call3_prog,
+			.nb_ins = RTE_DIM(test_call3_prog),
+			.prog_arg = {
+				.type = RTE_BPF_ARG_PTR,
+				.size = sizeof(struct dummy_vect8),
+			},
+			.xsym = test_call3_xsym,
+			.nb_xsym = RTE_DIM(test_call3_xsym),
+		},
+		.prepare = test_call3_prepare,
+		.check_result = test_call3_check,
+		/* for now don't support function calls on 32 bit platform */
+		.allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)),
+	},
 };
 
 static int
-- 
2.17.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [dpdk-dev] [PATCH 0/2] bpf: fix and new test-case
  2019-07-03 13:40 [dpdk-dev] [PATCH 0/2] bpf: fix and new test-case Konstantin Ananyev
  2019-07-03 13:40 ` [dpdk-dev] [PATCH 1/2] bpf: fix validate for function return value Konstantin Ananyev
  2019-07-03 13:40 ` [dpdk-dev] [PATCH 2/2] test/bpf: add test-case " Konstantin Ananyev
@ 2019-07-04  9:07 ` Thomas Monjalon
  2 siblings, 0 replies; 4+ messages in thread
From: Thomas Monjalon @ 2019-07-04  9:07 UTC (permalink / raw)
  To: Konstantin Ananyev; +Cc: dev, michel

03/07/2019 15:40, Konstantin Ananyev:
> Fixes problem in validate part for function return value checking
> and adds new test-case to cover that.
> 
> Konstantin Ananyev (2):
>   bpf: fix validate for function return value
>   test/bpf: add test-case for function return value

Applied, thanks




^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-07-04  9:07 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-03 13:40 [dpdk-dev] [PATCH 0/2] bpf: fix and new test-case Konstantin Ananyev
2019-07-03 13:40 ` [dpdk-dev] [PATCH 1/2] bpf: fix validate for function return value Konstantin Ananyev
2019-07-03 13:40 ` [dpdk-dev] [PATCH 2/2] test/bpf: add test-case " Konstantin Ananyev
2019-07-04  9:07 ` [dpdk-dev] [PATCH 0/2] bpf: fix and new test-case Thomas Monjalon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).