diff options
author | Daniel Borkmann <daniel@iogearbox.net> | 2017-11-22 15:40:54 -0500 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2017-11-22 15:40:55 -0500 |
commit | 107af8ec117b0af6e90ddfe42e568b2efd8f6ff7 (patch) | |
tree | 1606e891bab8ee8bf102c3f0a3b4319d81a0ef2d /tools | |
parent | f1a8b8e3d98b0b3d1d88d119f52cc85d05ab3189 (diff) | |
parent | a60dd35d2e39209fa7645945e1192bf9769872c6 (diff) |
Merge branch 'bpf-fix-null-arg-semantics'
Gianluca Borello says:
====================
This set includes some fixes in semantics and usability issues that emerged
recently, and would be good to have them in net before the next release.
In particular, ARG_CONST_SIZE_OR_ZERO semantics was recently changed in
commit 9fd29c08e520 ("bpf: improve verifier ARG_CONST_SIZE_OR_ZERO
semantics") with the goal of letting the compiler generate simpler code
that the verifier can more easily accept.
To handle this change in semantics, a few checks in some helpers were
added, like in commit 9c019e2bc4b2 ("bpf: change helper bpf_probe_read arg2
type to ARG_CONST_SIZE_OR_ZERO"), and those checks are less than ideal
because once they make it into a released kernel bpf programs can start
relying on them, preventing the possibility of being removed later on.
This patch tries to fix the issue by introducing a new argument type
ARG_PTR_TO_MEM_OR_NULL that can be used for helpers that can receive a
<NULL, 0> tuple. By doing so, we can fix the semantics of the other helpers
that don't need <NULL, 0> and can just handle <!NULL, 0>, allowing the code
to get rid of those checks.
====================
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/testing/selftests/bpf/test_verifier.c | 113 |
1 files changed, 106 insertions, 7 deletions
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c index 2a5267bef160..3c64f30cf63c 100644 --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c | |||
@@ -5631,7 +5631,7 @@ static struct bpf_test tests[] = { | |||
5631 | .prog_type = BPF_PROG_TYPE_TRACEPOINT, | 5631 | .prog_type = BPF_PROG_TYPE_TRACEPOINT, |
5632 | }, | 5632 | }, |
5633 | { | 5633 | { |
5634 | "helper access to variable memory: size = 0 allowed on NULL", | 5634 | "helper access to variable memory: size = 0 allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)", |
5635 | .insns = { | 5635 | .insns = { |
5636 | BPF_MOV64_IMM(BPF_REG_1, 0), | 5636 | BPF_MOV64_IMM(BPF_REG_1, 0), |
5637 | BPF_MOV64_IMM(BPF_REG_2, 0), | 5637 | BPF_MOV64_IMM(BPF_REG_2, 0), |
@@ -5645,7 +5645,7 @@ static struct bpf_test tests[] = { | |||
5645 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | 5645 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, |
5646 | }, | 5646 | }, |
5647 | { | 5647 | { |
5648 | "helper access to variable memory: size > 0 not allowed on NULL", | 5648 | "helper access to variable memory: size > 0 not allowed on NULL (ARG_PTR_TO_MEM_OR_NULL)", |
5649 | .insns = { | 5649 | .insns = { |
5650 | BPF_MOV64_IMM(BPF_REG_1, 0), | 5650 | BPF_MOV64_IMM(BPF_REG_1, 0), |
5651 | BPF_MOV64_IMM(BPF_REG_2, 0), | 5651 | BPF_MOV64_IMM(BPF_REG_2, 0), |
@@ -5663,7 +5663,7 @@ static struct bpf_test tests[] = { | |||
5663 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | 5663 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, |
5664 | }, | 5664 | }, |
5665 | { | 5665 | { |
5666 | "helper access to variable memory: size = 0 allowed on != NULL stack pointer", | 5666 | "helper access to variable memory: size = 0 allowed on != NULL stack pointer (ARG_PTR_TO_MEM_OR_NULL)", |
5667 | .insns = { | 5667 | .insns = { |
5668 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), | 5668 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), |
5669 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), | 5669 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), |
@@ -5680,7 +5680,7 @@ static struct bpf_test tests[] = { | |||
5680 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | 5680 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, |
5681 | }, | 5681 | }, |
5682 | { | 5682 | { |
5683 | "helper access to variable memory: size = 0 allowed on != NULL map pointer", | 5683 | "helper access to variable memory: size = 0 allowed on != NULL map pointer (ARG_PTR_TO_MEM_OR_NULL)", |
5684 | .insns = { | 5684 | .insns = { |
5685 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | 5685 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
5686 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | 5686 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
@@ -5702,7 +5702,7 @@ static struct bpf_test tests[] = { | |||
5702 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | 5702 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, |
5703 | }, | 5703 | }, |
5704 | { | 5704 | { |
5705 | "helper access to variable memory: size possible = 0 allowed on != NULL stack pointer", | 5705 | "helper access to variable memory: size possible = 0 allowed on != NULL stack pointer (ARG_PTR_TO_MEM_OR_NULL)", |
5706 | .insns = { | 5706 | .insns = { |
5707 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | 5707 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
5708 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | 5708 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
@@ -5727,7 +5727,7 @@ static struct bpf_test tests[] = { | |||
5727 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | 5727 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, |
5728 | }, | 5728 | }, |
5729 | { | 5729 | { |
5730 | "helper access to variable memory: size possible = 0 allowed on != NULL map pointer", | 5730 | "helper access to variable memory: size possible = 0 allowed on != NULL map pointer (ARG_PTR_TO_MEM_OR_NULL)", |
5731 | .insns = { | 5731 | .insns = { |
5732 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | 5732 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
5733 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | 5733 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
@@ -5750,7 +5750,7 @@ static struct bpf_test tests[] = { | |||
5750 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | 5750 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, |
5751 | }, | 5751 | }, |
5752 | { | 5752 | { |
5753 | "helper access to variable memory: size possible = 0 allowed on != NULL packet pointer", | 5753 | "helper access to variable memory: size possible = 0 allowed on != NULL packet pointer (ARG_PTR_TO_MEM_OR_NULL)", |
5754 | .insns = { | 5754 | .insns = { |
5755 | BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, | 5755 | BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, |
5756 | offsetof(struct __sk_buff, data)), | 5756 | offsetof(struct __sk_buff, data)), |
@@ -5772,6 +5772,105 @@ static struct bpf_test tests[] = { | |||
5772 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | 5772 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, |
5773 | }, | 5773 | }, |
5774 | { | 5774 | { |
5775 | "helper access to variable memory: size = 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)", | ||
5776 | .insns = { | ||
5777 | BPF_MOV64_IMM(BPF_REG_1, 0), | ||
5778 | BPF_MOV64_IMM(BPF_REG_2, 0), | ||
5779 | BPF_MOV64_IMM(BPF_REG_3, 0), | ||
5780 | BPF_EMIT_CALL(BPF_FUNC_probe_read), | ||
5781 | BPF_EXIT_INSN(), | ||
5782 | }, | ||
5783 | .errstr = "R1 type=inv expected=fp", | ||
5784 | .result = REJECT, | ||
5785 | .prog_type = BPF_PROG_TYPE_TRACEPOINT, | ||
5786 | }, | ||
5787 | { | ||
5788 | "helper access to variable memory: size > 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)", | ||
5789 | .insns = { | ||
5790 | BPF_MOV64_IMM(BPF_REG_1, 0), | ||
5791 | BPF_MOV64_IMM(BPF_REG_2, 1), | ||
5792 | BPF_MOV64_IMM(BPF_REG_3, 0), | ||
5793 | BPF_EMIT_CALL(BPF_FUNC_probe_read), | ||
5794 | BPF_EXIT_INSN(), | ||
5795 | }, | ||
5796 | .errstr = "R1 type=inv expected=fp", | ||
5797 | .result = REJECT, | ||
5798 | .prog_type = BPF_PROG_TYPE_TRACEPOINT, | ||
5799 | }, | ||
5800 | { | ||
5801 | "helper access to variable memory: size = 0 allowed on != NULL stack pointer (!ARG_PTR_TO_MEM_OR_NULL)", | ||
5802 | .insns = { | ||
5803 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), | ||
5804 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), | ||
5805 | BPF_MOV64_IMM(BPF_REG_2, 0), | ||
5806 | BPF_MOV64_IMM(BPF_REG_3, 0), | ||
5807 | BPF_EMIT_CALL(BPF_FUNC_probe_read), | ||
5808 | BPF_EXIT_INSN(), | ||
5809 | }, | ||
5810 | .result = ACCEPT, | ||
5811 | .prog_type = BPF_PROG_TYPE_TRACEPOINT, | ||
5812 | }, | ||
5813 | { | ||
5814 | "helper access to variable memory: size = 0 allowed on != NULL map pointer (!ARG_PTR_TO_MEM_OR_NULL)", | ||
5815 | .insns = { | ||
5816 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
5817 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
5818 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
5819 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
5820 | BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), | ||
5821 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4), | ||
5822 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
5823 | BPF_MOV64_IMM(BPF_REG_2, 0), | ||
5824 | BPF_MOV64_IMM(BPF_REG_3, 0), | ||
5825 | BPF_EMIT_CALL(BPF_FUNC_probe_read), | ||
5826 | BPF_EXIT_INSN(), | ||
5827 | }, | ||
5828 | .fixup_map1 = { 3 }, | ||
5829 | .result = ACCEPT, | ||
5830 | .prog_type = BPF_PROG_TYPE_TRACEPOINT, | ||
5831 | }, | ||
5832 | { | ||
5833 | "helper access to variable memory: size possible = 0 allowed on != NULL stack pointer (!ARG_PTR_TO_MEM_OR_NULL)", | ||
5834 | .insns = { | ||
5835 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
5836 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
5837 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
5838 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
5839 | BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), | ||
5840 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6), | ||
5841 | BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0), | ||
5842 | BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 4), | ||
5843 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), | ||
5844 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), | ||
5845 | BPF_MOV64_IMM(BPF_REG_3, 0), | ||
5846 | BPF_EMIT_CALL(BPF_FUNC_probe_read), | ||
5847 | BPF_EXIT_INSN(), | ||
5848 | }, | ||
5849 | .fixup_map1 = { 3 }, | ||
5850 | .result = ACCEPT, | ||
5851 | .prog_type = BPF_PROG_TYPE_TRACEPOINT, | ||
5852 | }, | ||
5853 | { | ||
5854 | "helper access to variable memory: size possible = 0 allowed on != NULL map pointer (!ARG_PTR_TO_MEM_OR_NULL)", | ||
5855 | .insns = { | ||
5856 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
5857 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
5858 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
5859 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
5860 | BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), | ||
5861 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5), | ||
5862 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
5863 | BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0), | ||
5864 | BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 8, 2), | ||
5865 | BPF_MOV64_IMM(BPF_REG_3, 0), | ||
5866 | BPF_EMIT_CALL(BPF_FUNC_probe_read), | ||
5867 | BPF_EXIT_INSN(), | ||
5868 | }, | ||
5869 | .fixup_map1 = { 3 }, | ||
5870 | .result = ACCEPT, | ||
5871 | .prog_type = BPF_PROG_TYPE_TRACEPOINT, | ||
5872 | }, | ||
5873 | { | ||
5775 | "helper access to variable memory: 8 bytes leak", | 5874 | "helper access to variable memory: 8 bytes leak", |
5776 | .insns = { | 5875 | .insns = { |
5777 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), | 5876 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), |