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