aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2018-01-18 16:38:59 -0500
committerDaniel Borkmann <daniel@iogearbox.net>2018-01-18 16:39:40 -0500
commit0c91c4239d23d44a5cb95f51e9d4b71d88793d75 (patch)
tree7ca9af66f490c3d959c3c6e9042bf86b1c513563 /tools
parente7b2823a582a5bca5ee47644f448e317178e8824 (diff)
parent111e6b45315c8d13658f23885b30eb9df3ea2914 (diff)
Merge branch 'bpf-improve-test-verifier-coverage'
Alexei Starovoitov says: ==================== BPF verifier has 700+ tests used to check correctness of the verifier. Beyond checking the verifier log tell kernel to run accepted programs as well via bpf_prog_test_run() command. That improves quality of the tests and increases bpf test coverage. ==================== Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/selftests/bpf/test_verifier.c50
1 files changed, 49 insertions, 1 deletions
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
index 960179882a1c..6c22edb1f006 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -29,6 +29,7 @@
29#include <linux/filter.h> 29#include <linux/filter.h>
30#include <linux/bpf_perf_event.h> 30#include <linux/bpf_perf_event.h>
31#include <linux/bpf.h> 31#include <linux/bpf.h>
32#include <linux/if_ether.h>
32 33
33#include <bpf/bpf.h> 34#include <bpf/bpf.h>
34 35
@@ -49,6 +50,8 @@
49#define MAX_INSNS 512 50#define MAX_INSNS 512
50#define MAX_FIXUPS 8 51#define MAX_FIXUPS 8
51#define MAX_NR_MAPS 4 52#define MAX_NR_MAPS 4
53#define POINTER_VALUE 0xcafe4all
54#define TEST_DATA_LEN 64
52 55
53#define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0) 56#define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0)
54#define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1) 57#define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1)
@@ -62,6 +65,7 @@ struct bpf_test {
62 int fixup_map_in_map[MAX_FIXUPS]; 65 int fixup_map_in_map[MAX_FIXUPS];
63 const char *errstr; 66 const char *errstr;
64 const char *errstr_unpriv; 67 const char *errstr_unpriv;
68 uint32_t retval;
65 enum { 69 enum {
66 UNDEF, 70 UNDEF,
67 ACCEPT, 71 ACCEPT,
@@ -95,6 +99,7 @@ static struct bpf_test tests[] = {
95 BPF_EXIT_INSN(), 99 BPF_EXIT_INSN(),
96 }, 100 },
97 .result = ACCEPT, 101 .result = ACCEPT,
102 .retval = -3,
98 }, 103 },
99 { 104 {
100 "unreachable", 105 "unreachable",
@@ -210,6 +215,7 @@ static struct bpf_test tests[] = {
210 BPF_EXIT_INSN(), 215 BPF_EXIT_INSN(),
211 }, 216 },
212 .result = ACCEPT, 217 .result = ACCEPT,
218 .retval = 1,
213 }, 219 },
214 { 220 {
215 "test8 ld_imm64", 221 "test8 ld_imm64",
@@ -517,6 +523,7 @@ static struct bpf_test tests[] = {
517 .errstr_unpriv = "R0 leaks addr", 523 .errstr_unpriv = "R0 leaks addr",
518 .result = ACCEPT, 524 .result = ACCEPT,
519 .result_unpriv = REJECT, 525 .result_unpriv = REJECT,
526 .retval = POINTER_VALUE,
520 }, 527 },
521 { 528 {
522 "check valid spill/fill, skb mark", 529 "check valid spill/fill, skb mark",
@@ -803,6 +810,7 @@ static struct bpf_test tests[] = {
803 .errstr_unpriv = "R1 pointer comparison", 810 .errstr_unpriv = "R1 pointer comparison",
804 .result_unpriv = REJECT, 811 .result_unpriv = REJECT,
805 .result = ACCEPT, 812 .result = ACCEPT,
813 .retval = -ENOENT,
806 }, 814 },
807 { 815 {
808 "jump test 4", 816 "jump test 4",
@@ -1823,6 +1831,7 @@ static struct bpf_test tests[] = {
1823 BPF_EXIT_INSN(), 1831 BPF_EXIT_INSN(),
1824 }, 1832 },
1825 .result = ACCEPT, 1833 .result = ACCEPT,
1834 .retval = 0xfaceb00c,
1826 }, 1835 },
1827 { 1836 {
1828 "PTR_TO_STACK store/load - bad alignment on off", 1837 "PTR_TO_STACK store/load - bad alignment on off",
@@ -1881,6 +1890,7 @@ static struct bpf_test tests[] = {
1881 .result = ACCEPT, 1890 .result = ACCEPT,
1882 .result_unpriv = REJECT, 1891 .result_unpriv = REJECT,
1883 .errstr_unpriv = "R0 leaks addr", 1892 .errstr_unpriv = "R0 leaks addr",
1893 .retval = POINTER_VALUE,
1884 }, 1894 },
1885 { 1895 {
1886 "unpriv: add const to pointer", 1896 "unpriv: add const to pointer",
@@ -2054,6 +2064,7 @@ static struct bpf_test tests[] = {
2054 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0), 2064 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, 0),
2055 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, 2065 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
2056 BPF_FUNC_get_hash_recalc), 2066 BPF_FUNC_get_hash_recalc),
2067 BPF_MOV64_IMM(BPF_REG_0, 0),
2057 BPF_EXIT_INSN(), 2068 BPF_EXIT_INSN(),
2058 }, 2069 },
2059 .result = ACCEPT, 2070 .result = ACCEPT,
@@ -2818,6 +2829,7 @@ static struct bpf_test tests[] = {
2818 }, 2829 },
2819 .result = ACCEPT, 2830 .result = ACCEPT,
2820 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2831 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2832 .retval = 1,
2821 }, 2833 },
2822 { 2834 {
2823 "direct packet access: test12 (and, good access)", 2835 "direct packet access: test12 (and, good access)",
@@ -2842,6 +2854,7 @@ static struct bpf_test tests[] = {
2842 }, 2854 },
2843 .result = ACCEPT, 2855 .result = ACCEPT,
2844 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2856 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2857 .retval = 1,
2845 }, 2858 },
2846 { 2859 {
2847 "direct packet access: test13 (branches, good access)", 2860 "direct packet access: test13 (branches, good access)",
@@ -2872,6 +2885,7 @@ static struct bpf_test tests[] = {
2872 }, 2885 },
2873 .result = ACCEPT, 2886 .result = ACCEPT,
2874 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2887 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2888 .retval = 1,
2875 }, 2889 },
2876 { 2890 {
2877 "direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)", 2891 "direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)",
@@ -2895,6 +2909,7 @@ static struct bpf_test tests[] = {
2895 }, 2909 },
2896 .result = ACCEPT, 2910 .result = ACCEPT,
2897 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2911 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2912 .retval = 1,
2898 }, 2913 },
2899 { 2914 {
2900 "direct packet access: test15 (spill with xadd)", 2915 "direct packet access: test15 (spill with xadd)",
@@ -3181,6 +3196,7 @@ static struct bpf_test tests[] = {
3181 }, 3196 },
3182 .result = ACCEPT, 3197 .result = ACCEPT,
3183 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 3198 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
3199 .retval = 1,
3184 }, 3200 },
3185 { 3201 {
3186 "direct packet access: test28 (marking on <=, bad access)", 3202 "direct packet access: test28 (marking on <=, bad access)",
@@ -5798,6 +5814,7 @@ static struct bpf_test tests[] = {
5798 }, 5814 },
5799 .result = ACCEPT, 5815 .result = ACCEPT,
5800 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 5816 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
5817 .retval = 0 /* csum_diff of 64-byte packet */,
5801 }, 5818 },
5802 { 5819 {
5803 "helper access to variable memory: size = 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)", 5820 "helper access to variable memory: size = 0 not allowed on NULL (!ARG_PTR_TO_MEM_OR_NULL)",
@@ -6166,6 +6183,7 @@ static struct bpf_test tests[] = {
6166 }, 6183 },
6167 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 6184 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6168 .result = ACCEPT, 6185 .result = ACCEPT,
6186 .retval = 42 /* ultimate return value */,
6169 }, 6187 },
6170 { 6188 {
6171 "ld_ind: check calling conv, r1", 6189 "ld_ind: check calling conv, r1",
@@ -6237,6 +6255,7 @@ static struct bpf_test tests[] = {
6237 BPF_EXIT_INSN(), 6255 BPF_EXIT_INSN(),
6238 }, 6256 },
6239 .result = ACCEPT, 6257 .result = ACCEPT,
6258 .retval = 1,
6240 }, 6259 },
6241 { 6260 {
6242 "check bpf_perf_event_data->sample_period byte load permitted", 6261 "check bpf_perf_event_data->sample_period byte load permitted",
@@ -7224,6 +7243,7 @@ static struct bpf_test tests[] = {
7224 }, 7243 },
7225 .fixup_map1 = { 3 }, 7244 .fixup_map1 = { 3 },
7226 .result = ACCEPT, 7245 .result = ACCEPT,
7246 .retval = POINTER_VALUE,
7227 .result_unpriv = REJECT, 7247 .result_unpriv = REJECT,
7228 .errstr_unpriv = "R0 leaks addr as return value" 7248 .errstr_unpriv = "R0 leaks addr as return value"
7229 }, 7249 },
@@ -7244,6 +7264,7 @@ static struct bpf_test tests[] = {
7244 }, 7264 },
7245 .fixup_map1 = { 3 }, 7265 .fixup_map1 = { 3 },
7246 .result = ACCEPT, 7266 .result = ACCEPT,
7267 .retval = POINTER_VALUE,
7247 .result_unpriv = REJECT, 7268 .result_unpriv = REJECT,
7248 .errstr_unpriv = "R0 leaks addr as return value" 7269 .errstr_unpriv = "R0 leaks addr as return value"
7249 }, 7270 },
@@ -7685,6 +7706,7 @@ static struct bpf_test tests[] = {
7685 BPF_EXIT_INSN(), 7706 BPF_EXIT_INSN(),
7686 }, 7707 },
7687 .result = ACCEPT, 7708 .result = ACCEPT,
7709 .retval = TEST_DATA_LEN,
7688 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 7710 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
7689 }, 7711 },
7690 { 7712 {
@@ -8705,6 +8727,7 @@ static struct bpf_test tests[] = {
8705 .errstr_unpriv = "function calls to other bpf functions are allowed for root only", 8727 .errstr_unpriv = "function calls to other bpf functions are allowed for root only",
8706 .result_unpriv = REJECT, 8728 .result_unpriv = REJECT,
8707 .result = ACCEPT, 8729 .result = ACCEPT,
8730 .retval = 1,
8708 }, 8731 },
8709 { 8732 {
8710 "calls: overlapping caller/callee", 8733 "calls: overlapping caller/callee",
@@ -8900,6 +8923,7 @@ static struct bpf_test tests[] = {
8900 }, 8923 },
8901 .prog_type = BPF_PROG_TYPE_SCHED_ACT, 8924 .prog_type = BPF_PROG_TYPE_SCHED_ACT,
8902 .result = ACCEPT, 8925 .result = ACCEPT,
8926 .retval = TEST_DATA_LEN,
8903 }, 8927 },
8904 { 8928 {
8905 "calls: callee using args1", 8929 "calls: callee using args1",
@@ -8912,6 +8936,7 @@ static struct bpf_test tests[] = {
8912 .errstr_unpriv = "allowed for root only", 8936 .errstr_unpriv = "allowed for root only",
8913 .result_unpriv = REJECT, 8937 .result_unpriv = REJECT,
8914 .result = ACCEPT, 8938 .result = ACCEPT,
8939 .retval = POINTER_VALUE,
8915 }, 8940 },
8916 { 8941 {
8917 "calls: callee using wrong args2", 8942 "calls: callee using wrong args2",
@@ -8942,6 +8967,7 @@ static struct bpf_test tests[] = {
8942 .errstr_unpriv = "allowed for root only", 8967 .errstr_unpriv = "allowed for root only",
8943 .result_unpriv = REJECT, 8968 .result_unpriv = REJECT,
8944 .result = ACCEPT, 8969 .result = ACCEPT,
8970 .retval = TEST_DATA_LEN + TEST_DATA_LEN - ETH_HLEN - ETH_HLEN,
8945 }, 8971 },
8946 { 8972 {
8947 "calls: callee changing pkt pointers", 8973 "calls: callee changing pkt pointers",
@@ -8990,6 +9016,7 @@ static struct bpf_test tests[] = {
8990 }, 9016 },
8991 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 9017 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
8992 .result = ACCEPT, 9018 .result = ACCEPT,
9019 .retval = TEST_DATA_LEN + TEST_DATA_LEN,
8993 }, 9020 },
8994 { 9021 {
8995 "calls: calls with stack arith", 9022 "calls: calls with stack arith",
@@ -9008,6 +9035,7 @@ static struct bpf_test tests[] = {
9008 }, 9035 },
9009 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 9036 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9010 .result = ACCEPT, 9037 .result = ACCEPT,
9038 .retval = 42,
9011 }, 9039 },
9012 { 9040 {
9013 "calls: calls with misaligned stack access", 9041 "calls: calls with misaligned stack access",
@@ -9041,6 +9069,7 @@ static struct bpf_test tests[] = {
9041 }, 9069 },
9042 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 9070 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
9043 .result = ACCEPT, 9071 .result = ACCEPT,
9072 .retval = 43,
9044 }, 9073 },
9045 { 9074 {
9046 "calls: calls control flow, jump test 2", 9075 "calls: calls control flow, jump test 2",
@@ -9533,6 +9562,7 @@ static struct bpf_test tests[] = {
9533 }, 9562 },
9534 .prog_type = BPF_PROG_TYPE_XDP, 9563 .prog_type = BPF_PROG_TYPE_XDP,
9535 .result = ACCEPT, 9564 .result = ACCEPT,
9565 .retval = 42,
9536 }, 9566 },
9537 { 9567 {
9538 "calls: write into callee stack frame", 9568 "calls: write into callee stack frame",
@@ -10144,6 +10174,7 @@ static struct bpf_test tests[] = {
10144 }, 10174 },
10145 .result = ACCEPT, 10175 .result = ACCEPT,
10146 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 10176 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10177 .retval = POINTER_VALUE,
10147 }, 10178 },
10148 { 10179 {
10149 "calls: pkt_ptr spill into caller stack 2", 10180 "calls: pkt_ptr spill into caller stack 2",
@@ -10209,6 +10240,7 @@ static struct bpf_test tests[] = {
10209 }, 10240 },
10210 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 10241 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10211 .result = ACCEPT, 10242 .result = ACCEPT,
10243 .retval = 1,
10212 }, 10244 },
10213 { 10245 {
10214 "calls: pkt_ptr spill into caller stack 4", 10246 "calls: pkt_ptr spill into caller stack 4",
@@ -10242,6 +10274,7 @@ static struct bpf_test tests[] = {
10242 }, 10274 },
10243 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 10275 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
10244 .result = ACCEPT, 10276 .result = ACCEPT,
10277 .retval = 1,
10245 }, 10278 },
10246 { 10279 {
10247 "calls: pkt_ptr spill into caller stack 5", 10280 "calls: pkt_ptr spill into caller stack 5",
@@ -10650,10 +10683,12 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
10650 int fd_prog, expected_ret, reject_from_alignment; 10683 int fd_prog, expected_ret, reject_from_alignment;
10651 struct bpf_insn *prog = test->insns; 10684 struct bpf_insn *prog = test->insns;
10652 int prog_len = probe_filter_length(prog); 10685 int prog_len = probe_filter_length(prog);
10686 char data_in[TEST_DATA_LEN] = {};
10653 int prog_type = test->prog_type; 10687 int prog_type = test->prog_type;
10654 int map_fds[MAX_NR_MAPS]; 10688 int map_fds[MAX_NR_MAPS];
10655 const char *expected_err; 10689 const char *expected_err;
10656 int i; 10690 uint32_t retval;
10691 int i, err;
10657 10692
10658 for (i = 0; i < MAX_NR_MAPS; i++) 10693 for (i = 0; i < MAX_NR_MAPS; i++)
10659 map_fds[i] = -1; 10694 map_fds[i] = -1;
@@ -10696,6 +10731,19 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
10696 } 10731 }
10697 } 10732 }
10698 10733
10734 if (fd_prog >= 0) {
10735 err = bpf_prog_test_run(fd_prog, 1, data_in, sizeof(data_in),
10736 NULL, NULL, &retval, NULL);
10737 if (err && errno != 524/*ENOTSUPP*/ && errno != EPERM) {
10738 printf("Unexpected bpf_prog_test_run error\n");
10739 goto fail_log;
10740 }
10741 if (!err && retval != test->retval &&
10742 test->retval != POINTER_VALUE) {
10743 printf("FAIL retval %d != %d\n", retval, test->retval);
10744 goto fail_log;
10745 }
10746 }
10699 (*passes)++; 10747 (*passes)++;
10700 printf("OK%s\n", reject_from_alignment ? 10748 printf("OK%s\n", reject_from_alignment ?
10701 " (NOTE: reject due to unknown alignment)" : ""); 10749 " (NOTE: reject due to unknown alignment)" : "");