1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Converted from tools/testing/selftests/bpf/verifier/div_overflow.c */ |
3 | |
4 | #include <linux/bpf.h> |
5 | #include <bpf/bpf_helpers.h> |
6 | #include <limits.h> |
7 | #include "bpf_misc.h" |
8 | |
9 | /* Just make sure that JITs used udiv/umod as otherwise we get |
10 | * an exception from INT_MIN/-1 overflow similarly as with div |
11 | * by zero. |
12 | */ |
13 | |
14 | SEC("tc" ) |
15 | __description("DIV32 overflow, check 1" ) |
16 | __success __retval(0) |
17 | __naked void div32_overflow_check_1(void) |
18 | { |
19 | asm volatile (" \ |
20 | w1 = -1; \ |
21 | w0 = %[int_min]; \ |
22 | w0 /= w1; \ |
23 | exit; \ |
24 | " : |
25 | : __imm_const(int_min, INT_MIN) |
26 | : __clobber_all); |
27 | } |
28 | |
29 | SEC("tc" ) |
30 | __description("DIV32 overflow, check 2" ) |
31 | __success __retval(0) |
32 | __naked void div32_overflow_check_2(void) |
33 | { |
34 | asm volatile (" \ |
35 | w0 = %[int_min]; \ |
36 | w0 /= -1; \ |
37 | exit; \ |
38 | " : |
39 | : __imm_const(int_min, INT_MIN) |
40 | : __clobber_all); |
41 | } |
42 | |
43 | SEC("tc" ) |
44 | __description("DIV64 overflow, check 1" ) |
45 | __success __retval(0) |
46 | __naked void div64_overflow_check_1(void) |
47 | { |
48 | asm volatile (" \ |
49 | r1 = -1; \ |
50 | r2 = %[llong_min] ll; \ |
51 | r2 /= r1; \ |
52 | w0 = 0; \ |
53 | if r0 == r2 goto l0_%=; \ |
54 | w0 = 1; \ |
55 | l0_%=: exit; \ |
56 | " : |
57 | : __imm_const(llong_min, LLONG_MIN) |
58 | : __clobber_all); |
59 | } |
60 | |
61 | SEC("tc" ) |
62 | __description("DIV64 overflow, check 2" ) |
63 | __success __retval(0) |
64 | __naked void div64_overflow_check_2(void) |
65 | { |
66 | asm volatile (" \ |
67 | r1 = %[llong_min] ll; \ |
68 | r1 /= -1; \ |
69 | w0 = 0; \ |
70 | if r0 == r1 goto l0_%=; \ |
71 | w0 = 1; \ |
72 | l0_%=: exit; \ |
73 | " : |
74 | : __imm_const(llong_min, LLONG_MIN) |
75 | : __clobber_all); |
76 | } |
77 | |
78 | SEC("tc" ) |
79 | __description("MOD32 overflow, check 1" ) |
80 | __success __retval(INT_MIN) |
81 | __naked void mod32_overflow_check_1(void) |
82 | { |
83 | asm volatile (" \ |
84 | w1 = -1; \ |
85 | w0 = %[int_min]; \ |
86 | w0 %%= w1; \ |
87 | exit; \ |
88 | " : |
89 | : __imm_const(int_min, INT_MIN) |
90 | : __clobber_all); |
91 | } |
92 | |
93 | SEC("tc" ) |
94 | __description("MOD32 overflow, check 2" ) |
95 | __success __retval(INT_MIN) |
96 | __naked void mod32_overflow_check_2(void) |
97 | { |
98 | asm volatile (" \ |
99 | w0 = %[int_min]; \ |
100 | w0 %%= -1; \ |
101 | exit; \ |
102 | " : |
103 | : __imm_const(int_min, INT_MIN) |
104 | : __clobber_all); |
105 | } |
106 | |
107 | SEC("tc" ) |
108 | __description("MOD64 overflow, check 1" ) |
109 | __success __retval(1) |
110 | __naked void mod64_overflow_check_1(void) |
111 | { |
112 | asm volatile (" \ |
113 | r1 = -1; \ |
114 | r2 = %[llong_min] ll; \ |
115 | r3 = r2; \ |
116 | r2 %%= r1; \ |
117 | w0 = 0; \ |
118 | if r3 != r2 goto l0_%=; \ |
119 | w0 = 1; \ |
120 | l0_%=: exit; \ |
121 | " : |
122 | : __imm_const(llong_min, LLONG_MIN) |
123 | : __clobber_all); |
124 | } |
125 | |
126 | SEC("tc" ) |
127 | __description("MOD64 overflow, check 2" ) |
128 | __success __retval(1) |
129 | __naked void mod64_overflow_check_2(void) |
130 | { |
131 | asm volatile (" \ |
132 | r2 = %[llong_min] ll; \ |
133 | r3 = r2; \ |
134 | r2 %%= -1; \ |
135 | w0 = 0; \ |
136 | if r3 != r2 goto l0_%=; \ |
137 | w0 = 1; \ |
138 | l0_%=: exit; \ |
139 | " : |
140 | : __imm_const(llong_min, LLONG_MIN) |
141 | : __clobber_all); |
142 | } |
143 | |
144 | char _license[] SEC("license" ) = "GPL" ; |
145 | |