1 // SPDX-License-Identifier: GPL-2.0 2 /* Converted from tools/testing/selftests/bpf/verifier/ctx_sk_msg.c */ 3 4 #include <linux/bpf.h> 5 #include <bpf/bpf_helpers.h> 6 #include "bpf_misc.h" 7 8 SEC("sk_msg") 9 __description("valid access family in SK_MSG") 10 __success 11 __naked void access_family_in_sk_msg(void) 12 { 13 asm volatile (" \ 14 r0 = *(u32*)(r1 + %[sk_msg_md_family]); \ 15 exit; \ 16 " : 17 : __imm_const(sk_msg_md_family, offsetof(struct sk_msg_md, family)) 18 : __clobber_all); 19 } 20 21 SEC("sk_msg") 22 __description("valid access remote_ip4 in SK_MSG") 23 __success 24 __naked void remote_ip4_in_sk_msg(void) 25 { 26 asm volatile (" \ 27 r0 = *(u32*)(r1 + %[sk_msg_md_remote_ip4]); \ 28 exit; \ 29 " : 30 : __imm_const(sk_msg_md_remote_ip4, offsetof(struct sk_msg_md, remote_ip4)) 31 : __clobber_all); 32 } 33 34 SEC("sk_msg") 35 __description("valid access local_ip4 in SK_MSG") 36 __success 37 __naked void local_ip4_in_sk_msg(void) 38 { 39 asm volatile (" \ 40 r0 = *(u32*)(r1 + %[sk_msg_md_local_ip4]); \ 41 exit; \ 42 " : 43 : __imm_const(sk_msg_md_local_ip4, offsetof(struct sk_msg_md, local_ip4)) 44 : __clobber_all); 45 } 46 47 SEC("sk_msg") 48 __description("valid access remote_port in SK_MSG") 49 __success 50 __naked void remote_port_in_sk_msg(void) 51 { 52 asm volatile (" \ 53 r0 = *(u32*)(r1 + %[sk_msg_md_remote_port]); \ 54 exit; \ 55 " : 56 : __imm_const(sk_msg_md_remote_port, offsetof(struct sk_msg_md, remote_port)) 57 : __clobber_all); 58 } 59 60 SEC("sk_msg") 61 __description("valid access local_port in SK_MSG") 62 __success 63 __naked void local_port_in_sk_msg(void) 64 { 65 asm volatile (" \ 66 r0 = *(u32*)(r1 + %[sk_msg_md_local_port]); \ 67 exit; \ 68 " : 69 : __imm_const(sk_msg_md_local_port, offsetof(struct sk_msg_md, local_port)) 70 : __clobber_all); 71 } 72 73 SEC("sk_skb") 74 __description("valid access remote_ip6 in SK_MSG") 75 __success 76 __naked void remote_ip6_in_sk_msg(void) 77 { 78 asm volatile (" \ 79 r0 = *(u32*)(r1 + %[sk_msg_md_remote_ip6_0]); \ 80 r0 = *(u32*)(r1 + %[sk_msg_md_remote_ip6_1]); \ 81 r0 = *(u32*)(r1 + %[sk_msg_md_remote_ip6_2]); \ 82 r0 = *(u32*)(r1 + %[sk_msg_md_remote_ip6_3]); \ 83 exit; \ 84 " : 85 : __imm_const(sk_msg_md_remote_ip6_0, offsetof(struct sk_msg_md, remote_ip6[0])), 86 __imm_const(sk_msg_md_remote_ip6_1, offsetof(struct sk_msg_md, remote_ip6[1])), 87 __imm_const(sk_msg_md_remote_ip6_2, offsetof(struct sk_msg_md, remote_ip6[2])), 88 __imm_const(sk_msg_md_remote_ip6_3, offsetof(struct sk_msg_md, remote_ip6[3])) 89 : __clobber_all); 90 } 91 92 SEC("sk_skb") 93 __description("valid access local_ip6 in SK_MSG") 94 __success 95 __naked void local_ip6_in_sk_msg(void) 96 { 97 asm volatile (" \ 98 r0 = *(u32*)(r1 + %[sk_msg_md_local_ip6_0]); \ 99 r0 = *(u32*)(r1 + %[sk_msg_md_local_ip6_1]); \ 100 r0 = *(u32*)(r1 + %[sk_msg_md_local_ip6_2]); \ 101 r0 = *(u32*)(r1 + %[sk_msg_md_local_ip6_3]); \ 102 exit; \ 103 " : 104 : __imm_const(sk_msg_md_local_ip6_0, offsetof(struct sk_msg_md, local_ip6[0])), 105 __imm_const(sk_msg_md_local_ip6_1, offsetof(struct sk_msg_md, local_ip6[1])), 106 __imm_const(sk_msg_md_local_ip6_2, offsetof(struct sk_msg_md, local_ip6[2])), 107 __imm_const(sk_msg_md_local_ip6_3, offsetof(struct sk_msg_md, local_ip6[3])) 108 : __clobber_all); 109 } 110 111 SEC("sk_msg") 112 __description("valid access size in SK_MSG") 113 __success 114 __naked void access_size_in_sk_msg(void) 115 { 116 asm volatile (" \ 117 r0 = *(u32*)(r1 + %[sk_msg_md_size]); \ 118 exit; \ 119 " : 120 : __imm_const(sk_msg_md_size, offsetof(struct sk_msg_md, size)) 121 : __clobber_all); 122 } 123 124 SEC("sk_msg") 125 __description("invalid 64B read of size in SK_MSG") 126 __failure __msg("invalid bpf_context access") 127 __flag(BPF_F_ANY_ALIGNMENT) 128 __naked void of_size_in_sk_msg(void) 129 { 130 asm volatile (" \ 131 r2 = *(u64*)(r1 + %[sk_msg_md_size]); \ 132 exit; \ 133 " : 134 : __imm_const(sk_msg_md_size, offsetof(struct sk_msg_md, size)) 135 : __clobber_all); 136 } 137 138 SEC("sk_msg") 139 __description("invalid read past end of SK_MSG") 140 __failure __msg("invalid bpf_context access") 141 __naked void past_end_of_sk_msg(void) 142 { 143 asm volatile (" \ 144 r2 = *(u32*)(r1 + %[__imm_0]); \ 145 exit; \ 146 " : 147 : __imm_const(__imm_0, offsetof(struct sk_msg_md, size) + 4) 148 : __clobber_all); 149 } 150 151 SEC("sk_msg") 152 __description("invalid read offset in SK_MSG") 153 __failure __msg("invalid bpf_context access") 154 __flag(BPF_F_ANY_ALIGNMENT) 155 __naked void read_offset_in_sk_msg(void) 156 { 157 asm volatile (" \ 158 r2 = *(u32*)(r1 + %[__imm_0]); \ 159 exit; \ 160 " : 161 : __imm_const(__imm_0, offsetof(struct sk_msg_md, family) + 1) 162 : __clobber_all); 163 } 164 165 SEC("sk_msg") 166 __description("direct packet read for SK_MSG") 167 __success 168 __naked void packet_read_for_sk_msg(void) 169 { 170 asm volatile (" \ 171 r2 = *(u64*)(r1 + %[sk_msg_md_data]); \ 172 r3 = *(u64*)(r1 + %[sk_msg_md_data_end]); \ 173 r0 = r2; \ 174 r0 += 8; \ 175 if r0 > r3 goto l0_%=; \ 176 r0 = *(u8*)(r2 + 0); \ 177 l0_%=: r0 = 0; \ 178 exit; \ 179 " : 180 : __imm_const(sk_msg_md_data, offsetof(struct sk_msg_md, data)), 181 __imm_const(sk_msg_md_data_end, offsetof(struct sk_msg_md, data_end)) 182 : __clobber_all); 183 } 184 185 SEC("sk_msg") 186 __description("direct packet write for SK_MSG") 187 __success 188 __naked void packet_write_for_sk_msg(void) 189 { 190 asm volatile (" \ 191 r2 = *(u64*)(r1 + %[sk_msg_md_data]); \ 192 r3 = *(u64*)(r1 + %[sk_msg_md_data_end]); \ 193 r0 = r2; \ 194 r0 += 8; \ 195 if r0 > r3 goto l0_%=; \ 196 *(u8*)(r2 + 0) = r2; \ 197 l0_%=: r0 = 0; \ 198 exit; \ 199 " : 200 : __imm_const(sk_msg_md_data, offsetof(struct sk_msg_md, data)), 201 __imm_const(sk_msg_md_data_end, offsetof(struct sk_msg_md, data_end)) 202 : __clobber_all); 203 } 204 205 SEC("sk_msg") 206 __description("overlapping checks for direct packet access SK_MSG") 207 __success 208 __naked void direct_packet_access_sk_msg(void) 209 { 210 asm volatile (" \ 211 r2 = *(u64*)(r1 + %[sk_msg_md_data]); \ 212 r3 = *(u64*)(r1 + %[sk_msg_md_data_end]); \ 213 r0 = r2; \ 214 r0 += 8; \ 215 if r0 > r3 goto l0_%=; \ 216 r1 = r2; \ 217 r1 += 6; \ 218 if r1 > r3 goto l0_%=; \ 219 r0 = *(u16*)(r2 + 6); \ 220 l0_%=: r0 = 0; \ 221 exit; \ 222 " : 223 : __imm_const(sk_msg_md_data, offsetof(struct sk_msg_md, data)), 224 __imm_const(sk_msg_md_data_end, offsetof(struct sk_msg_md, data_end)) 225 : __clobber_all); 226 } 227 228 char _license[] SEC("license") = "GPL"; 229