aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2017-11-22 15:40:54 -0500
committerDaniel Borkmann <daniel@iogearbox.net>2017-11-22 15:40:55 -0500
commit107af8ec117b0af6e90ddfe42e568b2efd8f6ff7 (patch)
tree1606e891bab8ee8bf102c3f0a3b4319d81a0ef2d /tools
parentf1a8b8e3d98b0b3d1d88d119f52cc85d05ab3189 (diff)
parenta60dd35d2e39209fa7645945e1192bf9769872c6 (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.c113
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),