From f78e9f6e5f6153e1315bc023f93baa9a31170f18 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 6 Aug 2021 10:04:58 +0200 Subject: [PATCH] 5.10-stable patches added patches: bpf-selftests-adjust-few-selftest-outcomes-wrt-unreachable-code.patch bpf-selftests-adjust-few-selftest-result_unpriv-outcomes.patch bpf-update-selftests-to-reflect-new-error-states.patch selftest-bpf-adjust-expected-verifier-errors.patch selftest-bpf-verifier-tests-for-var-off-access.patch selftests-bpf-add-a-test-for-ptr_to_map_value-on-stack-for-helper-access.patch --- ...lftest-outcomes-wrt-unreachable-code.patch | 315 ++++++++++++++ ...-few-selftest-result_unpriv-outcomes.patch | 74 ++++ ...elftests-to-reflect-new-error-states.patch | 315 ++++++++++++++ ...-bpf-adjust-expected-verifier-errors.patch | 387 ++++++++++++++++++ ...pf-verifier-tests-for-var-off-access.patch | 139 +++++++ ...map_value-on-stack-for-helper-access.patch | 55 +++ queue-5.10/series | 6 + 7 files changed, 1291 insertions(+) create mode 100644 queue-5.10/bpf-selftests-adjust-few-selftest-outcomes-wrt-unreachable-code.patch create mode 100644 queue-5.10/bpf-selftests-adjust-few-selftest-result_unpriv-outcomes.patch create mode 100644 queue-5.10/bpf-update-selftests-to-reflect-new-error-states.patch create mode 100644 queue-5.10/selftest-bpf-adjust-expected-verifier-errors.patch create mode 100644 queue-5.10/selftest-bpf-verifier-tests-for-var-off-access.patch create mode 100644 queue-5.10/selftests-bpf-add-a-test-for-ptr_to_map_value-on-stack-for-helper-access.patch diff --git a/queue-5.10/bpf-selftests-adjust-few-selftest-outcomes-wrt-unreachable-code.patch b/queue-5.10/bpf-selftests-adjust-few-selftest-outcomes-wrt-unreachable-code.patch new file mode 100644 index 00000000000..8355b6ca76b --- /dev/null +++ b/queue-5.10/bpf-selftests-adjust-few-selftest-outcomes-wrt-unreachable-code.patch @@ -0,0 +1,315 @@ +From foo@baz Fri Aug 6 10:03:43 AM CEST 2021 +From: Ovidiu Panait +Date: Wed, 4 Aug 2021 20:09:16 +0300 +Subject: bpf, selftests: Adjust few selftest outcomes wrt unreachable code +To: stable@vger.kernel.org +Cc: bpf@vger.kernel.org, daniel@iogearbox.net +Message-ID: <20210804170917.3842969-6-ovidiu.panait@windriver.com> + +From: Daniel Borkmann + +commit 973377ffe8148180b2651825b92ae91988141b05 upstream + +In almost all cases from test_verifier that have been changed in here, we've +had an unreachable path with a load from a register which has an invalid +address on purpose. This was basically to make sure that we never walk this +path and to have the verifier complain if it would otherwise. Change it to +match on the right error for unprivileged given we now test these paths +under speculative execution. + +There's one case where we match on exact # of insns_processed. Due to the +extra path, this will of course mismatch on unprivileged. Thus, restrict the +test->insn_processed check to privileged-only. + +In one other case, we result in a 'pointer comparison prohibited' error. This +is similarly due to verifying an 'invalid' branch where we end up with a value +pointer on one side of the comparison. + +Signed-off-by: Daniel Borkmann +Reviewed-by: John Fastabend +Acked-by: Alexei Starovoitov +Signed-off-by: Ovidiu Panait +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/bpf/test_verifier.c | 2 - + tools/testing/selftests/bpf/verifier/and.c | 2 + + tools/testing/selftests/bpf/verifier/bounds.c | 14 ++++++++++ + tools/testing/selftests/bpf/verifier/dead_code.c | 2 + + tools/testing/selftests/bpf/verifier/jmp32.c | 22 +++++++++++++++++ + tools/testing/selftests/bpf/verifier/jset.c | 10 ++++--- + tools/testing/selftests/bpf/verifier/unpriv.c | 2 + + tools/testing/selftests/bpf/verifier/value_ptr_arith.c | 7 +++-- + 8 files changed, 53 insertions(+), 8 deletions(-) + +--- a/tools/testing/selftests/bpf/test_verifier.c ++++ b/tools/testing/selftests/bpf/test_verifier.c +@@ -1036,7 +1036,7 @@ static void do_test_single(struct bpf_te + } + } + +- if (test->insn_processed) { ++ if (!unpriv && test->insn_processed) { + uint32_t insn_processed; + char *proc; + +--- a/tools/testing/selftests/bpf/verifier/and.c ++++ b/tools/testing/selftests/bpf/verifier/and.c +@@ -61,6 +61,8 @@ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R1 !read_ok", ++ .result_unpriv = REJECT, + .result = ACCEPT, + .retval = 0 + }, +--- a/tools/testing/selftests/bpf/verifier/bounds.c ++++ b/tools/testing/selftests/bpf/verifier/bounds.c +@@ -508,6 +508,8 @@ + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, -1), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R0 invalid mem access 'inv'", ++ .result_unpriv = REJECT, + .result = ACCEPT + }, + { +@@ -528,6 +530,8 @@ + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, -1), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R0 invalid mem access 'inv'", ++ .result_unpriv = REJECT, + .result = ACCEPT + }, + { +@@ -569,6 +573,8 @@ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R0 min value is outside of the allowed memory range", ++ .result_unpriv = REJECT, + .fixup_map_hash_8b = { 3 }, + .result = ACCEPT, + }, +@@ -589,6 +595,8 @@ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R0 min value is outside of the allowed memory range", ++ .result_unpriv = REJECT, + .fixup_map_hash_8b = { 3 }, + .result = ACCEPT, + }, +@@ -609,6 +617,8 @@ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R0 min value is outside of the allowed memory range", ++ .result_unpriv = REJECT, + .fixup_map_hash_8b = { 3 }, + .result = ACCEPT, + }, +@@ -674,6 +684,8 @@ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R0 min value is outside of the allowed memory range", ++ .result_unpriv = REJECT, + .fixup_map_hash_8b = { 3 }, + .result = ACCEPT, + }, +@@ -695,6 +707,8 @@ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R0 min value is outside of the allowed memory range", ++ .result_unpriv = REJECT, + .fixup_map_hash_8b = { 3 }, + .result = ACCEPT, + }, +--- a/tools/testing/selftests/bpf/verifier/dead_code.c ++++ b/tools/testing/selftests/bpf/verifier/dead_code.c +@@ -8,6 +8,8 @@ + BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 10, -4), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R9 !read_ok", ++ .result_unpriv = REJECT, + .result = ACCEPT, + .retval = 7, + }, +--- a/tools/testing/selftests/bpf/verifier/jmp32.c ++++ b/tools/testing/selftests/bpf/verifier/jmp32.c +@@ -87,6 +87,8 @@ + BPF_LDX_MEM(BPF_B, BPF_REG_8, BPF_REG_9, 0), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R9 !read_ok", ++ .result_unpriv = REJECT, + .result = ACCEPT, + }, + { +@@ -150,6 +152,8 @@ + BPF_LDX_MEM(BPF_B, BPF_REG_8, BPF_REG_9, 0), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R9 !read_ok", ++ .result_unpriv = REJECT, + .result = ACCEPT, + }, + { +@@ -213,6 +217,8 @@ + BPF_LDX_MEM(BPF_B, BPF_REG_8, BPF_REG_9, 0), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R9 !read_ok", ++ .result_unpriv = REJECT, + .result = ACCEPT, + }, + { +@@ -280,6 +286,8 @@ + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R0 invalid mem access 'inv'", ++ .result_unpriv = REJECT, + .result = ACCEPT, + .retval = 2, + }, +@@ -348,6 +356,8 @@ + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R0 invalid mem access 'inv'", ++ .result_unpriv = REJECT, + .result = ACCEPT, + .retval = 2, + }, +@@ -416,6 +426,8 @@ + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R0 invalid mem access 'inv'", ++ .result_unpriv = REJECT, + .result = ACCEPT, + .retval = 2, + }, +@@ -484,6 +496,8 @@ + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R0 invalid mem access 'inv'", ++ .result_unpriv = REJECT, + .result = ACCEPT, + .retval = 2, + }, +@@ -552,6 +566,8 @@ + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R0 invalid mem access 'inv'", ++ .result_unpriv = REJECT, + .result = ACCEPT, + .retval = 2, + }, +@@ -620,6 +636,8 @@ + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R0 invalid mem access 'inv'", ++ .result_unpriv = REJECT, + .result = ACCEPT, + .retval = 2, + }, +@@ -688,6 +706,8 @@ + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R0 invalid mem access 'inv'", ++ .result_unpriv = REJECT, + .result = ACCEPT, + .retval = 2, + }, +@@ -756,6 +776,8 @@ + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R0 invalid mem access 'inv'", ++ .result_unpriv = REJECT, + .result = ACCEPT, + .retval = 2, + }, +--- a/tools/testing/selftests/bpf/verifier/jset.c ++++ b/tools/testing/selftests/bpf/verifier/jset.c +@@ -82,8 +82,8 @@ + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, +- .retval_unpriv = 1, +- .result_unpriv = ACCEPT, ++ .errstr_unpriv = "R9 !read_ok", ++ .result_unpriv = REJECT, + .retval = 1, + .result = ACCEPT, + }, +@@ -141,7 +141,8 @@ + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, +- .result_unpriv = ACCEPT, ++ .errstr_unpriv = "R9 !read_ok", ++ .result_unpriv = REJECT, + .result = ACCEPT, + }, + { +@@ -162,6 +163,7 @@ + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, +- .result_unpriv = ACCEPT, ++ .errstr_unpriv = "R9 !read_ok", ++ .result_unpriv = REJECT, + .result = ACCEPT, + }, +--- a/tools/testing/selftests/bpf/verifier/unpriv.c ++++ b/tools/testing/selftests/bpf/verifier/unpriv.c +@@ -419,6 +419,8 @@ + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0), + BPF_EXIT_INSN(), + }, ++ .errstr_unpriv = "R7 invalid mem access 'inv'", ++ .result_unpriv = REJECT, + .result = ACCEPT, + .retval = 0, + }, +--- a/tools/testing/selftests/bpf/verifier/value_ptr_arith.c ++++ b/tools/testing/selftests/bpf/verifier/value_ptr_arith.c +@@ -120,7 +120,7 @@ + .fixup_map_array_48b = { 1 }, + .result = ACCEPT, + .result_unpriv = REJECT, +- .errstr_unpriv = "R2 tried to add from different maps, paths or scalars", ++ .errstr_unpriv = "R2 pointer comparison prohibited", + .retval = 0, + }, + { +@@ -159,7 +159,8 @@ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + // fake-dead code; targeted from branch A to +- // prevent dead code sanitization ++ // prevent dead code sanitization, rejected ++ // via branch B however + BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0), + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), +@@ -167,7 +168,7 @@ + .fixup_map_array_48b = { 1 }, + .result = ACCEPT, + .result_unpriv = REJECT, +- .errstr_unpriv = "R2 tried to add from different maps, paths or scalars", ++ .errstr_unpriv = "R0 invalid mem access 'inv'", + .retval = 0, + }, + { diff --git a/queue-5.10/bpf-selftests-adjust-few-selftest-result_unpriv-outcomes.patch b/queue-5.10/bpf-selftests-adjust-few-selftest-result_unpriv-outcomes.patch new file mode 100644 index 00000000000..609e4882268 --- /dev/null +++ b/queue-5.10/bpf-selftests-adjust-few-selftest-result_unpriv-outcomes.patch @@ -0,0 +1,74 @@ +From foo@baz Fri Aug 6 10:03:43 AM CEST 2021 +From: Ovidiu Panait +Date: Wed, 4 Aug 2021 20:09:14 +0300 +Subject: bpf, selftests: Adjust few selftest result_unpriv outcomes +To: stable@vger.kernel.org +Cc: bpf@vger.kernel.org, daniel@iogearbox.net +Message-ID: <20210804170917.3842969-4-ovidiu.panait@windriver.com> + +From: Daniel Borkmann + +commit 1bad6fd52be4ce12d207e2820ceb0f29ab31fc53 upstream + +Given we don't need to simulate the speculative domain for registers with +immediates anymore since the verifier uses direct imm-based rewrites instead +of having to mask, we can also lift a few cases that were previously rejected. + +Signed-off-by: Daniel Borkmann +Acked-by: Alexei Starovoitov +Signed-off-by: Ovidiu Panait +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/bpf/verifier/stack_ptr.c | 2 -- + tools/testing/selftests/bpf/verifier/value_ptr_arith.c | 8 -------- + 2 files changed, 10 deletions(-) + +--- a/tools/testing/selftests/bpf/verifier/stack_ptr.c ++++ b/tools/testing/selftests/bpf/verifier/stack_ptr.c +@@ -295,8 +295,6 @@ + BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), + BPF_EXIT_INSN(), + }, +- .result_unpriv = REJECT, +- .errstr_unpriv = "invalid write to stack R1 off=0 size=1", + .result = ACCEPT, + .retval = 42, + }, +--- a/tools/testing/selftests/bpf/verifier/value_ptr_arith.c ++++ b/tools/testing/selftests/bpf/verifier/value_ptr_arith.c +@@ -302,8 +302,6 @@ + }, + .fixup_map_array_48b = { 3 }, + .result = ACCEPT, +- .result_unpriv = REJECT, +- .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range", + .retval = 1, + }, + { +@@ -373,8 +371,6 @@ + }, + .fixup_map_array_48b = { 3 }, + .result = ACCEPT, +- .result_unpriv = REJECT, +- .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range", + .retval = 1, + }, + { +@@ -474,8 +470,6 @@ + }, + .fixup_map_array_48b = { 3 }, + .result = ACCEPT, +- .result_unpriv = REJECT, +- .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range", + .retval = 1, + }, + { +@@ -768,8 +762,6 @@ + }, + .fixup_map_array_48b = { 3 }, + .result = ACCEPT, +- .result_unpriv = REJECT, +- .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range", + .retval = 1, + }, + { diff --git a/queue-5.10/bpf-update-selftests-to-reflect-new-error-states.patch b/queue-5.10/bpf-update-selftests-to-reflect-new-error-states.patch new file mode 100644 index 00000000000..55b22db15e2 --- /dev/null +++ b/queue-5.10/bpf-update-selftests-to-reflect-new-error-states.patch @@ -0,0 +1,315 @@ +From foo@baz Fri Aug 6 10:03:43 AM CEST 2021 +From: Ovidiu Panait +Date: Wed, 4 Aug 2021 20:09:15 +0300 +Subject: bpf: Update selftests to reflect new error states +To: stable@vger.kernel.org +Cc: bpf@vger.kernel.org, daniel@iogearbox.net +Message-ID: <20210804170917.3842969-5-ovidiu.panait@windriver.com> + +From: Daniel Borkmann + +commit d7a5091351756d0ae8e63134313c455624e36a13 upstream + +Update various selftest error messages: + + * The 'Rx tried to sub from different maps, paths, or prohibited types' + is reworked into more specific/differentiated error messages for better + guidance. + + * The change into 'value -4294967168 makes map_value pointer be out of + bounds' is due to moving the mixed bounds check into the speculation + handling and thus occuring slightly later than above mentioned sanity + check. + + * The change into 'math between map_value pointer and register with + unbounded min value' is similarly due to register sanity check coming + before the mixed bounds check. + + * The case of 'map access: known scalar += value_ptr from different maps' + now loads fine given masks are the same from the different paths (despite + max map value size being different). + +Signed-off-by: Daniel Borkmann +Reviewed-by: John Fastabend +Acked-by: Alexei Starovoitov +Signed-off-by: Ovidiu Panait +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/bpf/verifier/bounds.c | 5 -- + tools/testing/selftests/bpf/verifier/bounds_deduction.c | 21 +++++----- + tools/testing/selftests/bpf/verifier/bounds_mix_sign_unsign.c | 13 ------ + tools/testing/selftests/bpf/verifier/map_ptr.c | 4 - + tools/testing/selftests/bpf/verifier/unpriv.c | 2 + tools/testing/selftests/bpf/verifier/value_ptr_arith.c | 6 -- + 6 files changed, 16 insertions(+), 35 deletions(-) + +--- a/tools/testing/selftests/bpf/verifier/bounds.c ++++ b/tools/testing/selftests/bpf/verifier/bounds.c +@@ -261,8 +261,6 @@ + }, + .fixup_map_hash_8b = { 3 }, + /* not actually fully unbounded, but the bound is very high */ +- .errstr_unpriv = "R1 has unknown scalar with mixed signed bounds, pointer arithmetic with it prohibited for !root", +- .result_unpriv = REJECT, + .errstr = "value -4294967168 makes map_value pointer be out of bounds", + .result = REJECT, + }, +@@ -298,9 +296,6 @@ + BPF_EXIT_INSN(), + }, + .fixup_map_hash_8b = { 3 }, +- /* not actually fully unbounded, but the bound is very high */ +- .errstr_unpriv = "R1 has unknown scalar with mixed signed bounds, pointer arithmetic with it prohibited for !root", +- .result_unpriv = REJECT, + .errstr = "value -4294967168 makes map_value pointer be out of bounds", + .result = REJECT, + }, +--- a/tools/testing/selftests/bpf/verifier/bounds_deduction.c ++++ b/tools/testing/selftests/bpf/verifier/bounds_deduction.c +@@ -6,7 +6,7 @@ + BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), + BPF_EXIT_INSN(), + }, +- .errstr_unpriv = "R0 tried to sub from different maps, paths, or prohibited types", ++ .errstr_unpriv = "R1 has pointer with unsupported alu operation", + .errstr = "R0 tried to subtract pointer from scalar", + .result = REJECT, + }, +@@ -21,7 +21,7 @@ + BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0), + BPF_EXIT_INSN(), + }, +- .errstr_unpriv = "R1 tried to sub from different maps, paths, or prohibited types", ++ .errstr_unpriv = "R1 has pointer with unsupported alu operation", + .result_unpriv = REJECT, + .result = ACCEPT, + .retval = 1, +@@ -34,22 +34,23 @@ + BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), + BPF_EXIT_INSN(), + }, +- .errstr_unpriv = "R0 tried to sub from different maps, paths, or prohibited types", ++ .errstr_unpriv = "R1 has pointer with unsupported alu operation", + .errstr = "R0 tried to subtract pointer from scalar", + .result = REJECT, + }, + { + "check deducing bounds from const, 4", + .insns = { ++ BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 0, 1), + BPF_EXIT_INSN(), + BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1), + BPF_EXIT_INSN(), +- BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0), ++ BPF_ALU64_REG(BPF_SUB, BPF_REG_6, BPF_REG_0), + BPF_EXIT_INSN(), + }, +- .errstr_unpriv = "R1 tried to sub from different maps, paths, or prohibited types", ++ .errstr_unpriv = "R6 has pointer with unsupported alu operation", + .result_unpriv = REJECT, + .result = ACCEPT, + }, +@@ -61,7 +62,7 @@ + BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), + BPF_EXIT_INSN(), + }, +- .errstr_unpriv = "R0 tried to sub from different maps, paths, or prohibited types", ++ .errstr_unpriv = "R1 has pointer with unsupported alu operation", + .errstr = "R0 tried to subtract pointer from scalar", + .result = REJECT, + }, +@@ -74,7 +75,7 @@ + BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), + BPF_EXIT_INSN(), + }, +- .errstr_unpriv = "R0 tried to sub from different maps, paths, or prohibited types", ++ .errstr_unpriv = "R1 has pointer with unsupported alu operation", + .errstr = "R0 tried to subtract pointer from scalar", + .result = REJECT, + }, +@@ -88,7 +89,7 @@ + offsetof(struct __sk_buff, mark)), + BPF_EXIT_INSN(), + }, +- .errstr_unpriv = "R1 tried to sub from different maps, paths, or prohibited types", ++ .errstr_unpriv = "R1 has pointer with unsupported alu operation", + .errstr = "dereference of modified ctx ptr", + .result = REJECT, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, +@@ -103,7 +104,7 @@ + offsetof(struct __sk_buff, mark)), + BPF_EXIT_INSN(), + }, +- .errstr_unpriv = "R1 tried to add from different maps, paths, or prohibited types", ++ .errstr_unpriv = "R1 has pointer with unsupported alu operation", + .errstr = "dereference of modified ctx ptr", + .result = REJECT, + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, +@@ -116,7 +117,7 @@ + BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), + BPF_EXIT_INSN(), + }, +- .errstr_unpriv = "R0 tried to sub from different maps, paths, or prohibited types", ++ .errstr_unpriv = "R1 has pointer with unsupported alu operation", + .errstr = "R0 tried to subtract pointer from scalar", + .result = REJECT, + }, +--- a/tools/testing/selftests/bpf/verifier/bounds_mix_sign_unsign.c ++++ b/tools/testing/selftests/bpf/verifier/bounds_mix_sign_unsign.c +@@ -19,7 +19,6 @@ + }, + .fixup_map_hash_8b = { 3 }, + .errstr = "unbounded min value", +- .errstr_unpriv = "R1 has unknown scalar with mixed signed bounds", + .result = REJECT, + }, + { +@@ -43,7 +42,6 @@ + }, + .fixup_map_hash_8b = { 3 }, + .errstr = "unbounded min value", +- .errstr_unpriv = "R1 has unknown scalar with mixed signed bounds", + .result = REJECT, + }, + { +@@ -69,7 +67,6 @@ + }, + .fixup_map_hash_8b = { 3 }, + .errstr = "unbounded min value", +- .errstr_unpriv = "R8 has unknown scalar with mixed signed bounds", + .result = REJECT, + }, + { +@@ -94,7 +91,6 @@ + }, + .fixup_map_hash_8b = { 3 }, + .errstr = "unbounded min value", +- .errstr_unpriv = "R8 has unknown scalar with mixed signed bounds", + .result = REJECT, + }, + { +@@ -141,7 +137,6 @@ + }, + .fixup_map_hash_8b = { 3 }, + .errstr = "unbounded min value", +- .errstr_unpriv = "R1 has unknown scalar with mixed signed bounds", + .result = REJECT, + }, + { +@@ -210,7 +205,6 @@ + }, + .fixup_map_hash_8b = { 3 }, + .errstr = "unbounded min value", +- .errstr_unpriv = "R1 has unknown scalar with mixed signed bounds", + .result = REJECT, + }, + { +@@ -260,7 +254,6 @@ + }, + .fixup_map_hash_8b = { 3 }, + .errstr = "unbounded min value", +- .errstr_unpriv = "R1 has unknown scalar with mixed signed bounds", + .result = REJECT, + }, + { +@@ -287,7 +280,6 @@ + }, + .fixup_map_hash_8b = { 3 }, + .errstr = "unbounded min value", +- .errstr_unpriv = "R1 has unknown scalar with mixed signed bounds", + .result = REJECT, + }, + { +@@ -313,7 +305,6 @@ + }, + .fixup_map_hash_8b = { 3 }, + .errstr = "unbounded min value", +- .errstr_unpriv = "R1 has unknown scalar with mixed signed bounds", + .result = REJECT, + }, + { +@@ -342,7 +333,6 @@ + }, + .fixup_map_hash_8b = { 3 }, + .errstr = "unbounded min value", +- .errstr_unpriv = "R7 has unknown scalar with mixed signed bounds", + .result = REJECT, + }, + { +@@ -372,7 +362,6 @@ + }, + .fixup_map_hash_8b = { 4 }, + .errstr = "unbounded min value", +- .errstr_unpriv = "R1 has unknown scalar with mixed signed bounds", + .result = REJECT, + }, + { +@@ -400,7 +389,5 @@ + }, + .fixup_map_hash_8b = { 3 }, + .errstr = "unbounded min value", +- .errstr_unpriv = "R1 has unknown scalar with mixed signed bounds", + .result = REJECT, +- .result_unpriv = REJECT, + }, +--- a/tools/testing/selftests/bpf/verifier/map_ptr.c ++++ b/tools/testing/selftests/bpf/verifier/map_ptr.c +@@ -75,7 +75,7 @@ + }, + .fixup_map_hash_16b = { 4 }, + .result_unpriv = REJECT, +- .errstr_unpriv = "R1 tried to add from different maps, paths, or prohibited types", ++ .errstr_unpriv = "R1 has pointer with unsupported alu operation", + .result = ACCEPT, + }, + { +@@ -93,6 +93,6 @@ + }, + .fixup_map_hash_16b = { 4 }, + .result_unpriv = REJECT, +- .errstr_unpriv = "R1 tried to add from different maps, paths, or prohibited types", ++ .errstr_unpriv = "R0 has pointer with unsupported alu operation", + .result = ACCEPT, + }, +--- a/tools/testing/selftests/bpf/verifier/unpriv.c ++++ b/tools/testing/selftests/bpf/verifier/unpriv.c +@@ -504,7 +504,7 @@ + BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, -8), + BPF_EXIT_INSN(), + }, +- .errstr_unpriv = "R1 tried to add from different maps, paths, or prohibited types", ++ .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", + .result_unpriv = REJECT, + .result = ACCEPT, + }, +--- a/tools/testing/selftests/bpf/verifier/value_ptr_arith.c ++++ b/tools/testing/selftests/bpf/verifier/value_ptr_arith.c +@@ -21,8 +21,6 @@ + .fixup_map_hash_16b = { 5 }, + .fixup_map_array_48b = { 8 }, + .result = ACCEPT, +- .result_unpriv = REJECT, +- .errstr_unpriv = "R1 tried to add from different maps", + .retval = 1, + }, + { +@@ -122,7 +120,7 @@ + .fixup_map_array_48b = { 1 }, + .result = ACCEPT, + .result_unpriv = REJECT, +- .errstr_unpriv = "R2 tried to add from different pointers or scalars", ++ .errstr_unpriv = "R2 tried to add from different maps, paths or scalars", + .retval = 0, + }, + { +@@ -169,7 +167,7 @@ + .fixup_map_array_48b = { 1 }, + .result = ACCEPT, + .result_unpriv = REJECT, +- .errstr_unpriv = "R2 tried to add from different maps, paths, or prohibited types", ++ .errstr_unpriv = "R2 tried to add from different maps, paths or scalars", + .retval = 0, + }, + { diff --git a/queue-5.10/selftest-bpf-adjust-expected-verifier-errors.patch b/queue-5.10/selftest-bpf-adjust-expected-verifier-errors.patch new file mode 100644 index 00000000000..ef21b21a179 --- /dev/null +++ b/queue-5.10/selftest-bpf-adjust-expected-verifier-errors.patch @@ -0,0 +1,387 @@ +From foo@baz Fri Aug 6 10:03:43 AM CEST 2021 +From: Ovidiu Panait +Date: Wed, 4 Aug 2021 20:09:13 +0300 +Subject: selftest/bpf: Adjust expected verifier errors +To: stable@vger.kernel.org +Cc: bpf@vger.kernel.org, daniel@iogearbox.net +Message-ID: <20210804170917.3842969-3-ovidiu.panait@windriver.com> + +From: Andrei Matei + +commit a680cb3d8e3f4f84205720b90c926579d04eedb6 upstream + +The verifier errors around stack accesses have changed slightly in the +previous commit (generally for the better). + +Signed-off-by: Andrei Matei +Signed-off-by: Alexei Starovoitov +Link: https://lore.kernel.org/bpf/20210207011027.676572-3-andreimatei1@gmail.com +Signed-off-by: Ovidiu Panait +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/bpf/verifier/basic_stack.c | 2 - + tools/testing/selftests/bpf/verifier/calls.c | 4 +- + tools/testing/selftests/bpf/verifier/const_or.c | 4 +- + tools/testing/selftests/bpf/verifier/helper_access_var_len.c | 12 +++--- + tools/testing/selftests/bpf/verifier/int_ptr.c | 6 +-- + tools/testing/selftests/bpf/verifier/raw_stack.c | 10 ++--- + tools/testing/selftests/bpf/verifier/stack_ptr.c | 22 ++++++----- + tools/testing/selftests/bpf/verifier/unpriv.c | 2 - + tools/testing/selftests/bpf/verifier/var_off.c | 16 ++++---- + 9 files changed, 41 insertions(+), 37 deletions(-) + +--- a/tools/testing/selftests/bpf/verifier/basic_stack.c ++++ b/tools/testing/selftests/bpf/verifier/basic_stack.c +@@ -4,7 +4,7 @@ + BPF_ST_MEM(BPF_DW, BPF_REG_10, 8, 0), + BPF_EXIT_INSN(), + }, +- .errstr = "invalid stack", ++ .errstr = "invalid write to stack", + .result = REJECT, + }, + { +--- a/tools/testing/selftests/bpf/verifier/calls.c ++++ b/tools/testing/selftests/bpf/verifier/calls.c +@@ -1228,7 +1228,7 @@ + .prog_type = BPF_PROG_TYPE_XDP, + .fixup_map_hash_8b = { 23 }, + .result = REJECT, +- .errstr = "invalid read from stack off -16+0 size 8", ++ .errstr = "invalid read from stack R7 off=-16 size=8", + }, + { + "calls: two calls that receive map_value via arg=ptr_stack_of_caller. test1", +@@ -1958,7 +1958,7 @@ + BPF_EXIT_INSN(), + }, + .fixup_map_hash_48b = { 6 }, +- .errstr = "invalid indirect read from stack off -8+0 size 8", ++ .errstr = "invalid indirect read from stack R2 off -8+0 size 8", + .result = REJECT, + .prog_type = BPF_PROG_TYPE_XDP, + }, +--- a/tools/testing/selftests/bpf/verifier/const_or.c ++++ b/tools/testing/selftests/bpf/verifier/const_or.c +@@ -23,7 +23,7 @@ + BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel), + BPF_EXIT_INSN(), + }, +- .errstr = "invalid stack type R1 off=-48 access_size=58", ++ .errstr = "invalid indirect access to stack R1 off=-48 size=58", + .result = REJECT, + .prog_type = BPF_PROG_TYPE_TRACEPOINT, + }, +@@ -54,7 +54,7 @@ + BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel), + BPF_EXIT_INSN(), + }, +- .errstr = "invalid stack type R1 off=-48 access_size=58", ++ .errstr = "invalid indirect access to stack R1 off=-48 size=58", + .result = REJECT, + .prog_type = BPF_PROG_TYPE_TRACEPOINT, + }, +--- a/tools/testing/selftests/bpf/verifier/helper_access_var_len.c ++++ b/tools/testing/selftests/bpf/verifier/helper_access_var_len.c +@@ -39,7 +39,7 @@ + BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel), + BPF_EXIT_INSN(), + }, +- .errstr = "invalid indirect read from stack off -64+0 size 64", ++ .errstr = "invalid indirect read from stack R1 off -64+0 size 64", + .result = REJECT, + .prog_type = BPF_PROG_TYPE_TRACEPOINT, + }, +@@ -59,7 +59,7 @@ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, +- .errstr = "invalid stack type R1 off=-64 access_size=65", ++ .errstr = "invalid indirect access to stack R1 off=-64 size=65", + .result = REJECT, + .prog_type = BPF_PROG_TYPE_TRACEPOINT, + }, +@@ -136,7 +136,7 @@ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, +- .errstr = "invalid stack type R1 off=-64 access_size=65", ++ .errstr = "invalid indirect access to stack R1 off=-64 size=65", + .result = REJECT, + .prog_type = BPF_PROG_TYPE_TRACEPOINT, + }, +@@ -156,7 +156,7 @@ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, +- .errstr = "invalid stack type R1 off=-64 access_size=65", ++ .errstr = "invalid indirect access to stack R1 off=-64 size=65", + .result = REJECT, + .prog_type = BPF_PROG_TYPE_TRACEPOINT, + }, +@@ -194,7 +194,7 @@ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, +- .errstr = "invalid indirect read from stack off -64+0 size 64", ++ .errstr = "invalid indirect read from stack R1 off -64+0 size 64", + .result = REJECT, + .prog_type = BPF_PROG_TYPE_TRACEPOINT, + }, +@@ -584,7 +584,7 @@ + BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16), + BPF_EXIT_INSN(), + }, +- .errstr = "invalid indirect read from stack off -64+32 size 64", ++ .errstr = "invalid indirect read from stack R1 off -64+32 size 64", + .result = REJECT, + .prog_type = BPF_PROG_TYPE_TRACEPOINT, + }, +--- a/tools/testing/selftests/bpf/verifier/int_ptr.c ++++ b/tools/testing/selftests/bpf/verifier/int_ptr.c +@@ -27,7 +27,7 @@ + }, + .result = REJECT, + .prog_type = BPF_PROG_TYPE_CGROUP_SYSCTL, +- .errstr = "invalid indirect read from stack off -16+0 size 8", ++ .errstr = "invalid indirect read from stack R4 off -16+0 size 8", + }, + { + "ARG_PTR_TO_LONG half-uninitialized", +@@ -59,7 +59,7 @@ + }, + .result = REJECT, + .prog_type = BPF_PROG_TYPE_CGROUP_SYSCTL, +- .errstr = "invalid indirect read from stack off -16+4 size 8", ++ .errstr = "invalid indirect read from stack R4 off -16+4 size 8", + }, + { + "ARG_PTR_TO_LONG misaligned", +@@ -125,7 +125,7 @@ + }, + .result = REJECT, + .prog_type = BPF_PROG_TYPE_CGROUP_SYSCTL, +- .errstr = "invalid stack type R4 off=-4 access_size=8", ++ .errstr = "invalid indirect access to stack R4 off=-4 size=8", + }, + { + "ARG_PTR_TO_LONG initialized", +--- a/tools/testing/selftests/bpf/verifier/raw_stack.c ++++ b/tools/testing/selftests/bpf/verifier/raw_stack.c +@@ -11,7 +11,7 @@ + BPF_EXIT_INSN(), + }, + .result = REJECT, +- .errstr = "invalid read from stack off -8+0 size 8", ++ .errstr = "invalid read from stack R6 off=-8 size=8", + .prog_type = BPF_PROG_TYPE_SCHED_CLS, + }, + { +@@ -59,7 +59,7 @@ + BPF_EXIT_INSN(), + }, + .result = REJECT, +- .errstr = "invalid stack type R3", ++ .errstr = "invalid zero-sized read", + .prog_type = BPF_PROG_TYPE_SCHED_CLS, + }, + { +@@ -205,7 +205,7 @@ + BPF_EXIT_INSN(), + }, + .result = REJECT, +- .errstr = "invalid stack type R3 off=-513 access_size=8", ++ .errstr = "invalid indirect access to stack R3 off=-513 size=8", + .prog_type = BPF_PROG_TYPE_SCHED_CLS, + }, + { +@@ -221,7 +221,7 @@ + BPF_EXIT_INSN(), + }, + .result = REJECT, +- .errstr = "invalid stack type R3 off=-1 access_size=8", ++ .errstr = "invalid indirect access to stack R3 off=-1 size=8", + .prog_type = BPF_PROG_TYPE_SCHED_CLS, + }, + { +@@ -285,7 +285,7 @@ + BPF_EXIT_INSN(), + }, + .result = REJECT, +- .errstr = "invalid stack type R3 off=-512 access_size=0", ++ .errstr = "invalid zero-sized read", + .prog_type = BPF_PROG_TYPE_SCHED_CLS, + }, + { +--- a/tools/testing/selftests/bpf/verifier/stack_ptr.c ++++ b/tools/testing/selftests/bpf/verifier/stack_ptr.c +@@ -44,7 +44,7 @@ + BPF_EXIT_INSN(), + }, + .result = REJECT, +- .errstr = "invalid stack off=-79992 size=8", ++ .errstr = "invalid write to stack R1 off=-79992 size=8", + .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", + }, + { +@@ -57,7 +57,7 @@ + BPF_EXIT_INSN(), + }, + .result = REJECT, +- .errstr = "invalid stack off=0 size=8", ++ .errstr = "invalid write to stack R1 off=0 size=8", + }, + { + "PTR_TO_STACK check high 1", +@@ -106,7 +106,7 @@ + BPF_EXIT_INSN(), + }, + .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", +- .errstr = "invalid stack off=0 size=1", ++ .errstr = "invalid write to stack R1 off=0 size=1", + .result = REJECT, + }, + { +@@ -119,7 +119,8 @@ + BPF_EXIT_INSN(), + }, + .result = REJECT, +- .errstr = "invalid stack off", ++ .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", ++ .errstr = "invalid write to stack R1", + }, + { + "PTR_TO_STACK check high 6", +@@ -131,7 +132,8 @@ + BPF_EXIT_INSN(), + }, + .result = REJECT, +- .errstr = "invalid stack off", ++ .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", ++ .errstr = "invalid write to stack", + }, + { + "PTR_TO_STACK check high 7", +@@ -183,7 +185,7 @@ + BPF_EXIT_INSN(), + }, + .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", +- .errstr = "invalid stack off=-513 size=1", ++ .errstr = "invalid write to stack R1 off=-513 size=1", + .result = REJECT, + }, + { +@@ -208,7 +210,8 @@ + BPF_EXIT_INSN(), + }, + .result = REJECT, +- .errstr = "invalid stack off", ++ .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", ++ .errstr = "invalid write to stack", + }, + { + "PTR_TO_STACK check low 6", +@@ -220,7 +223,8 @@ + BPF_EXIT_INSN(), + }, + .result = REJECT, +- .errstr = "invalid stack off", ++ .errstr = "invalid write to stack", ++ .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", + }, + { + "PTR_TO_STACK check low 7", +@@ -292,7 +296,7 @@ + BPF_EXIT_INSN(), + }, + .result_unpriv = REJECT, +- .errstr_unpriv = "invalid stack off=0 size=1", ++ .errstr_unpriv = "invalid write to stack R1 off=0 size=1", + .result = ACCEPT, + .retval = 42, + }, +--- a/tools/testing/selftests/bpf/verifier/unpriv.c ++++ b/tools/testing/selftests/bpf/verifier/unpriv.c +@@ -108,7 +108,7 @@ + BPF_EXIT_INSN(), + }, + .fixup_map_hash_8b = { 3 }, +- .errstr_unpriv = "invalid indirect read from stack off -8+0 size 8", ++ .errstr_unpriv = "invalid indirect read from stack R2 off -8+0 size 8", + .result_unpriv = REJECT, + .result = ACCEPT, + }, +--- a/tools/testing/selftests/bpf/verifier/var_off.c ++++ b/tools/testing/selftests/bpf/verifier/var_off.c +@@ -18,7 +18,7 @@ + .prog_type = BPF_PROG_TYPE_LWT_IN, + }, + { +- "variable-offset stack access", ++ "variable-offset stack read, priv vs unpriv", + .insns = { + /* Fill the top 8 bytes of the stack */ + BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), +@@ -63,7 +63,7 @@ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, +- .errstr = "R4 unbounded indirect variable offset stack access", ++ .errstr = "invalid unbounded variable-offset indirect access to stack R4", + .result = REJECT, + .prog_type = BPF_PROG_TYPE_SOCK_OPS, + }, +@@ -88,7 +88,7 @@ + BPF_EXIT_INSN(), + }, + .fixup_map_hash_8b = { 5 }, +- .errstr = "R2 max value is outside of stack bound", ++ .errstr = "invalid variable-offset indirect access to stack R2", + .result = REJECT, + .prog_type = BPF_PROG_TYPE_LWT_IN, + }, +@@ -113,7 +113,7 @@ + BPF_EXIT_INSN(), + }, + .fixup_map_hash_8b = { 5 }, +- .errstr = "R2 min value is outside of stack bound", ++ .errstr = "invalid variable-offset indirect access to stack R2", + .result = REJECT, + .prog_type = BPF_PROG_TYPE_LWT_IN, + }, +@@ -138,7 +138,7 @@ + BPF_EXIT_INSN(), + }, + .fixup_map_hash_8b = { 5 }, +- .errstr = "invalid indirect read from stack var_off", ++ .errstr = "invalid indirect read from stack R2 var_off", + .result = REJECT, + .prog_type = BPF_PROG_TYPE_LWT_IN, + }, +@@ -163,7 +163,7 @@ + BPF_EXIT_INSN(), + }, + .fixup_map_hash_8b = { 5 }, +- .errstr = "invalid indirect read from stack var_off", ++ .errstr = "invalid indirect read from stack R2 var_off", + .result = REJECT, + .prog_type = BPF_PROG_TYPE_LWT_IN, + }, +@@ -189,7 +189,7 @@ + BPF_EXIT_INSN(), + }, + .fixup_map_hash_8b = { 6 }, +- .errstr_unpriv = "R2 stack pointer arithmetic goes out of range, prohibited for !root", ++ .errstr_unpriv = "R2 variable stack access prohibited for !root", + .result_unpriv = REJECT, + .result = ACCEPT, + .prog_type = BPF_PROG_TYPE_CGROUP_SKB, +@@ -217,7 +217,7 @@ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, +- .errstr = "invalid indirect read from stack var_off", ++ .errstr = "invalid indirect read from stack R4 var_off", + .result = REJECT, + .prog_type = BPF_PROG_TYPE_SOCK_OPS, + }, diff --git a/queue-5.10/selftest-bpf-verifier-tests-for-var-off-access.patch b/queue-5.10/selftest-bpf-verifier-tests-for-var-off-access.patch new file mode 100644 index 00000000000..70ffc3b2d0e --- /dev/null +++ b/queue-5.10/selftest-bpf-verifier-tests-for-var-off-access.patch @@ -0,0 +1,139 @@ +From foo@baz Fri Aug 6 10:03:43 AM CEST 2021 +From: Ovidiu Panait +Date: Wed, 4 Aug 2021 20:09:17 +0300 +Subject: selftest/bpf: Verifier tests for var-off access +To: stable@vger.kernel.org +Cc: bpf@vger.kernel.org, daniel@iogearbox.net +Message-ID: <20210804170917.3842969-7-ovidiu.panait@windriver.com> + +From: Andrei Matei + +commit 7a22930c4179b51352f2ec9feb35167cbe79afd9 upstream + +Add tests for the new functionality - reading and writing to the stack +through a variable-offset pointer. + +Signed-off-by: Andrei Matei +Signed-off-by: Alexei Starovoitov +Link: https://lore.kernel.org/bpf/20210207011027.676572-4-andreimatei1@gmail.com +Signed-off-by: Ovidiu Panait +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/bpf/verifier/var_off.c | 99 ++++++++++++++++++++++++- + 1 file changed, 97 insertions(+), 2 deletions(-) + +--- a/tools/testing/selftests/bpf/verifier/var_off.c ++++ b/tools/testing/selftests/bpf/verifier/var_off.c +@@ -31,15 +31,110 @@ + * we don't know which + */ + BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10), +- /* dereference it */ ++ /* dereference it for a stack read */ + BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0), ++ BPF_MOV64_IMM(BPF_REG_0, 0), ++ BPF_EXIT_INSN(), ++ }, ++ .result = ACCEPT, ++ .result_unpriv = REJECT, ++ .errstr_unpriv = "R2 variable stack access prohibited for !root", ++ .prog_type = BPF_PROG_TYPE_CGROUP_SKB, ++}, ++{ ++ "variable-offset stack read, uninitialized", ++ .insns = { ++ /* Get an unknown value */ ++ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0), ++ /* Make it small and 4-byte aligned */ ++ BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4), ++ BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 8), ++ /* add it to fp. We now have either fp-4 or fp-8, but ++ * we don't know which ++ */ ++ BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10), ++ /* dereference it for a stack read */ ++ BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0), ++ BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, +- .errstr = "variable stack access var_off=(0xfffffffffffffff8; 0x4)", + .result = REJECT, ++ .errstr = "invalid variable-offset read from stack R2", + .prog_type = BPF_PROG_TYPE_LWT_IN, + }, + { ++ "variable-offset stack write, priv vs unpriv", ++ .insns = { ++ /* Get an unknown value */ ++ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0), ++ /* Make it small and 8-byte aligned */ ++ BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 8), ++ BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 16), ++ /* Add it to fp. We now have either fp-8 or fp-16, but ++ * we don't know which ++ */ ++ BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10), ++ /* Dereference it for a stack write */ ++ BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0), ++ /* Now read from the address we just wrote. This shows ++ * that, after a variable-offset write, a priviledged ++ * program can read the slots that were in the range of ++ * that write (even if the verifier doesn't actually know ++ * if the slot being read was really written to or not. ++ */ ++ BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_2, 0), ++ BPF_MOV64_IMM(BPF_REG_0, 0), ++ BPF_EXIT_INSN(), ++ }, ++ /* Variable stack access is rejected for unprivileged. ++ */ ++ .errstr_unpriv = "R2 variable stack access prohibited for !root", ++ .result_unpriv = REJECT, ++ .result = ACCEPT, ++}, ++{ ++ "variable-offset stack write clobbers spilled regs", ++ .insns = { ++ /* Dummy instruction; needed because we need to patch the next one ++ * and we can't patch the first instruction. ++ */ ++ BPF_MOV64_IMM(BPF_REG_6, 0), ++ /* Make R0 a map ptr */ ++ BPF_LD_MAP_FD(BPF_REG_0, 0), ++ /* Get an unknown value */ ++ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0), ++ /* Make it small and 8-byte aligned */ ++ BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 8), ++ BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 16), ++ /* Add it to fp. We now have either fp-8 or fp-16, but ++ * we don't know which. ++ */ ++ BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10), ++ /* Spill R0(map ptr) into stack */ ++ BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8), ++ /* Dereference the unknown value for a stack write */ ++ BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0), ++ /* Fill the register back into R2 */ ++ BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8), ++ /* Try to dereference R2 for a memory load */ ++ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8), ++ BPF_EXIT_INSN(), ++ }, ++ .fixup_map_hash_8b = { 1 }, ++ /* The unpriviledged case is not too interesting; variable ++ * stack access is rejected. ++ */ ++ .errstr_unpriv = "R2 variable stack access prohibited for !root", ++ .result_unpriv = REJECT, ++ /* In the priviledged case, dereferencing a spilled-and-then-filled ++ * register is rejected because the previous variable offset stack ++ * write might have overwritten the spilled pointer (i.e. we lose track ++ * of the spilled register when we analyze the write). ++ */ ++ .errstr = "R2 invalid mem access 'inv'", ++ .result = REJECT, ++}, ++{ + "indirect variable-offset stack access, unbounded", + .insns = { + BPF_MOV64_IMM(BPF_REG_2, 6), diff --git a/queue-5.10/selftests-bpf-add-a-test-for-ptr_to_map_value-on-stack-for-helper-access.patch b/queue-5.10/selftests-bpf-add-a-test-for-ptr_to_map_value-on-stack-for-helper-access.patch new file mode 100644 index 00000000000..12ea57b1a56 --- /dev/null +++ b/queue-5.10/selftests-bpf-add-a-test-for-ptr_to_map_value-on-stack-for-helper-access.patch @@ -0,0 +1,55 @@ +From foo@baz Fri Aug 6 10:03:43 AM CEST 2021 +From: Ovidiu Panait +Date: Wed, 4 Aug 2021 20:09:12 +0300 +Subject: selftests/bpf: Add a test for ptr_to_map_value on stack for helper access +To: stable@vger.kernel.org +Cc: bpf@vger.kernel.org, daniel@iogearbox.net +Message-ID: <20210804170917.3842969-2-ovidiu.panait@windriver.com> + +From: Yonghong Song + +commit b4b638c36b7e7acd847b9c4b9c80f268e45ea30c upstream + +Change bpf_iter_task.c such that pointer to map_value may appear +on the stack for bpf_seq_printf() to access. Without previous +verifier patch, the bpf_iter test will fail. + +Signed-off-by: Yonghong Song +Signed-off-by: Daniel Borkmann +Acked-by: Song Liu +Link: https://lore.kernel.org/bpf/20201210013350.943985-1-yhs@fb.com +Signed-off-by: Ovidiu Panait +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/bpf/progs/bpf_iter_task.c | 3 ++- + tools/testing/selftests/bpf/verifier/unpriv.c | 5 +++-- + 2 files changed, 5 insertions(+), 3 deletions(-) + +--- a/tools/testing/selftests/bpf/progs/bpf_iter_task.c ++++ b/tools/testing/selftests/bpf/progs/bpf_iter_task.c +@@ -11,9 +11,10 @@ int dump_task(struct bpf_iter__task *ctx + { + struct seq_file *seq = ctx->meta->seq; + struct task_struct *task = ctx->task; ++ static char info[] = " === END ==="; + + if (task == (void *)0) { +- BPF_SEQ_PRINTF(seq, " === END ===\n"); ++ BPF_SEQ_PRINTF(seq, "%s\n", info); + return 0; + } + +--- a/tools/testing/selftests/bpf/verifier/unpriv.c ++++ b/tools/testing/selftests/bpf/verifier/unpriv.c +@@ -108,8 +108,9 @@ + BPF_EXIT_INSN(), + }, + .fixup_map_hash_8b = { 3 }, +- .errstr = "invalid indirect read from stack off -8+0 size 8", +- .result = REJECT, ++ .errstr_unpriv = "invalid indirect read from stack off -8+0 size 8", ++ .result_unpriv = REJECT, ++ .result = ACCEPT, + }, + { + "unpriv: mangle pointer on stack 1", diff --git a/queue-5.10/series b/queue-5.10/series index 0aaa72659d8..5a2fdc7124e 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -22,3 +22,9 @@ revert-bluetooth-shutdown-controller-after-workqueues-are-flushed-or-cancelled.p firmware-arm_scmi-ensure-drivers-provide-a-probe-function.patch firmware-arm_scmi-add-delayed-response-status-check.patch revert-watchdog-itco_wdt-account-for-rebooting-on-second-timeout.patch +selftests-bpf-add-a-test-for-ptr_to_map_value-on-stack-for-helper-access.patch +selftest-bpf-adjust-expected-verifier-errors.patch +bpf-selftests-adjust-few-selftest-result_unpriv-outcomes.patch +bpf-update-selftests-to-reflect-new-error-states.patch +bpf-selftests-adjust-few-selftest-outcomes-wrt-unreachable-code.patch +selftest-bpf-verifier-tests-for-var-off-access.patch -- 2.47.3