diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-04-10 09:13:06 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-04-10 09:13:06 -0400 |
commit | 523aa3586ffb1fc11a9bf88f77ebaf71a15eb998 (patch) | |
tree | 1fe96f54e8f1e667798a49ae4b3f951feb136ae0 /tools | |
parent | fd0f50db2eb72555ef8f70af14c1e3ee2079b32c (diff) | |
parent | 39da7c509acff13fc8cb12ec1bb20337c988ed36 (diff) |
Merge 4.11-rc6 into driver-core-next
We want the fixes in here as well for testing.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/include/linux/filter.h | 10 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/Makefile | 9 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/test_verifier.c | 290 | ||||
-rw-r--r-- | tools/testing/selftests/powerpc/Makefile | 10 |
4 files changed, 308 insertions, 11 deletions
diff --git a/tools/include/linux/filter.h b/tools/include/linux/filter.h index 122153b16ea4..390d7c9685fd 100644 --- a/tools/include/linux/filter.h +++ b/tools/include/linux/filter.h | |||
@@ -168,6 +168,16 @@ | |||
168 | .off = OFF, \ | 168 | .off = OFF, \ |
169 | .imm = 0 }) | 169 | .imm = 0 }) |
170 | 170 | ||
171 | /* Atomic memory add, *(uint *)(dst_reg + off16) += src_reg */ | ||
172 | |||
173 | #define BPF_STX_XADD(SIZE, DST, SRC, OFF) \ | ||
174 | ((struct bpf_insn) { \ | ||
175 | .code = BPF_STX | BPF_SIZE(SIZE) | BPF_XADD, \ | ||
176 | .dst_reg = DST, \ | ||
177 | .src_reg = SRC, \ | ||
178 | .off = OFF, \ | ||
179 | .imm = 0 }) | ||
180 | |||
171 | /* Memory store, *(uint *) (dst_reg + off16) = imm32 */ | 181 | /* Memory store, *(uint *) (dst_reg + off16) = imm32 */ |
172 | 182 | ||
173 | #define BPF_ST_MEM(SIZE, DST, OFF, IMM) \ | 183 | #define BPF_ST_MEM(SIZE, DST, OFF, IMM) \ |
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 6a1ad58cb66f..9af09e8099c0 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile | |||
@@ -1,7 +1,14 @@ | |||
1 | LIBDIR := ../../../lib | 1 | LIBDIR := ../../../lib |
2 | BPFDIR := $(LIBDIR)/bpf | 2 | BPFDIR := $(LIBDIR)/bpf |
3 | APIDIR := ../../../include/uapi | ||
4 | GENDIR := ../../../../include/generated | ||
5 | GENHDR := $(GENDIR)/autoconf.h | ||
3 | 6 | ||
4 | CFLAGS += -Wall -O2 -I../../../include/uapi -I$(LIBDIR) | 7 | ifneq ($(wildcard $(GENHDR)),) |
8 | GENFLAGS := -DHAVE_GENHDR | ||
9 | endif | ||
10 | |||
11 | CFLAGS += -Wall -O2 -I$(APIDIR) -I$(LIBDIR) -I$(GENDIR) $(GENFLAGS) | ||
5 | LDLIBS += -lcap | 12 | LDLIBS += -lcap |
6 | 13 | ||
7 | TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map | 14 | TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map |
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c index d1555e4240c0..c848e90b6421 100644 --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c | |||
@@ -30,6 +30,14 @@ | |||
30 | 30 | ||
31 | #include <bpf/bpf.h> | 31 | #include <bpf/bpf.h> |
32 | 32 | ||
33 | #ifdef HAVE_GENHDR | ||
34 | # include "autoconf.h" | ||
35 | #else | ||
36 | # if defined(__i386) || defined(__x86_64) || defined(__s390x__) || defined(__aarch64__) | ||
37 | # define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 1 | ||
38 | # endif | ||
39 | #endif | ||
40 | |||
33 | #include "../../../include/linux/filter.h" | 41 | #include "../../../include/linux/filter.h" |
34 | 42 | ||
35 | #ifndef ARRAY_SIZE | 43 | #ifndef ARRAY_SIZE |
@@ -39,6 +47,8 @@ | |||
39 | #define MAX_INSNS 512 | 47 | #define MAX_INSNS 512 |
40 | #define MAX_FIXUPS 8 | 48 | #define MAX_FIXUPS 8 |
41 | 49 | ||
50 | #define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0) | ||
51 | |||
42 | struct bpf_test { | 52 | struct bpf_test { |
43 | const char *descr; | 53 | const char *descr; |
44 | struct bpf_insn insns[MAX_INSNS]; | 54 | struct bpf_insn insns[MAX_INSNS]; |
@@ -53,6 +63,7 @@ struct bpf_test { | |||
53 | REJECT | 63 | REJECT |
54 | } result, result_unpriv; | 64 | } result, result_unpriv; |
55 | enum bpf_prog_type prog_type; | 65 | enum bpf_prog_type prog_type; |
66 | uint8_t flags; | ||
56 | }; | 67 | }; |
57 | 68 | ||
58 | /* Note we want this to be 64 bit aligned so that the end of our array is | 69 | /* Note we want this to be 64 bit aligned so that the end of our array is |
@@ -2432,6 +2443,30 @@ static struct bpf_test tests[] = { | |||
2432 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | 2443 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, |
2433 | }, | 2444 | }, |
2434 | { | 2445 | { |
2446 | "direct packet access: test15 (spill with xadd)", | ||
2447 | .insns = { | ||
2448 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
2449 | offsetof(struct __sk_buff, data)), | ||
2450 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
2451 | offsetof(struct __sk_buff, data_end)), | ||
2452 | BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), | ||
2453 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), | ||
2454 | BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8), | ||
2455 | BPF_MOV64_IMM(BPF_REG_5, 4096), | ||
2456 | BPF_MOV64_REG(BPF_REG_4, BPF_REG_10), | ||
2457 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8), | ||
2458 | BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_2, 0), | ||
2459 | BPF_STX_XADD(BPF_DW, BPF_REG_4, BPF_REG_5, 0), | ||
2460 | BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_4, 0), | ||
2461 | BPF_STX_MEM(BPF_W, BPF_REG_2, BPF_REG_5, 0), | ||
2462 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
2463 | BPF_EXIT_INSN(), | ||
2464 | }, | ||
2465 | .errstr = "R2 invalid mem access 'inv'", | ||
2466 | .result = REJECT, | ||
2467 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
2468 | }, | ||
2469 | { | ||
2435 | "helper access to packet: test1, valid packet_ptr range", | 2470 | "helper access to packet: test1, valid packet_ptr range", |
2436 | .insns = { | 2471 | .insns = { |
2437 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | 2472 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, |
@@ -2934,6 +2969,7 @@ static struct bpf_test tests[] = { | |||
2934 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | 2969 | .errstr_unpriv = "R0 pointer arithmetic prohibited", |
2935 | .result_unpriv = REJECT, | 2970 | .result_unpriv = REJECT, |
2936 | .result = ACCEPT, | 2971 | .result = ACCEPT, |
2972 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
2937 | }, | 2973 | }, |
2938 | { | 2974 | { |
2939 | "valid map access into an array with a variable", | 2975 | "valid map access into an array with a variable", |
@@ -2957,6 +2993,7 @@ static struct bpf_test tests[] = { | |||
2957 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | 2993 | .errstr_unpriv = "R0 pointer arithmetic prohibited", |
2958 | .result_unpriv = REJECT, | 2994 | .result_unpriv = REJECT, |
2959 | .result = ACCEPT, | 2995 | .result = ACCEPT, |
2996 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
2960 | }, | 2997 | }, |
2961 | { | 2998 | { |
2962 | "valid map access into an array with a signed variable", | 2999 | "valid map access into an array with a signed variable", |
@@ -2984,6 +3021,7 @@ static struct bpf_test tests[] = { | |||
2984 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | 3021 | .errstr_unpriv = "R0 pointer arithmetic prohibited", |
2985 | .result_unpriv = REJECT, | 3022 | .result_unpriv = REJECT, |
2986 | .result = ACCEPT, | 3023 | .result = ACCEPT, |
3024 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
2987 | }, | 3025 | }, |
2988 | { | 3026 | { |
2989 | "invalid map access into an array with a constant", | 3027 | "invalid map access into an array with a constant", |
@@ -3025,6 +3063,7 @@ static struct bpf_test tests[] = { | |||
3025 | .errstr = "R0 min value is outside of the array range", | 3063 | .errstr = "R0 min value is outside of the array range", |
3026 | .result_unpriv = REJECT, | 3064 | .result_unpriv = REJECT, |
3027 | .result = REJECT, | 3065 | .result = REJECT, |
3066 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
3028 | }, | 3067 | }, |
3029 | { | 3068 | { |
3030 | "invalid map access into an array with a variable", | 3069 | "invalid map access into an array with a variable", |
@@ -3048,6 +3087,7 @@ static struct bpf_test tests[] = { | |||
3048 | .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.", | 3087 | .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.", |
3049 | .result_unpriv = REJECT, | 3088 | .result_unpriv = REJECT, |
3050 | .result = REJECT, | 3089 | .result = REJECT, |
3090 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
3051 | }, | 3091 | }, |
3052 | { | 3092 | { |
3053 | "invalid map access into an array with no floor check", | 3093 | "invalid map access into an array with no floor check", |
@@ -3074,6 +3114,7 @@ static struct bpf_test tests[] = { | |||
3074 | .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.", | 3114 | .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.", |
3075 | .result_unpriv = REJECT, | 3115 | .result_unpriv = REJECT, |
3076 | .result = REJECT, | 3116 | .result = REJECT, |
3117 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
3077 | }, | 3118 | }, |
3078 | { | 3119 | { |
3079 | "invalid map access into an array with a invalid max check", | 3120 | "invalid map access into an array with a invalid max check", |
@@ -3100,6 +3141,7 @@ static struct bpf_test tests[] = { | |||
3100 | .errstr = "invalid access to map value, value_size=48 off=44 size=8", | 3141 | .errstr = "invalid access to map value, value_size=48 off=44 size=8", |
3101 | .result_unpriv = REJECT, | 3142 | .result_unpriv = REJECT, |
3102 | .result = REJECT, | 3143 | .result = REJECT, |
3144 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
3103 | }, | 3145 | }, |
3104 | { | 3146 | { |
3105 | "invalid map access into an array with a invalid max check", | 3147 | "invalid map access into an array with a invalid max check", |
@@ -3129,6 +3171,7 @@ static struct bpf_test tests[] = { | |||
3129 | .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.", | 3171 | .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.", |
3130 | .result_unpriv = REJECT, | 3172 | .result_unpriv = REJECT, |
3131 | .result = REJECT, | 3173 | .result = REJECT, |
3174 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
3132 | }, | 3175 | }, |
3133 | { | 3176 | { |
3134 | "multiple registers share map_lookup_elem result", | 3177 | "multiple registers share map_lookup_elem result", |
@@ -3252,6 +3295,7 @@ static struct bpf_test tests[] = { | |||
3252 | .result = REJECT, | 3295 | .result = REJECT, |
3253 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | 3296 | .errstr_unpriv = "R0 pointer arithmetic prohibited", |
3254 | .result_unpriv = REJECT, | 3297 | .result_unpriv = REJECT, |
3298 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
3255 | }, | 3299 | }, |
3256 | { | 3300 | { |
3257 | "constant register |= constant should keep constant type", | 3301 | "constant register |= constant should keep constant type", |
@@ -3418,6 +3462,26 @@ static struct bpf_test tests[] = { | |||
3418 | .prog_type = BPF_PROG_TYPE_LWT_XMIT, | 3462 | .prog_type = BPF_PROG_TYPE_LWT_XMIT, |
3419 | }, | 3463 | }, |
3420 | { | 3464 | { |
3465 | "overlapping checks for direct packet access", | ||
3466 | .insns = { | ||
3467 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
3468 | offsetof(struct __sk_buff, data)), | ||
3469 | BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, | ||
3470 | offsetof(struct __sk_buff, data_end)), | ||
3471 | BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), | ||
3472 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), | ||
3473 | BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 4), | ||
3474 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), | ||
3475 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6), | ||
3476 | BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1), | ||
3477 | BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_2, 6), | ||
3478 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
3479 | BPF_EXIT_INSN(), | ||
3480 | }, | ||
3481 | .result = ACCEPT, | ||
3482 | .prog_type = BPF_PROG_TYPE_LWT_XMIT, | ||
3483 | }, | ||
3484 | { | ||
3421 | "invalid access of tc_classid for LWT_IN", | 3485 | "invalid access of tc_classid for LWT_IN", |
3422 | .insns = { | 3486 | .insns = { |
3423 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, | 3487 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, |
@@ -3961,7 +4025,208 @@ static struct bpf_test tests[] = { | |||
3961 | .result_unpriv = REJECT, | 4025 | .result_unpriv = REJECT, |
3962 | }, | 4026 | }, |
3963 | { | 4027 | { |
3964 | "map element value (adjusted) is preserved across register spilling", | 4028 | "map element value or null is marked on register spilling", |
4029 | .insns = { | ||
4030 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
4031 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
4032 | BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0), | ||
4033 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
4034 | BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), | ||
4035 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), | ||
4036 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -152), | ||
4037 | BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0), | ||
4038 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), | ||
4039 | BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0), | ||
4040 | BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42), | ||
4041 | BPF_EXIT_INSN(), | ||
4042 | }, | ||
4043 | .fixup_map2 = { 3 }, | ||
4044 | .errstr_unpriv = "R0 leaks addr", | ||
4045 | .result = ACCEPT, | ||
4046 | .result_unpriv = REJECT, | ||
4047 | }, | ||
4048 | { | ||
4049 | "map element value store of cleared call register", | ||
4050 | .insns = { | ||
4051 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
4052 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
4053 | BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0), | ||
4054 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
4055 | BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), | ||
4056 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), | ||
4057 | BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 0), | ||
4058 | BPF_EXIT_INSN(), | ||
4059 | }, | ||
4060 | .fixup_map2 = { 3 }, | ||
4061 | .errstr_unpriv = "R1 !read_ok", | ||
4062 | .errstr = "R1 !read_ok", | ||
4063 | .result = REJECT, | ||
4064 | .result_unpriv = REJECT, | ||
4065 | }, | ||
4066 | { | ||
4067 | "map element value with unaligned store", | ||
4068 | .insns = { | ||
4069 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
4070 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
4071 | BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0), | ||
4072 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
4073 | BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), | ||
4074 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 17), | ||
4075 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3), | ||
4076 | BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42), | ||
4077 | BPF_ST_MEM(BPF_DW, BPF_REG_0, 2, 43), | ||
4078 | BPF_ST_MEM(BPF_DW, BPF_REG_0, -2, 44), | ||
4079 | BPF_MOV64_REG(BPF_REG_8, BPF_REG_0), | ||
4080 | BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 32), | ||
4081 | BPF_ST_MEM(BPF_DW, BPF_REG_8, 2, 33), | ||
4082 | BPF_ST_MEM(BPF_DW, BPF_REG_8, -2, 34), | ||
4083 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, 5), | ||
4084 | BPF_ST_MEM(BPF_DW, BPF_REG_8, 0, 22), | ||
4085 | BPF_ST_MEM(BPF_DW, BPF_REG_8, 4, 23), | ||
4086 | BPF_ST_MEM(BPF_DW, BPF_REG_8, -7, 24), | ||
4087 | BPF_MOV64_REG(BPF_REG_7, BPF_REG_8), | ||
4088 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 3), | ||
4089 | BPF_ST_MEM(BPF_DW, BPF_REG_7, 0, 22), | ||
4090 | BPF_ST_MEM(BPF_DW, BPF_REG_7, 4, 23), | ||
4091 | BPF_ST_MEM(BPF_DW, BPF_REG_7, -4, 24), | ||
4092 | BPF_EXIT_INSN(), | ||
4093 | }, | ||
4094 | .fixup_map2 = { 3 }, | ||
4095 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
4096 | .result = ACCEPT, | ||
4097 | .result_unpriv = REJECT, | ||
4098 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
4099 | }, | ||
4100 | { | ||
4101 | "map element value with unaligned load", | ||
4102 | .insns = { | ||
4103 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
4104 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
4105 | BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0), | ||
4106 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
4107 | BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), | ||
4108 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11), | ||
4109 | BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), | ||
4110 | BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 9), | ||
4111 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 3), | ||
4112 | BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), | ||
4113 | BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 2), | ||
4114 | BPF_MOV64_REG(BPF_REG_8, BPF_REG_0), | ||
4115 | BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 0), | ||
4116 | BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 2), | ||
4117 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 5), | ||
4118 | BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), | ||
4119 | BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 4), | ||
4120 | BPF_EXIT_INSN(), | ||
4121 | }, | ||
4122 | .fixup_map2 = { 3 }, | ||
4123 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
4124 | .result = ACCEPT, | ||
4125 | .result_unpriv = REJECT, | ||
4126 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
4127 | }, | ||
4128 | { | ||
4129 | "map element value illegal alu op, 1", | ||
4130 | .insns = { | ||
4131 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
4132 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
4133 | BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0), | ||
4134 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
4135 | BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), | ||
4136 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), | ||
4137 | BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 8), | ||
4138 | BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22), | ||
4139 | BPF_EXIT_INSN(), | ||
4140 | }, | ||
4141 | .fixup_map2 = { 3 }, | ||
4142 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
4143 | .errstr = "invalid mem access 'inv'", | ||
4144 | .result = REJECT, | ||
4145 | .result_unpriv = REJECT, | ||
4146 | }, | ||
4147 | { | ||
4148 | "map element value illegal alu op, 2", | ||
4149 | .insns = { | ||
4150 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
4151 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
4152 | BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0), | ||
4153 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
4154 | BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), | ||
4155 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), | ||
4156 | BPF_ALU32_IMM(BPF_ADD, BPF_REG_0, 0), | ||
4157 | BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22), | ||
4158 | BPF_EXIT_INSN(), | ||
4159 | }, | ||
4160 | .fixup_map2 = { 3 }, | ||
4161 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
4162 | .errstr = "invalid mem access 'inv'", | ||
4163 | .result = REJECT, | ||
4164 | .result_unpriv = REJECT, | ||
4165 | }, | ||
4166 | { | ||
4167 | "map element value illegal alu op, 3", | ||
4168 | .insns = { | ||
4169 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
4170 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
4171 | BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0), | ||
4172 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
4173 | BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), | ||
4174 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), | ||
4175 | BPF_ALU64_IMM(BPF_DIV, BPF_REG_0, 42), | ||
4176 | BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22), | ||
4177 | BPF_EXIT_INSN(), | ||
4178 | }, | ||
4179 | .fixup_map2 = { 3 }, | ||
4180 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
4181 | .errstr = "invalid mem access 'inv'", | ||
4182 | .result = REJECT, | ||
4183 | .result_unpriv = REJECT, | ||
4184 | }, | ||
4185 | { | ||
4186 | "map element value illegal alu op, 4", | ||
4187 | .insns = { | ||
4188 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
4189 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
4190 | BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0), | ||
4191 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
4192 | BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), | ||
4193 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), | ||
4194 | BPF_ENDIAN(BPF_FROM_BE, BPF_REG_0, 64), | ||
4195 | BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22), | ||
4196 | BPF_EXIT_INSN(), | ||
4197 | }, | ||
4198 | .fixup_map2 = { 3 }, | ||
4199 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | ||
4200 | .errstr = "invalid mem access 'inv'", | ||
4201 | .result = REJECT, | ||
4202 | .result_unpriv = REJECT, | ||
4203 | }, | ||
4204 | { | ||
4205 | "map element value illegal alu op, 5", | ||
4206 | .insns = { | ||
4207 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
4208 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
4209 | BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0), | ||
4210 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
4211 | BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), | ||
4212 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7), | ||
4213 | BPF_MOV64_IMM(BPF_REG_3, 4096), | ||
4214 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
4215 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
4216 | BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0), | ||
4217 | BPF_STX_XADD(BPF_DW, BPF_REG_2, BPF_REG_3, 0), | ||
4218 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 0), | ||
4219 | BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 22), | ||
4220 | BPF_EXIT_INSN(), | ||
4221 | }, | ||
4222 | .fixup_map2 = { 3 }, | ||
4223 | .errstr_unpriv = "R0 invalid mem access 'inv'", | ||
4224 | .errstr = "R0 invalid mem access 'inv'", | ||
4225 | .result = REJECT, | ||
4226 | .result_unpriv = REJECT, | ||
4227 | }, | ||
4228 | { | ||
4229 | "map element value is preserved across register spilling", | ||
3965 | .insns = { | 4230 | .insns = { |
3966 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | 4231 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
3967 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | 4232 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
@@ -3983,6 +4248,7 @@ static struct bpf_test tests[] = { | |||
3983 | .errstr_unpriv = "R0 pointer arithmetic prohibited", | 4248 | .errstr_unpriv = "R0 pointer arithmetic prohibited", |
3984 | .result = ACCEPT, | 4249 | .result = ACCEPT, |
3985 | .result_unpriv = REJECT, | 4250 | .result_unpriv = REJECT, |
4251 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
3986 | }, | 4252 | }, |
3987 | { | 4253 | { |
3988 | "helper access to variable memory: stack, bitwise AND + JMP, correct bounds", | 4254 | "helper access to variable memory: stack, bitwise AND + JMP, correct bounds", |
@@ -4421,6 +4687,7 @@ static struct bpf_test tests[] = { | |||
4421 | .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.", | 4687 | .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.", |
4422 | .result = REJECT, | 4688 | .result = REJECT, |
4423 | .result_unpriv = REJECT, | 4689 | .result_unpriv = REJECT, |
4690 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
4424 | }, | 4691 | }, |
4425 | { | 4692 | { |
4426 | "invalid range check", | 4693 | "invalid range check", |
@@ -4452,6 +4719,7 @@ static struct bpf_test tests[] = { | |||
4452 | .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.", | 4719 | .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.", |
4453 | .result = REJECT, | 4720 | .result = REJECT, |
4454 | .result_unpriv = REJECT, | 4721 | .result_unpriv = REJECT, |
4722 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | ||
4455 | } | 4723 | } |
4456 | }; | 4724 | }; |
4457 | 4725 | ||
@@ -4530,11 +4798,11 @@ static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog, | |||
4530 | static void do_test_single(struct bpf_test *test, bool unpriv, | 4798 | static void do_test_single(struct bpf_test *test, bool unpriv, |
4531 | int *passes, int *errors) | 4799 | int *passes, int *errors) |
4532 | { | 4800 | { |
4801 | int fd_prog, expected_ret, reject_from_alignment; | ||
4533 | struct bpf_insn *prog = test->insns; | 4802 | struct bpf_insn *prog = test->insns; |
4534 | int prog_len = probe_filter_length(prog); | 4803 | int prog_len = probe_filter_length(prog); |
4535 | int prog_type = test->prog_type; | 4804 | int prog_type = test->prog_type; |
4536 | int fd_f1 = -1, fd_f2 = -1, fd_f3 = -1; | 4805 | int fd_f1 = -1, fd_f2 = -1, fd_f3 = -1; |
4537 | int fd_prog, expected_ret; | ||
4538 | const char *expected_err; | 4806 | const char *expected_err; |
4539 | 4807 | ||
4540 | do_test_fixup(test, prog, &fd_f1, &fd_f2, &fd_f3); | 4808 | do_test_fixup(test, prog, &fd_f1, &fd_f2, &fd_f3); |
@@ -4547,8 +4815,19 @@ static void do_test_single(struct bpf_test *test, bool unpriv, | |||
4547 | test->result_unpriv : test->result; | 4815 | test->result_unpriv : test->result; |
4548 | expected_err = unpriv && test->errstr_unpriv ? | 4816 | expected_err = unpriv && test->errstr_unpriv ? |
4549 | test->errstr_unpriv : test->errstr; | 4817 | test->errstr_unpriv : test->errstr; |
4818 | |||
4819 | reject_from_alignment = fd_prog < 0 && | ||
4820 | (test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS) && | ||
4821 | strstr(bpf_vlog, "Unknown alignment."); | ||
4822 | #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | ||
4823 | if (reject_from_alignment) { | ||
4824 | printf("FAIL\nFailed due to alignment despite having efficient unaligned access: '%s'!\n", | ||
4825 | strerror(errno)); | ||
4826 | goto fail_log; | ||
4827 | } | ||
4828 | #endif | ||
4550 | if (expected_ret == ACCEPT) { | 4829 | if (expected_ret == ACCEPT) { |
4551 | if (fd_prog < 0) { | 4830 | if (fd_prog < 0 && !reject_from_alignment) { |
4552 | printf("FAIL\nFailed to load prog '%s'!\n", | 4831 | printf("FAIL\nFailed to load prog '%s'!\n", |
4553 | strerror(errno)); | 4832 | strerror(errno)); |
4554 | goto fail_log; | 4833 | goto fail_log; |
@@ -4558,14 +4837,15 @@ static void do_test_single(struct bpf_test *test, bool unpriv, | |||
4558 | printf("FAIL\nUnexpected success to load!\n"); | 4837 | printf("FAIL\nUnexpected success to load!\n"); |
4559 | goto fail_log; | 4838 | goto fail_log; |
4560 | } | 4839 | } |
4561 | if (!strstr(bpf_vlog, expected_err)) { | 4840 | if (!strstr(bpf_vlog, expected_err) && !reject_from_alignment) { |
4562 | printf("FAIL\nUnexpected error message!\n"); | 4841 | printf("FAIL\nUnexpected error message!\n"); |
4563 | goto fail_log; | 4842 | goto fail_log; |
4564 | } | 4843 | } |
4565 | } | 4844 | } |
4566 | 4845 | ||
4567 | (*passes)++; | 4846 | (*passes)++; |
4568 | printf("OK\n"); | 4847 | printf("OK%s\n", reject_from_alignment ? |
4848 | " (NOTE: reject due to unknown alignment)" : ""); | ||
4569 | close_fds: | 4849 | close_fds: |
4570 | close(fd_prog); | 4850 | close(fd_prog); |
4571 | close(fd_f1); | 4851 | close(fd_f1); |
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile index 1c5d0575802e..bf13fc2297aa 100644 --- a/tools/testing/selftests/powerpc/Makefile +++ b/tools/testing/selftests/powerpc/Makefile | |||
@@ -34,34 +34,34 @@ endif | |||
34 | all: $(SUB_DIRS) | 34 | all: $(SUB_DIRS) |
35 | 35 | ||
36 | $(SUB_DIRS): | 36 | $(SUB_DIRS): |
37 | BUILD_TARGET=$$OUTPUT/$@; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $@ all | 37 | BUILD_TARGET=$(OUTPUT)/$@; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $@ all |
38 | 38 | ||
39 | include ../lib.mk | 39 | include ../lib.mk |
40 | 40 | ||
41 | override define RUN_TESTS | 41 | override define RUN_TESTS |
42 | @for TARGET in $(SUB_DIRS); do \ | 42 | @for TARGET in $(SUB_DIRS); do \ |
43 | BUILD_TARGET=$$OUTPUT/$$TARGET; \ | 43 | BUILD_TARGET=$(OUTPUT)/$$TARGET; \ |
44 | $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests;\ | 44 | $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests;\ |
45 | done; | 45 | done; |
46 | endef | 46 | endef |
47 | 47 | ||
48 | override define INSTALL_RULE | 48 | override define INSTALL_RULE |
49 | @for TARGET in $(SUB_DIRS); do \ | 49 | @for TARGET in $(SUB_DIRS); do \ |
50 | BUILD_TARGET=$$OUTPUT/$$TARGET; \ | 50 | BUILD_TARGET=$(OUTPUT)/$$TARGET; \ |
51 | $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install;\ | 51 | $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install;\ |
52 | done; | 52 | done; |
53 | endef | 53 | endef |
54 | 54 | ||
55 | override define EMIT_TESTS | 55 | override define EMIT_TESTS |
56 | @for TARGET in $(SUB_DIRS); do \ | 56 | @for TARGET in $(SUB_DIRS); do \ |
57 | BUILD_TARGET=$$OUTPUT/$$TARGET; \ | 57 | BUILD_TARGET=$(OUTPUT)/$$TARGET; \ |
58 | $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests;\ | 58 | $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests;\ |
59 | done; | 59 | done; |
60 | endef | 60 | endef |
61 | 61 | ||
62 | clean: | 62 | clean: |
63 | @for TARGET in $(SUB_DIRS); do \ | 63 | @for TARGET in $(SUB_DIRS); do \ |
64 | BUILD_TARGET=$$OUTPUT/$$TARGET; \ | 64 | BUILD_TARGET=$(OUTPUT)/$$TARGET; \ |
65 | $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean; \ | 65 | $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean; \ |
66 | done; | 66 | done; |
67 | rm -f tags | 67 | rm -f tags |