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
14SEC("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
29SEC("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
43SEC("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; \
55l0_%=: exit; \
56" :
57 : __imm_const(llong_min, LLONG_MIN)
58 : __clobber_all);
59}
60
61SEC("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; \
72l0_%=: exit; \
73" :
74 : __imm_const(llong_min, LLONG_MIN)
75 : __clobber_all);
76}
77
78SEC("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
93SEC("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
107SEC("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; \
120l0_%=: exit; \
121" :
122 : __imm_const(llong_min, LLONG_MIN)
123 : __clobber_all);
124}
125
126SEC("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; \
138l0_%=: exit; \
139" :
140 : __imm_const(llong_min, LLONG_MIN)
141 : __clobber_all);
142}
143
144char _license[] SEC("license") = "GPL";
145

source code of linux/tools/testing/selftests/bpf/progs/verifier_div_overflow.c