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