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