Linux Audio

Check our new training course

Loading...
v6.13.7
   1// SPDX-License-Identifier: GPL-2.0
   2/* Converted from tools/testing/selftests/bpf/verifier/value_ptr_arith.c */
   3
   4#include <linux/bpf.h>
   5#include <bpf/bpf_helpers.h>
   6#include <errno.h>
   7#include "bpf_misc.h"
   8
   9#define MAX_ENTRIES 11
  10
  11struct test_val {
  12	unsigned int index;
  13	int foo[MAX_ENTRIES];
  14};
  15
  16struct {
  17	__uint(type, BPF_MAP_TYPE_ARRAY);
  18	__uint(max_entries, 1);
  19	__type(key, int);
  20	__type(value, struct test_val);
  21} map_array_48b SEC(".maps");
  22
  23struct other_val {
  24	long long foo;
  25	long long bar;
  26};
  27
  28struct {
  29	__uint(type, BPF_MAP_TYPE_HASH);
  30	__uint(max_entries, 1);
  31	__type(key, long long);
  32	__type(value, struct other_val);
  33} map_hash_16b SEC(".maps");
  34
  35struct {
  36	__uint(type, BPF_MAP_TYPE_HASH);
  37	__uint(max_entries, 1);
  38	__type(key, long long);
  39	__type(value, struct test_val);
  40} map_hash_48b SEC(".maps");
  41
  42SEC("socket")
  43__description("map access: known scalar += value_ptr unknown vs const")
  44__success __failure_unpriv
  45__msg_unpriv("R1 tried to add from different maps, paths or scalars")
  46__retval(1)
  47__naked void value_ptr_unknown_vs_const(void)
  48{
  49	asm volatile ("					\
  50	r0 = *(u32*)(r1 + %[__sk_buff_len]);		\
  51	r1 = 0;						\
  52	*(u64*)(r10 - 8) = r1;				\
  53	r2 = r10;					\
  54	r2 += -8;					\
  55	if r0 == 1 goto l0_%=;				\
  56	r1 = %[map_hash_16b] ll;			\
  57	if r0 != 1 goto l1_%=;				\
  58l0_%=:	r1 = %[map_array_48b] ll;			\
  59l1_%=:	call %[bpf_map_lookup_elem];			\
  60	if r0 == 0 goto l2_%=;				\
  61	r4 = *(u8*)(r0 + 0);				\
  62	if r4 == 1 goto l3_%=;				\
  63	r1 = 6;						\
  64	r1 = -r1;					\
  65	r1 &= 0x7;					\
  66	goto l4_%=;					\
  67l3_%=:	r1 = 3;						\
  68l4_%=:	r1 += r0;					\
  69	r0 = *(u8*)(r1 + 0);				\
  70l2_%=:	r0 = 1;						\
  71	exit;						\
  72"	:
  73	: __imm(bpf_map_lookup_elem),
  74	  __imm_addr(map_array_48b),
  75	  __imm_addr(map_hash_16b),
  76	  __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
  77	: __clobber_all);
  78}
  79
  80SEC("socket")
  81__description("map access: known scalar += value_ptr const vs unknown")
  82__success __failure_unpriv
  83__msg_unpriv("R1 tried to add from different maps, paths or scalars")
  84__retval(1)
  85__naked void value_ptr_const_vs_unknown(void)
  86{
  87	asm volatile ("					\
  88	r0 = *(u32*)(r1 + %[__sk_buff_len]);		\
  89	r1 = 0;						\
  90	*(u64*)(r10 - 8) = r1;				\
  91	r2 = r10;					\
  92	r2 += -8;					\
  93	if r0 == 1 goto l0_%=;				\
  94	r1 = %[map_hash_16b] ll;			\
  95	if r0 != 1 goto l1_%=;				\
  96l0_%=:	r1 = %[map_array_48b] ll;			\
  97l1_%=:	call %[bpf_map_lookup_elem];			\
  98	if r0 == 0 goto l2_%=;				\
  99	r4 = *(u8*)(r0 + 0);				\
 100	if r4 == 1 goto l3_%=;				\
 101	r1 = 3;						\
 102	goto l4_%=;					\
 103l3_%=:	r1 = 6;						\
 104	r1 = -r1;					\
 105	r1 &= 0x7;					\
 106l4_%=:	r1 += r0;					\
 107	r0 = *(u8*)(r1 + 0);				\
 108l2_%=:	r0 = 1;						\
 109	exit;						\
 110"	:
 111	: __imm(bpf_map_lookup_elem),
 112	  __imm_addr(map_array_48b),
 113	  __imm_addr(map_hash_16b),
 114	  __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
 115	: __clobber_all);
 116}
 117
 118SEC("socket")
 119__description("map access: known scalar += value_ptr const vs const (ne)")
 120__success __failure_unpriv
 121__msg_unpriv("R1 tried to add from different maps, paths or scalars")
 122__retval(1)
 123__naked void ptr_const_vs_const_ne(void)
 124{
 125	asm volatile ("					\
 126	r0 = *(u32*)(r1 + %[__sk_buff_len]);		\
 127	r1 = 0;						\
 128	*(u64*)(r10 - 8) = r1;				\
 129	r2 = r10;					\
 130	r2 += -8;					\
 131	if r0 == 1 goto l0_%=;				\
 132	r1 = %[map_hash_16b] ll;			\
 133	if r0 != 1 goto l1_%=;				\
 134l0_%=:	r1 = %[map_array_48b] ll;			\
 135l1_%=:	call %[bpf_map_lookup_elem];			\
 136	if r0 == 0 goto l2_%=;				\
 137	r4 = *(u8*)(r0 + 0);				\
 138	if r4 == 1 goto l3_%=;				\
 139	r1 = 3;						\
 140	goto l4_%=;					\
 141l3_%=:	r1 = 5;						\
 142l4_%=:	r1 += r0;					\
 143	r0 = *(u8*)(r1 + 0);				\
 144l2_%=:	r0 = 1;						\
 145	exit;						\
 146"	:
 147	: __imm(bpf_map_lookup_elem),
 148	  __imm_addr(map_array_48b),
 149	  __imm_addr(map_hash_16b),
 150	  __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
 151	: __clobber_all);
 152}
 153
 154SEC("socket")
 155__description("map access: known scalar += value_ptr const vs const (eq)")
 156__success __success_unpriv __retval(1)
 157__naked void ptr_const_vs_const_eq(void)
 158{
 159	asm volatile ("					\
 160	r0 = *(u32*)(r1 + %[__sk_buff_len]);		\
 161	r1 = 0;						\
 162	*(u64*)(r10 - 8) = r1;				\
 163	r2 = r10;					\
 164	r2 += -8;					\
 165	if r0 == 1 goto l0_%=;				\
 166	r1 = %[map_hash_16b] ll;			\
 167	if r0 != 1 goto l1_%=;				\
 168l0_%=:	r1 = %[map_array_48b] ll;			\
 169l1_%=:	call %[bpf_map_lookup_elem];			\
 170	if r0 == 0 goto l2_%=;				\
 171	r4 = *(u8*)(r0 + 0);				\
 172	if r4 == 1 goto l3_%=;				\
 173	r1 = 5;						\
 174	goto l4_%=;					\
 175l3_%=:	r1 = 5;						\
 176l4_%=:	r1 += r0;					\
 177	r0 = *(u8*)(r1 + 0);				\
 178l2_%=:	r0 = 1;						\
 179	exit;						\
 180"	:
 181	: __imm(bpf_map_lookup_elem),
 182	  __imm_addr(map_array_48b),
 183	  __imm_addr(map_hash_16b),
 184	  __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
 185	: __clobber_all);
 186}
 187
 188SEC("socket")
 189__description("map access: known scalar += value_ptr unknown vs unknown (eq)")
 190__success __success_unpriv __retval(1)
 191__naked void ptr_unknown_vs_unknown_eq(void)
 192{
 193	asm volatile ("					\
 194	r0 = *(u32*)(r1 + %[__sk_buff_len]);		\
 195	r1 = 0;						\
 196	*(u64*)(r10 - 8) = r1;				\
 197	r2 = r10;					\
 198	r2 += -8;					\
 199	if r0 == 1 goto l0_%=;				\
 200	r1 = %[map_hash_16b] ll;			\
 201	if r0 != 1 goto l1_%=;				\
 202l0_%=:	r1 = %[map_array_48b] ll;			\
 203l1_%=:	call %[bpf_map_lookup_elem];			\
 204	if r0 == 0 goto l2_%=;				\
 205	r4 = *(u8*)(r0 + 0);				\
 206	if r4 == 1 goto l3_%=;				\
 207	r1 = 6;						\
 208	r1 = -r1;					\
 209	r1 &= 0x7;					\
 210	goto l4_%=;					\
 211l3_%=:	r1 = 6;						\
 212	r1 = -r1;					\
 213	r1 &= 0x7;					\
 214l4_%=:	r1 += r0;					\
 215	r0 = *(u8*)(r1 + 0);				\
 216l2_%=:	r0 = 1;						\
 217	exit;						\
 218"	:
 219	: __imm(bpf_map_lookup_elem),
 220	  __imm_addr(map_array_48b),
 221	  __imm_addr(map_hash_16b),
 222	  __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
 223	: __clobber_all);
 224}
 225
 226SEC("socket")
 227__description("map access: known scalar += value_ptr unknown vs unknown (lt)")
 228__success __failure_unpriv
 229__msg_unpriv("R1 tried to add from different maps, paths or scalars")
 230__retval(1)
 231__naked void ptr_unknown_vs_unknown_lt(void)
 232{
 233	asm volatile ("					\
 234	r0 = *(u32*)(r1 + %[__sk_buff_len]);		\
 235	r1 = 0;						\
 236	*(u64*)(r10 - 8) = r1;				\
 237	r2 = r10;					\
 238	r2 += -8;					\
 239	if r0 == 1 goto l0_%=;				\
 240	r1 = %[map_hash_16b] ll;			\
 241	if r0 != 1 goto l1_%=;				\
 242l0_%=:	r1 = %[map_array_48b] ll;			\
 243l1_%=:	call %[bpf_map_lookup_elem];			\
 244	if r0 == 0 goto l2_%=;				\
 245	r4 = *(u8*)(r0 + 0);				\
 246	if r4 == 1 goto l3_%=;				\
 247	r1 = 6;						\
 248	r1 = -r1;					\
 249	r1 &= 0x3;					\
 250	goto l4_%=;					\
 251l3_%=:	r1 = 6;						\
 252	r1 = -r1;					\
 253	r1 &= 0x7;					\
 254l4_%=:	r1 += r0;					\
 255	r0 = *(u8*)(r1 + 0);				\
 256l2_%=:	r0 = 1;						\
 257	exit;						\
 258"	:
 259	: __imm(bpf_map_lookup_elem),
 260	  __imm_addr(map_array_48b),
 261	  __imm_addr(map_hash_16b),
 262	  __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
 263	: __clobber_all);
 264}
 265
 266SEC("socket")
 267__description("map access: known scalar += value_ptr unknown vs unknown (gt)")
 268__success __failure_unpriv
 269__msg_unpriv("R1 tried to add from different maps, paths or scalars")
 270__retval(1)
 271__naked void ptr_unknown_vs_unknown_gt(void)
 272{
 273	asm volatile ("					\
 274	r0 = *(u32*)(r1 + %[__sk_buff_len]);		\
 275	r1 = 0;						\
 276	*(u64*)(r10 - 8) = r1;				\
 277	r2 = r10;					\
 278	r2 += -8;					\
 279	if r0 == 1 goto l0_%=;				\
 280	r1 = %[map_hash_16b] ll;			\
 281	if r0 != 1 goto l1_%=;				\
 282l0_%=:	r1 = %[map_array_48b] ll;			\
 283l1_%=:	call %[bpf_map_lookup_elem];			\
 284	if r0 == 0 goto l2_%=;				\
 285	r4 = *(u8*)(r0 + 0);				\
 286	if r4 == 1 goto l3_%=;				\
 287	r1 = 6;						\
 288	r1 = -r1;					\
 289	r1 &= 0x7;					\
 290	goto l4_%=;					\
 291l3_%=:	r1 = 6;						\
 292	r1 = -r1;					\
 293	r1 &= 0x3;					\
 294l4_%=:	r1 += r0;					\
 295	r0 = *(u8*)(r1 + 0);				\
 296l2_%=:	r0 = 1;						\
 297	exit;						\
 298"	:
 299	: __imm(bpf_map_lookup_elem),
 300	  __imm_addr(map_array_48b),
 301	  __imm_addr(map_hash_16b),
 302	  __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
 303	: __clobber_all);
 304}
 305
 306SEC("socket")
 307__description("map access: known scalar += value_ptr from different maps")
 308__success __success_unpriv __retval(1)
 309__naked void value_ptr_from_different_maps(void)
 310{
 311	asm volatile ("					\
 312	r0 = *(u32*)(r1 + %[__sk_buff_len]);		\
 313	r1 = 0;						\
 314	*(u64*)(r10 - 8) = r1;				\
 315	r2 = r10;					\
 316	r2 += -8;					\
 317	if r0 == 1 goto l0_%=;				\
 318	r1 = %[map_hash_16b] ll;			\
 319	if r0 != 1 goto l1_%=;				\
 320l0_%=:	r1 = %[map_array_48b] ll;			\
 321l1_%=:	call %[bpf_map_lookup_elem];			\
 322	if r0 == 0 goto l2_%=;				\
 323	r1 = 4;						\
 324	r1 += r0;					\
 325	r0 = *(u8*)(r1 + 0);				\
 326l2_%=:	r0 = 1;						\
 327	exit;						\
 328"	:
 329	: __imm(bpf_map_lookup_elem),
 330	  __imm_addr(map_array_48b),
 331	  __imm_addr(map_hash_16b),
 332	  __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
 333	: __clobber_all);
 334}
 335
 336SEC("socket")
 337__description("map access: value_ptr -= known scalar from different maps")
 338__success __failure_unpriv
 339__msg_unpriv("R0 min value is outside of the allowed memory range")
 340__retval(1)
 341__naked void known_scalar_from_different_maps(void)
 342{
 343	asm volatile ("					\
 344	r0 = *(u32*)(r1 + %[__sk_buff_len]);		\
 345	r1 = 0;						\
 346	*(u64*)(r10 - 8) = r1;				\
 347	r2 = r10;					\
 348	r2 += -8;					\
 349	if r0 == 1 goto l0_%=;				\
 350	r1 = %[map_hash_16b] ll;			\
 351	if r0 != 1 goto l1_%=;				\
 352l0_%=:	r1 = %[map_array_48b] ll;			\
 353l1_%=:	call %[bpf_map_lookup_elem];			\
 354	if r0 == 0 goto l2_%=;				\
 355	r1 = 4;						\
 356	r0 -= r1;					\
 357	r0 += r1;					\
 358	r0 = *(u8*)(r0 + 0);				\
 359l2_%=:	r0 = 1;						\
 360	exit;						\
 361"	:
 362	: __imm(bpf_map_lookup_elem),
 363	  __imm_addr(map_array_48b),
 364	  __imm_addr(map_hash_16b),
 365	  __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
 366	: __clobber_all);
 367}
 368
 369SEC("socket")
 370__description("map access: known scalar += value_ptr from different maps, but same value properties")
 371__success __success_unpriv __retval(1)
 372__naked void maps_but_same_value_properties(void)
 373{
 374	asm volatile ("					\
 375	r0 = *(u32*)(r1 + %[__sk_buff_len]);		\
 376	r1 = 0;						\
 377	*(u64*)(r10 - 8) = r1;				\
 378	r2 = r10;					\
 379	r2 += -8;					\
 380	if r0 == 1 goto l0_%=;				\
 381	r1 = %[map_hash_48b] ll;			\
 382	if r0 != 1 goto l1_%=;				\
 383l0_%=:	r1 = %[map_array_48b] ll;			\
 384l1_%=:	call %[bpf_map_lookup_elem];			\
 385	if r0 == 0 goto l2_%=;				\
 386	r1 = 4;						\
 387	r1 += r0;					\
 388	r0 = *(u8*)(r1 + 0);				\
 389l2_%=:	r0 = 1;						\
 390	exit;						\
 391"	:
 392	: __imm(bpf_map_lookup_elem),
 393	  __imm_addr(map_array_48b),
 394	  __imm_addr(map_hash_48b),
 395	  __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
 396	: __clobber_all);
 397}
 398
 399SEC("socket")
 400__description("map access: mixing value pointer and scalar, 1")
 401__success __failure_unpriv __msg_unpriv("R2 pointer comparison prohibited")
 402__retval(0)
 403__naked void value_pointer_and_scalar_1(void)
 404{
 405	asm volatile ("					\
 406	/* load map value pointer into r0 and r2 */	\
 407	r0 = 1;						\
 408	r1 = %[map_array_48b] ll;			\
 409	r2 = r10;					\
 410	r2 += -16;					\
 411	r6 = 0;						\
 412	*(u64*)(r10 - 16) = r6;				\
 413	call %[bpf_map_lookup_elem];			\
 414	if r0 != 0 goto l0_%=;				\
 415	exit;						\
 416l0_%=:	/* load some number from the map into r1 */	\
 417	r1 = *(u8*)(r0 + 0);				\
 418	/* depending on r1, branch: */			\
 419	if r1 != 0 goto l1_%=;				\
 420	/* branch A */					\
 421	r2 = r0;					\
 422	r3 = 0;						\
 423	goto l2_%=;					\
 424l1_%=:	/* branch B */					\
 425	r2 = 0;						\
 426	r3 = 0x100000;					\
 427l2_%=:	/* common instruction */			\
 428	r2 += r3;					\
 429	/* depending on r1, branch: */			\
 430	if r1 != 0 goto l3_%=;				\
 431	/* branch A */					\
 432	goto l4_%=;					\
 433l3_%=:	/* branch B */					\
 434	r0 = 0x13371337;				\
 435	/* verifier follows fall-through */		\
 436	if r2 != 0x100000 goto l4_%=;			\
 437	r0 = 0;						\
 438	exit;						\
 439l4_%=:	/* fake-dead code; targeted from branch A to	\
 440	 * prevent dead code sanitization		\
 441	 */						\
 442	r0 = *(u8*)(r0 + 0);				\
 443	r0 = 0;						\
 444	exit;						\
 445"	:
 446	: __imm(bpf_map_lookup_elem),
 447	  __imm_addr(map_array_48b)
 448	: __clobber_all);
 449}
 450
 451SEC("socket")
 452__description("map access: mixing value pointer and scalar, 2")
 453__success __failure_unpriv __msg_unpriv("R0 invalid mem access 'scalar'")
 454__retval(0)
 455__naked void value_pointer_and_scalar_2(void)
 456{
 457	asm volatile ("					\
 458	/* load map value pointer into r0 and r2 */	\
 459	r0 = 1;						\
 460	r1 = %[map_array_48b] ll;			\
 461	r2 = r10;					\
 462	r2 += -16;					\
 463	r6 = 0;						\
 464	*(u64*)(r10 - 16) = r6;				\
 465	call %[bpf_map_lookup_elem];			\
 466	if r0 != 0 goto l0_%=;				\
 467	exit;						\
 468l0_%=:	/* load some number from the map into r1 */	\
 469	r1 = *(u8*)(r0 + 0);				\
 470	/* depending on r1, branch: */			\
 471	if r1 == 0 goto l1_%=;				\
 472	/* branch A */					\
 473	r2 = 0;						\
 474	r3 = 0x100000;					\
 475	goto l2_%=;					\
 476l1_%=:	/* branch B */					\
 477	r2 = r0;					\
 478	r3 = 0;						\
 479l2_%=:	/* common instruction */			\
 480	r2 += r3;					\
 481	/* depending on r1, branch: */			\
 482	if r1 != 0 goto l3_%=;				\
 483	/* branch A */					\
 484	goto l4_%=;					\
 485l3_%=:	/* branch B */					\
 486	r0 = 0x13371337;				\
 487	/* verifier follows fall-through */		\
 488	if r2 != 0x100000 goto l4_%=;			\
 489	r0 = 0;						\
 490	exit;						\
 491l4_%=:	/* fake-dead code; targeted from branch A to	\
 492	 * prevent dead code sanitization, rejected	\
 493	 * via branch B however				\
 494	 */						\
 495	r0 = *(u8*)(r0 + 0);				\
 496	r0 = 0;						\
 497	exit;						\
 498"	:
 499	: __imm(bpf_map_lookup_elem),
 500	  __imm_addr(map_array_48b)
 501	: __clobber_all);
 502}
 503
 504SEC("socket")
 505__description("sanitation: alu with different scalars 1")
 506__success __success_unpriv __retval(0x100000)
 507__naked void alu_with_different_scalars_1(void)
 508{
 509	asm volatile ("					\
 510	r0 = 1;						\
 511	r1 = %[map_array_48b] ll;			\
 512	r2 = r10;					\
 513	r2 += -16;					\
 514	r6 = 0;						\
 515	*(u64*)(r10 - 16) = r6;				\
 516	call %[bpf_map_lookup_elem];			\
 517	if r0 != 0 goto l0_%=;				\
 518	exit;						\
 519l0_%=:	r1 = *(u32*)(r0 + 0);				\
 520	if r1 == 0 goto l1_%=;				\
 521	r2 = 0;						\
 522	r3 = 0x100000;					\
 523	goto l2_%=;					\
 524l1_%=:	r2 = 42;					\
 525	r3 = 0x100001;					\
 526l2_%=:	r2 += r3;					\
 527	r0 = r2;					\
 528	exit;						\
 529"	:
 530	: __imm(bpf_map_lookup_elem),
 531	  __imm_addr(map_array_48b)
 532	: __clobber_all);
 533}
 534
 535SEC("socket")
 536__description("sanitation: alu with different scalars 2")
 537__success __success_unpriv __retval(0)
 538__naked void alu_with_different_scalars_2(void)
 539{
 540	asm volatile ("					\
 541	r0 = 1;						\
 542	r1 = %[map_array_48b] ll;			\
 543	r6 = r1;					\
 544	r2 = r10;					\
 545	r2 += -16;					\
 546	r7 = 0;						\
 547	*(u64*)(r10 - 16) = r7;				\
 548	call %[bpf_map_delete_elem];			\
 549	r7 = r0;					\
 550	r1 = r6;					\
 551	r2 = r10;					\
 552	r2 += -16;					\
 553	call %[bpf_map_delete_elem];			\
 554	r6 = r0;					\
 555	r8 = r6;					\
 556	r8 += r7;					\
 557	r0 = r8;					\
 558	r0 += %[einval];				\
 559	r0 += %[einval];				\
 560	exit;						\
 561"	:
 562	: __imm(bpf_map_delete_elem),
 563	  __imm_addr(map_array_48b),
 564	  __imm_const(einval, EINVAL)
 565	: __clobber_all);
 566}
 567
 568SEC("socket")
 569__description("sanitation: alu with different scalars 3")
 570__success __success_unpriv __retval(0)
 571__naked void alu_with_different_scalars_3(void)
 572{
 573	asm volatile ("					\
 574	r0 = %[einval];					\
 575	r0 *= -1;					\
 576	r7 = r0;					\
 577	r0 = %[einval];					\
 578	r0 *= -1;					\
 579	r6 = r0;					\
 580	r8 = r6;					\
 581	r8 += r7;					\
 582	r0 = r8;					\
 583	r0 += %[einval];				\
 584	r0 += %[einval];				\
 585	exit;						\
 586"	:
 587	: __imm_const(einval, EINVAL)
 588	: __clobber_all);
 589}
 590
 591SEC("socket")
 592__description("map access: value_ptr += known scalar, upper oob arith, test 1")
 593__success __failure_unpriv
 594__msg_unpriv("R0 pointer arithmetic of map value goes out of range")
 595__retval(1)
 596__naked void upper_oob_arith_test_1(void)
 597{
 598	asm volatile ("					\
 599	r1 = 0;						\
 600	*(u64*)(r10 - 8) = r1;				\
 601	r2 = r10;					\
 602	r2 += -8;					\
 603	r1 = %[map_array_48b] ll;			\
 604	call %[bpf_map_lookup_elem];			\
 605	if r0 == 0 goto l0_%=;				\
 606	r1 = 48;					\
 607	r0 += r1;					\
 608	r0 -= r1;					\
 609	r0 = *(u8*)(r0 + 0);				\
 610l0_%=:	r0 = 1;						\
 611	exit;						\
 612"	:
 613	: __imm(bpf_map_lookup_elem),
 614	  __imm_addr(map_array_48b)
 615	: __clobber_all);
 616}
 617
 618SEC("socket")
 619__description("map access: value_ptr += known scalar, upper oob arith, test 2")
 620__success __failure_unpriv
 621__msg_unpriv("R0 pointer arithmetic of map value goes out of range")
 622__retval(1)
 623__naked void upper_oob_arith_test_2(void)
 624{
 625	asm volatile ("					\
 626	r1 = 0;						\
 627	*(u64*)(r10 - 8) = r1;				\
 628	r2 = r10;					\
 629	r2 += -8;					\
 630	r1 = %[map_array_48b] ll;			\
 631	call %[bpf_map_lookup_elem];			\
 632	if r0 == 0 goto l0_%=;				\
 633	r1 = 49;					\
 634	r0 += r1;					\
 635	r0 -= r1;					\
 636	r0 = *(u8*)(r0 + 0);				\
 637l0_%=:	r0 = 1;						\
 638	exit;						\
 639"	:
 640	: __imm(bpf_map_lookup_elem),
 641	  __imm_addr(map_array_48b)
 642	: __clobber_all);
 643}
 644
 645SEC("socket")
 646__description("map access: value_ptr += known scalar, upper oob arith, test 3")
 647__success __success_unpriv __retval(1)
 648__naked void upper_oob_arith_test_3(void)
 649{
 650	asm volatile ("					\
 651	r1 = 0;						\
 652	*(u64*)(r10 - 8) = r1;				\
 653	r2 = r10;					\
 654	r2 += -8;					\
 655	r1 = %[map_array_48b] ll;			\
 656	call %[bpf_map_lookup_elem];			\
 657	if r0 == 0 goto l0_%=;				\
 658	r1 = 47;					\
 659	r0 += r1;					\
 660	r0 -= r1;					\
 661	r0 = *(u8*)(r0 + 0);				\
 662l0_%=:	r0 = 1;						\
 663	exit;						\
 664"	:
 665	: __imm(bpf_map_lookup_elem),
 666	  __imm_addr(map_array_48b)
 667	: __clobber_all);
 668}
 669
 670SEC("socket")
 671__description("map access: value_ptr -= known scalar, lower oob arith, test 1")
 672__failure __msg("R0 min value is outside of the allowed memory range")
 673__failure_unpriv
 674__msg_unpriv("R0 pointer arithmetic of map value goes out of range")
 675__naked void lower_oob_arith_test_1(void)
 676{
 677	asm volatile ("					\
 678	r1 = 0;						\
 679	*(u64*)(r10 - 8) = r1;				\
 680	r2 = r10;					\
 681	r2 += -8;					\
 682	r1 = %[map_array_48b] ll;			\
 683	call %[bpf_map_lookup_elem];			\
 684	if r0 == 0 goto l0_%=;				\
 685	r1 = 47;					\
 686	r0 += r1;					\
 687	r1 = 48;					\
 688	r0 -= r1;					\
 689	r0 = *(u8*)(r0 + 0);				\
 690l0_%=:	r0 = 1;						\
 691	exit;						\
 692"	:
 693	: __imm(bpf_map_lookup_elem),
 694	  __imm_addr(map_array_48b)
 695	: __clobber_all);
 696}
 697
 698SEC("socket")
 699__description("map access: value_ptr -= known scalar, lower oob arith, test 2")
 700__success __failure_unpriv
 701__msg_unpriv("R0 pointer arithmetic of map value goes out of range")
 702__retval(1)
 703__naked void lower_oob_arith_test_2(void)
 704{
 705	asm volatile ("					\
 706	r1 = 0;						\
 707	*(u64*)(r10 - 8) = r1;				\
 708	r2 = r10;					\
 709	r2 += -8;					\
 710	r1 = %[map_array_48b] ll;			\
 711	call %[bpf_map_lookup_elem];			\
 712	if r0 == 0 goto l0_%=;				\
 713	r1 = 47;					\
 714	r0 += r1;					\
 715	r1 = 48;					\
 716	r0 -= r1;					\
 717	r1 = 1;						\
 718	r0 += r1;					\
 719	r0 = *(u8*)(r0 + 0);				\
 720l0_%=:	r0 = 1;						\
 721	exit;						\
 722"	:
 723	: __imm(bpf_map_lookup_elem),
 724	  __imm_addr(map_array_48b)
 725	: __clobber_all);
 726}
 727
 728SEC("socket")
 729__description("map access: value_ptr -= known scalar, lower oob arith, test 3")
 730__success __success_unpriv __retval(1)
 731__naked void lower_oob_arith_test_3(void)
 732{
 733	asm volatile ("					\
 734	r1 = 0;						\
 735	*(u64*)(r10 - 8) = r1;				\
 736	r2 = r10;					\
 737	r2 += -8;					\
 738	r1 = %[map_array_48b] ll;			\
 739	call %[bpf_map_lookup_elem];			\
 740	if r0 == 0 goto l0_%=;				\
 741	r1 = 47;					\
 742	r0 += r1;					\
 743	r1 = 47;					\
 744	r0 -= r1;					\
 745	r0 = *(u8*)(r0 + 0);				\
 746l0_%=:	r0 = 1;						\
 747	exit;						\
 748"	:
 749	: __imm(bpf_map_lookup_elem),
 750	  __imm_addr(map_array_48b)
 751	: __clobber_all);
 752}
 753
 754SEC("socket")
 755__description("map access: known scalar += value_ptr")
 756__success __success_unpriv __retval(1)
 757__naked void access_known_scalar_value_ptr_1(void)
 758{
 759	asm volatile ("					\
 760	r1 = 0;						\
 761	*(u64*)(r10 - 8) = r1;				\
 762	r2 = r10;					\
 763	r2 += -8;					\
 764	r1 = %[map_array_48b] ll;			\
 765	call %[bpf_map_lookup_elem];			\
 766	if r0 == 0 goto l0_%=;				\
 767	r1 = 4;						\
 768	r1 += r0;					\
 769	r0 = *(u8*)(r1 + 0);				\
 770l0_%=:	r0 = 1;						\
 771	exit;						\
 772"	:
 773	: __imm(bpf_map_lookup_elem),
 774	  __imm_addr(map_array_48b)
 775	: __clobber_all);
 776}
 777
 778SEC("socket")
 779__description("map access: value_ptr += known scalar, 1")
 780__success __success_unpriv __retval(1)
 781__naked void value_ptr_known_scalar_1(void)
 782{
 783	asm volatile ("					\
 784	r1 = 0;						\
 785	*(u64*)(r10 - 8) = r1;				\
 786	r2 = r10;					\
 787	r2 += -8;					\
 788	r1 = %[map_array_48b] ll;			\
 789	call %[bpf_map_lookup_elem];			\
 790	if r0 == 0 goto l0_%=;				\
 791	r1 = 4;						\
 792	r0 += r1;					\
 793	r1 = *(u8*)(r0 + 0);				\
 794l0_%=:	r0 = 1;						\
 795	exit;						\
 796"	:
 797	: __imm(bpf_map_lookup_elem),
 798	  __imm_addr(map_array_48b)
 799	: __clobber_all);
 800}
 801
 802SEC("socket")
 803__description("map access: value_ptr += known scalar, 2")
 804__failure __msg("invalid access to map value")
 805__failure_unpriv
 806__naked void value_ptr_known_scalar_2_1(void)
 807{
 808	asm volatile ("					\
 809	r1 = 0;						\
 810	*(u64*)(r10 - 8) = r1;				\
 811	r2 = r10;					\
 812	r2 += -8;					\
 813	r1 = %[map_array_48b] ll;			\
 814	call %[bpf_map_lookup_elem];			\
 815	if r0 == 0 goto l0_%=;				\
 816	r1 = 49;					\
 817	r0 += r1;					\
 818	r1 = *(u8*)(r0 + 0);				\
 819l0_%=:	r0 = 1;						\
 820	exit;						\
 821"	:
 822	: __imm(bpf_map_lookup_elem),
 823	  __imm_addr(map_array_48b)
 824	: __clobber_all);
 825}
 826
 827SEC("socket")
 828__description("map access: value_ptr += known scalar, 3")
 829__failure __msg("invalid access to map value")
 830__failure_unpriv
 831__naked void value_ptr_known_scalar_3(void)
 832{
 833	asm volatile ("					\
 834	r1 = 0;						\
 835	*(u64*)(r10 - 8) = r1;				\
 836	r2 = r10;					\
 837	r2 += -8;					\
 838	r1 = %[map_array_48b] ll;			\
 839	call %[bpf_map_lookup_elem];			\
 840	if r0 == 0 goto l0_%=;				\
 841	r1 = -1;					\
 842	r0 += r1;					\
 843	r1 = *(u8*)(r0 + 0);				\
 844l0_%=:	r0 = 1;						\
 845	exit;						\
 846"	:
 847	: __imm(bpf_map_lookup_elem),
 848	  __imm_addr(map_array_48b)
 849	: __clobber_all);
 850}
 851
 852SEC("socket")
 853__description("map access: value_ptr += known scalar, 4")
 854__success __success_unpriv __retval(1)
 855__naked void value_ptr_known_scalar_4(void)
 856{
 857	asm volatile ("					\
 858	r1 = 0;						\
 859	*(u64*)(r10 - 8) = r1;				\
 860	r2 = r10;					\
 861	r2 += -8;					\
 862	r1 = %[map_array_48b] ll;			\
 863	call %[bpf_map_lookup_elem];			\
 864	if r0 == 0 goto l0_%=;				\
 865	r1 = 5;						\
 866	r0 += r1;					\
 867	r1 = -2;					\
 868	r0 += r1;					\
 869	r1 = -1;					\
 870	r0 += r1;					\
 871	r1 = *(u8*)(r0 + 0);				\
 872l0_%=:	r0 = 1;						\
 873	exit;						\
 874"	:
 875	: __imm(bpf_map_lookup_elem),
 876	  __imm_addr(map_array_48b)
 877	: __clobber_all);
 878}
 879
 880SEC("socket")
 881__description("map access: value_ptr += known scalar, 5")
 882__success __success_unpriv __retval(0xabcdef12)
 883__naked void value_ptr_known_scalar_5(void)
 884{
 885	asm volatile ("					\
 886	r1 = 0;						\
 887	*(u64*)(r10 - 8) = r1;				\
 888	r2 = r10;					\
 889	r2 += -8;					\
 890	r1 = %[map_array_48b] ll;			\
 891	call %[bpf_map_lookup_elem];			\
 892	if r0 == 0 goto l0_%=;				\
 893	r1 = %[__imm_0];				\
 894	r1 += r0;					\
 895	r0 = *(u32*)(r1 + 0);				\
 896l0_%=:	exit;						\
 897"	:
 898	: __imm(bpf_map_lookup_elem),
 899	  __imm_addr(map_array_48b),
 900	  __imm_const(__imm_0, (6 + 1) * sizeof(int))
 901	: __clobber_all);
 902}
 903
 904SEC("socket")
 905__description("map access: value_ptr += known scalar, 6")
 906__success __success_unpriv __retval(0xabcdef12)
 907__naked void value_ptr_known_scalar_6(void)
 908{
 909	asm volatile ("					\
 910	r1 = 0;						\
 911	*(u64*)(r10 - 8) = r1;				\
 912	r2 = r10;					\
 913	r2 += -8;					\
 914	r1 = %[map_array_48b] ll;			\
 915	call %[bpf_map_lookup_elem];			\
 916	if r0 == 0 goto l0_%=;				\
 917	r1 = %[__imm_0];				\
 918	r0 += r1;					\
 919	r1 = %[__imm_1];				\
 920	r0 += r1;					\
 921	r0 = *(u32*)(r0 + 0);				\
 922l0_%=:	exit;						\
 923"	:
 924	: __imm(bpf_map_lookup_elem),
 925	  __imm_addr(map_array_48b),
 926	  __imm_const(__imm_0, (3 + 1) * sizeof(int)),
 927	  __imm_const(__imm_1, 3 * sizeof(int))
 928	: __clobber_all);
 929}
 930
 931SEC("socket")
 932__description("map access: value_ptr += N, value_ptr -= N known scalar")
 933__success __success_unpriv __retval(0x12345678)
 934__naked void value_ptr_n_known_scalar(void)
 935{
 936	asm volatile ("					\
 937	r1 = 0;						\
 938	*(u64*)(r10 - 8) = r1;				\
 939	r2 = r10;					\
 940	r2 += -8;					\
 941	r1 = %[map_array_48b] ll;			\
 942	call %[bpf_map_lookup_elem];			\
 943	if r0 == 0 goto l0_%=;				\
 944	w1 = 0x12345678;				\
 945	*(u32*)(r0 + 0) = r1;				\
 946	r0 += 2;					\
 947	r1 = 2;						\
 948	r0 -= r1;					\
 949	r0 = *(u32*)(r0 + 0);				\
 950l0_%=:	exit;						\
 951"	:
 952	: __imm(bpf_map_lookup_elem),
 953	  __imm_addr(map_array_48b)
 954	: __clobber_all);
 955}
 956
 957SEC("socket")
 958__description("map access: unknown scalar += value_ptr, 1")
 959__success __success_unpriv __retval(1)
 960__naked void unknown_scalar_value_ptr_1(void)
 961{
 962	asm volatile ("					\
 963	r1 = 0;						\
 964	*(u64*)(r10 - 8) = r1;				\
 965	r2 = r10;					\
 966	r2 += -8;					\
 967	r1 = %[map_array_48b] ll;			\
 968	call %[bpf_map_lookup_elem];			\
 969	if r0 == 0 goto l0_%=;				\
 970	r1 = *(u8*)(r0 + 0);				\
 971	r1 &= 0xf;					\
 972	r1 += r0;					\
 973	r0 = *(u8*)(r1 + 0);				\
 974l0_%=:	r0 = 1;						\
 975	exit;						\
 976"	:
 977	: __imm(bpf_map_lookup_elem),
 978	  __imm_addr(map_array_48b)
 979	: __clobber_all);
 980}
 981
 982SEC("socket")
 983__description("map access: unknown scalar += value_ptr, 2")
 984__success __success_unpriv __retval(0xabcdef12) __flag(BPF_F_ANY_ALIGNMENT)
 985__naked void unknown_scalar_value_ptr_2(void)
 986{
 987	asm volatile ("					\
 988	r1 = 0;						\
 989	*(u64*)(r10 - 8) = r1;				\
 990	r2 = r10;					\
 991	r2 += -8;					\
 992	r1 = %[map_array_48b] ll;			\
 993	call %[bpf_map_lookup_elem];			\
 994	if r0 == 0 goto l0_%=;				\
 995	r1 = *(u32*)(r0 + 0);				\
 996	r1 &= 31;					\
 997	r1 += r0;					\
 998	r0 = *(u32*)(r1 + 0);				\
 999l0_%=:	exit;						\
1000"	:
1001	: __imm(bpf_map_lookup_elem),
1002	  __imm_addr(map_array_48b)
1003	: __clobber_all);
1004}
1005
1006SEC("socket")
1007__description("map access: unknown scalar += value_ptr, 3")
1008__success __failure_unpriv
1009__msg_unpriv("R0 pointer arithmetic of map value goes out of range")
1010__retval(0xabcdef12) __flag(BPF_F_ANY_ALIGNMENT)
1011__naked void unknown_scalar_value_ptr_3(void)
1012{
1013	asm volatile ("					\
1014	r1 = 0;						\
1015	*(u64*)(r10 - 8) = r1;				\
1016	r2 = r10;					\
1017	r2 += -8;					\
1018	r1 = %[map_array_48b] ll;			\
1019	call %[bpf_map_lookup_elem];			\
1020	if r0 == 0 goto l0_%=;				\
1021	r1 = -1;					\
1022	r0 += r1;					\
1023	r1 = 1;						\
1024	r0 += r1;					\
1025	r1 = *(u32*)(r0 + 0);				\
1026	r1 &= 31;					\
1027	r1 += r0;					\
1028	r0 = *(u32*)(r1 + 0);				\
1029l0_%=:	exit;						\
1030"	:
1031	: __imm(bpf_map_lookup_elem),
1032	  __imm_addr(map_array_48b)
1033	: __clobber_all);
1034}
1035
1036SEC("socket")
1037__description("map access: unknown scalar += value_ptr, 4")
1038__failure __msg("R1 max value is outside of the allowed memory range")
1039__msg_unpriv("R1 pointer arithmetic of map value goes out of range")
1040__flag(BPF_F_ANY_ALIGNMENT)
1041__naked void unknown_scalar_value_ptr_4(void)
1042{
1043	asm volatile ("					\
1044	r1 = 0;						\
1045	*(u64*)(r10 - 8) = r1;				\
1046	r2 = r10;					\
1047	r2 += -8;					\
1048	r1 = %[map_array_48b] ll;			\
1049	call %[bpf_map_lookup_elem];			\
1050	if r0 == 0 goto l0_%=;				\
1051	r1 = 19;					\
1052	r0 += r1;					\
1053	r1 = *(u32*)(r0 + 0);				\
1054	r1 &= 31;					\
1055	r1 += r0;					\
1056	r0 = *(u32*)(r1 + 0);				\
1057l0_%=:	exit;						\
1058"	:
1059	: __imm(bpf_map_lookup_elem),
1060	  __imm_addr(map_array_48b)
1061	: __clobber_all);
1062}
1063
1064SEC("socket")
1065__description("map access: value_ptr += unknown scalar, 1")
1066__success __success_unpriv __retval(1)
1067__naked void value_ptr_unknown_scalar_1(void)
1068{
1069	asm volatile ("					\
1070	r1 = 0;						\
1071	*(u64*)(r10 - 8) = r1;				\
1072	r2 = r10;					\
1073	r2 += -8;					\
1074	r1 = %[map_array_48b] ll;			\
1075	call %[bpf_map_lookup_elem];			\
1076	if r0 == 0 goto l0_%=;				\
1077	r1 = *(u8*)(r0 + 0);				\
1078	r1 &= 0xf;					\
1079	r0 += r1;					\
1080	r1 = *(u8*)(r0 + 0);				\
1081l0_%=:	r0 = 1;						\
1082	exit;						\
1083"	:
1084	: __imm(bpf_map_lookup_elem),
1085	  __imm_addr(map_array_48b)
1086	: __clobber_all);
1087}
1088
1089SEC("socket")
1090__description("map access: value_ptr += unknown scalar, 2")
1091__success __success_unpriv __retval(0xabcdef12) __flag(BPF_F_ANY_ALIGNMENT)
1092__naked void value_ptr_unknown_scalar_2_1(void)
1093{
1094	asm volatile ("					\
1095	r1 = 0;						\
1096	*(u64*)(r10 - 8) = r1;				\
1097	r2 = r10;					\
1098	r2 += -8;					\
1099	r1 = %[map_array_48b] ll;			\
1100	call %[bpf_map_lookup_elem];			\
1101	if r0 == 0 goto l0_%=;				\
1102	r1 = *(u32*)(r0 + 0);				\
1103	r1 &= 31;					\
1104	r0 += r1;					\
1105	r0 = *(u32*)(r0 + 0);				\
1106l0_%=:	exit;						\
1107"	:
1108	: __imm(bpf_map_lookup_elem),
1109	  __imm_addr(map_array_48b)
1110	: __clobber_all);
1111}
1112
1113SEC("socket")
1114__description("map access: value_ptr += unknown scalar, 3")
1115__success __success_unpriv __retval(1)
1116__naked void value_ptr_unknown_scalar_3(void)
1117{
1118	asm volatile ("					\
1119	r1 = 0;						\
1120	*(u64*)(r10 - 8) = r1;				\
1121	r2 = r10;					\
1122	r2 += -8;					\
1123	r1 = %[map_array_48b] ll;			\
1124	call %[bpf_map_lookup_elem];			\
1125	if r0 == 0 goto l0_%=;				\
1126	r1 = *(u64*)(r0 + 0);				\
1127	r2 = *(u64*)(r0 + 8);				\
1128	r3 = *(u64*)(r0 + 16);				\
1129	r1 &= 0xf;					\
1130	r3 &= 1;					\
1131	r3 |= 1;					\
1132	if r2 > r3 goto l0_%=;				\
1133	r0 += r3;					\
1134	r0 = *(u8*)(r0 + 0);				\
1135	r0 = 1;						\
1136l1_%=:	exit;						\
1137l0_%=:	r0 = 2;						\
1138	goto l1_%=;					\
1139"	:
1140	: __imm(bpf_map_lookup_elem),
1141	  __imm_addr(map_array_48b)
1142	: __clobber_all);
1143}
1144
1145SEC("socket")
1146__description("map access: value_ptr += value_ptr")
1147__failure __msg("R0 pointer += pointer prohibited")
1148__failure_unpriv
1149__naked void access_value_ptr_value_ptr_1(void)
1150{
1151	asm volatile ("					\
1152	r1 = 0;						\
1153	*(u64*)(r10 - 8) = r1;				\
1154	r2 = r10;					\
1155	r2 += -8;					\
1156	r1 = %[map_array_48b] ll;			\
1157	call %[bpf_map_lookup_elem];			\
1158	if r0 == 0 goto l0_%=;				\
1159	r0 += r0;					\
1160	r1 = *(u8*)(r0 + 0);				\
1161l0_%=:	r0 = 1;						\
1162	exit;						\
1163"	:
1164	: __imm(bpf_map_lookup_elem),
1165	  __imm_addr(map_array_48b)
1166	: __clobber_all);
1167}
1168
1169SEC("socket")
1170__description("map access: known scalar -= value_ptr")
1171__failure __msg("R1 tried to subtract pointer from scalar")
1172__failure_unpriv
1173__naked void access_known_scalar_value_ptr_2(void)
1174{
1175	asm volatile ("					\
1176	r1 = 0;						\
1177	*(u64*)(r10 - 8) = r1;				\
1178	r2 = r10;					\
1179	r2 += -8;					\
1180	r1 = %[map_array_48b] ll;			\
1181	call %[bpf_map_lookup_elem];			\
1182	if r0 == 0 goto l0_%=;				\
1183	r1 = 4;						\
1184	r1 -= r0;					\
1185	r0 = *(u8*)(r1 + 0);				\
1186l0_%=:	r0 = 1;						\
1187	exit;						\
1188"	:
1189	: __imm(bpf_map_lookup_elem),
1190	  __imm_addr(map_array_48b)
1191	: __clobber_all);
1192}
1193
1194SEC("socket")
1195__description("map access: value_ptr -= known scalar")
1196__failure __msg("R0 min value is outside of the allowed memory range")
1197__failure_unpriv
1198__naked void access_value_ptr_known_scalar(void)
1199{
1200	asm volatile ("					\
1201	r1 = 0;						\
1202	*(u64*)(r10 - 8) = r1;				\
1203	r2 = r10;					\
1204	r2 += -8;					\
1205	r1 = %[map_array_48b] ll;			\
1206	call %[bpf_map_lookup_elem];			\
1207	if r0 == 0 goto l0_%=;				\
1208	r1 = 4;						\
1209	r0 -= r1;					\
1210	r1 = *(u8*)(r0 + 0);				\
1211l0_%=:	r0 = 1;						\
1212	exit;						\
1213"	:
1214	: __imm(bpf_map_lookup_elem),
1215	  __imm_addr(map_array_48b)
1216	: __clobber_all);
1217}
1218
1219SEC("socket")
1220__description("map access: value_ptr -= known scalar, 2")
1221__success __success_unpriv __retval(1)
1222__naked void value_ptr_known_scalar_2_2(void)
1223{
1224	asm volatile ("					\
1225	r1 = 0;						\
1226	*(u64*)(r10 - 8) = r1;				\
1227	r2 = r10;					\
1228	r2 += -8;					\
1229	r1 = %[map_array_48b] ll;			\
1230	call %[bpf_map_lookup_elem];			\
1231	if r0 == 0 goto l0_%=;				\
1232	r1 = 6;						\
1233	r2 = 4;						\
1234	r0 += r1;					\
1235	r0 -= r2;					\
1236	r1 = *(u8*)(r0 + 0);				\
1237l0_%=:	r0 = 1;						\
1238	exit;						\
1239"	:
1240	: __imm(bpf_map_lookup_elem),
1241	  __imm_addr(map_array_48b)
1242	: __clobber_all);
1243}
1244
1245SEC("socket")
1246__description("map access: unknown scalar -= value_ptr")
1247__failure __msg("R1 tried to subtract pointer from scalar")
1248__failure_unpriv
1249__naked void access_unknown_scalar_value_ptr(void)
1250{
1251	asm volatile ("					\
1252	r1 = 0;						\
1253	*(u64*)(r10 - 8) = r1;				\
1254	r2 = r10;					\
1255	r2 += -8;					\
1256	r1 = %[map_array_48b] ll;			\
1257	call %[bpf_map_lookup_elem];			\
1258	if r0 == 0 goto l0_%=;				\
1259	r1 = *(u8*)(r0 + 0);				\
1260	r1 &= 0xf;					\
1261	r1 -= r0;					\
1262	r0 = *(u8*)(r1 + 0);				\
1263l0_%=:	r0 = 1;						\
1264	exit;						\
1265"	:
1266	: __imm(bpf_map_lookup_elem),
1267	  __imm_addr(map_array_48b)
1268	: __clobber_all);
1269}
1270
1271SEC("socket")
1272__description("map access: value_ptr -= unknown scalar")
1273__failure __msg("R0 min value is negative")
1274__failure_unpriv
1275__naked void access_value_ptr_unknown_scalar(void)
1276{
1277	asm volatile ("					\
1278	r1 = 0;						\
1279	*(u64*)(r10 - 8) = r1;				\
1280	r2 = r10;					\
1281	r2 += -8;					\
1282	r1 = %[map_array_48b] ll;			\
1283	call %[bpf_map_lookup_elem];			\
1284	if r0 == 0 goto l0_%=;				\
1285	r1 = *(u8*)(r0 + 0);				\
1286	r1 &= 0xf;					\
1287	r0 -= r1;					\
1288	r1 = *(u8*)(r0 + 0);				\
1289l0_%=:	r0 = 1;						\
1290	exit;						\
1291"	:
1292	: __imm(bpf_map_lookup_elem),
1293	  __imm_addr(map_array_48b)
1294	: __clobber_all);
1295}
1296
1297SEC("socket")
1298__description("map access: value_ptr -= unknown scalar, 2")
1299__success __failure_unpriv
1300__msg_unpriv("R0 pointer arithmetic of map value goes out of range")
1301__retval(1)
1302__naked void value_ptr_unknown_scalar_2_2(void)
1303{
1304	asm volatile ("					\
1305	r1 = 0;						\
1306	*(u64*)(r10 - 8) = r1;				\
1307	r2 = r10;					\
1308	r2 += -8;					\
1309	r1 = %[map_array_48b] ll;			\
1310	call %[bpf_map_lookup_elem];			\
1311	if r0 == 0 goto l0_%=;				\
1312	r1 = *(u8*)(r0 + 0);				\
1313	r1 &= 0xf;					\
1314	r1 |= 0x7;					\
1315	r0 += r1;					\
1316	r1 = *(u8*)(r0 + 0);				\
1317	r1 &= 0x7;					\
1318	r0 -= r1;					\
1319	r1 = *(u8*)(r0 + 0);				\
1320l0_%=:	r0 = 1;						\
1321	exit;						\
1322"	:
1323	: __imm(bpf_map_lookup_elem),
1324	  __imm_addr(map_array_48b)
1325	: __clobber_all);
1326}
1327
1328SEC("socket")
1329__description("map access: value_ptr -= value_ptr")
1330__failure __msg("R0 invalid mem access 'scalar'")
1331__msg_unpriv("R0 pointer -= pointer prohibited")
1332__naked void access_value_ptr_value_ptr_2(void)
1333{
1334	asm volatile ("					\
1335	r1 = 0;						\
1336	*(u64*)(r10 - 8) = r1;				\
1337	r2 = r10;					\
1338	r2 += -8;					\
1339	r1 = %[map_array_48b] ll;			\
1340	call %[bpf_map_lookup_elem];			\
1341	if r0 == 0 goto l0_%=;				\
1342	r0 -= r0;					\
1343	r1 = *(u8*)(r0 + 0);				\
1344l0_%=:	r0 = 1;						\
1345	exit;						\
1346"	:
1347	: __imm(bpf_map_lookup_elem),
1348	  __imm_addr(map_array_48b)
1349	: __clobber_all);
1350}
1351
1352SEC("socket")
1353__description("map access: trying to leak tainted dst reg")
1354__failure __msg("math between map_value pointer and 4294967295 is not allowed")
1355__failure_unpriv
1356__naked void to_leak_tainted_dst_reg(void)
1357{
1358	asm volatile ("					\
1359	r0 = 0;						\
1360	r1 = 0;						\
1361	*(u64*)(r10 - 8) = r1;				\
1362	r2 = r10;					\
1363	r2 += -8;					\
1364	r1 = %[map_array_48b] ll;			\
1365	call %[bpf_map_lookup_elem];			\
1366	if r0 != 0 goto l0_%=;				\
1367	exit;						\
1368l0_%=:	r2 = r0;					\
1369	w1 = 0xFFFFFFFF;				\
1370	w1 = w1;					\
1371	r2 -= r1;					\
1372	*(u64*)(r0 + 0) = r2;				\
1373	r0 = 0;						\
1374	exit;						\
1375"	:
1376	: __imm(bpf_map_lookup_elem),
1377	  __imm_addr(map_array_48b)
1378	: __clobber_all);
1379}
1380
1381SEC("tc")
1382__description("32bit pkt_ptr -= scalar")
1383__success __retval(0) __flag(BPF_F_ANY_ALIGNMENT)
1384__naked void _32bit_pkt_ptr_scalar(void)
1385{
1386	asm volatile ("					\
1387	r8 = *(u32*)(r1 + %[__sk_buff_data_end]);	\
1388	r7 = *(u32*)(r1 + %[__sk_buff_data]);		\
1389	r6 = r7;					\
1390	r6 += 40;					\
1391	if r6 > r8 goto l0_%=;				\
1392	w4 = w7;					\
1393	w6 -= w4;					\
1394l0_%=:	r0 = 0;						\
1395	exit;						\
1396"	:
1397	: __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
1398	  __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
1399	: __clobber_all);
1400}
1401
1402SEC("tc")
1403__description("32bit scalar -= pkt_ptr")
1404__success __retval(0) __flag(BPF_F_ANY_ALIGNMENT)
1405__naked void _32bit_scalar_pkt_ptr(void)
1406{
1407	asm volatile ("					\
1408	r8 = *(u32*)(r1 + %[__sk_buff_data_end]);	\
1409	r7 = *(u32*)(r1 + %[__sk_buff_data]);		\
1410	r6 = r7;					\
1411	r6 += 40;					\
1412	if r6 > r8 goto l0_%=;				\
1413	w4 = w6;					\
1414	w4 -= w7;					\
1415l0_%=:	r0 = 0;						\
1416	exit;						\
1417"	:
1418	: __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
1419	  __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
1420	: __clobber_all);
1421}
1422
1423char _license[] SEC("license") = "GPL";
v6.8
   1// SPDX-License-Identifier: GPL-2.0
   2/* Converted from tools/testing/selftests/bpf/verifier/value_ptr_arith.c */
   3
   4#include <linux/bpf.h>
   5#include <bpf/bpf_helpers.h>
   6#include <errno.h>
   7#include "bpf_misc.h"
   8
   9#define MAX_ENTRIES 11
  10
  11struct test_val {
  12	unsigned int index;
  13	int foo[MAX_ENTRIES];
  14};
  15
  16struct {
  17	__uint(type, BPF_MAP_TYPE_ARRAY);
  18	__uint(max_entries, 1);
  19	__type(key, int);
  20	__type(value, struct test_val);
  21} map_array_48b SEC(".maps");
  22
  23struct other_val {
  24	long long foo;
  25	long long bar;
  26};
  27
  28struct {
  29	__uint(type, BPF_MAP_TYPE_HASH);
  30	__uint(max_entries, 1);
  31	__type(key, long long);
  32	__type(value, struct other_val);
  33} map_hash_16b SEC(".maps");
  34
  35struct {
  36	__uint(type, BPF_MAP_TYPE_HASH);
  37	__uint(max_entries, 1);
  38	__type(key, long long);
  39	__type(value, struct test_val);
  40} map_hash_48b SEC(".maps");
  41
  42SEC("socket")
  43__description("map access: known scalar += value_ptr unknown vs const")
  44__success __failure_unpriv
  45__msg_unpriv("R1 tried to add from different maps, paths or scalars")
  46__retval(1)
  47__naked void value_ptr_unknown_vs_const(void)
  48{
  49	asm volatile ("					\
  50	r0 = *(u32*)(r1 + %[__sk_buff_len]);		\
  51	r1 = 0;						\
  52	*(u64*)(r10 - 8) = r1;				\
  53	r2 = r10;					\
  54	r2 += -8;					\
  55	if r0 == 1 goto l0_%=;				\
  56	r1 = %[map_hash_16b] ll;			\
  57	if r0 != 1 goto l1_%=;				\
  58l0_%=:	r1 = %[map_array_48b] ll;			\
  59l1_%=:	call %[bpf_map_lookup_elem];			\
  60	if r0 == 0 goto l2_%=;				\
  61	r4 = *(u8*)(r0 + 0);				\
  62	if r4 == 1 goto l3_%=;				\
  63	r1 = 6;						\
  64	r1 = -r1;					\
  65	r1 &= 0x7;					\
  66	goto l4_%=;					\
  67l3_%=:	r1 = 3;						\
  68l4_%=:	r1 += r0;					\
  69	r0 = *(u8*)(r1 + 0);				\
  70l2_%=:	r0 = 1;						\
  71	exit;						\
  72"	:
  73	: __imm(bpf_map_lookup_elem),
  74	  __imm_addr(map_array_48b),
  75	  __imm_addr(map_hash_16b),
  76	  __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
  77	: __clobber_all);
  78}
  79
  80SEC("socket")
  81__description("map access: known scalar += value_ptr const vs unknown")
  82__success __failure_unpriv
  83__msg_unpriv("R1 tried to add from different maps, paths or scalars")
  84__retval(1)
  85__naked void value_ptr_const_vs_unknown(void)
  86{
  87	asm volatile ("					\
  88	r0 = *(u32*)(r1 + %[__sk_buff_len]);		\
  89	r1 = 0;						\
  90	*(u64*)(r10 - 8) = r1;				\
  91	r2 = r10;					\
  92	r2 += -8;					\
  93	if r0 == 1 goto l0_%=;				\
  94	r1 = %[map_hash_16b] ll;			\
  95	if r0 != 1 goto l1_%=;				\
  96l0_%=:	r1 = %[map_array_48b] ll;			\
  97l1_%=:	call %[bpf_map_lookup_elem];			\
  98	if r0 == 0 goto l2_%=;				\
  99	r4 = *(u8*)(r0 + 0);				\
 100	if r4 == 1 goto l3_%=;				\
 101	r1 = 3;						\
 102	goto l4_%=;					\
 103l3_%=:	r1 = 6;						\
 104	r1 = -r1;					\
 105	r1 &= 0x7;					\
 106l4_%=:	r1 += r0;					\
 107	r0 = *(u8*)(r1 + 0);				\
 108l2_%=:	r0 = 1;						\
 109	exit;						\
 110"	:
 111	: __imm(bpf_map_lookup_elem),
 112	  __imm_addr(map_array_48b),
 113	  __imm_addr(map_hash_16b),
 114	  __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
 115	: __clobber_all);
 116}
 117
 118SEC("socket")
 119__description("map access: known scalar += value_ptr const vs const (ne)")
 120__success __failure_unpriv
 121__msg_unpriv("R1 tried to add from different maps, paths or scalars")
 122__retval(1)
 123__naked void ptr_const_vs_const_ne(void)
 124{
 125	asm volatile ("					\
 126	r0 = *(u32*)(r1 + %[__sk_buff_len]);		\
 127	r1 = 0;						\
 128	*(u64*)(r10 - 8) = r1;				\
 129	r2 = r10;					\
 130	r2 += -8;					\
 131	if r0 == 1 goto l0_%=;				\
 132	r1 = %[map_hash_16b] ll;			\
 133	if r0 != 1 goto l1_%=;				\
 134l0_%=:	r1 = %[map_array_48b] ll;			\
 135l1_%=:	call %[bpf_map_lookup_elem];			\
 136	if r0 == 0 goto l2_%=;				\
 137	r4 = *(u8*)(r0 + 0);				\
 138	if r4 == 1 goto l3_%=;				\
 139	r1 = 3;						\
 140	goto l4_%=;					\
 141l3_%=:	r1 = 5;						\
 142l4_%=:	r1 += r0;					\
 143	r0 = *(u8*)(r1 + 0);				\
 144l2_%=:	r0 = 1;						\
 145	exit;						\
 146"	:
 147	: __imm(bpf_map_lookup_elem),
 148	  __imm_addr(map_array_48b),
 149	  __imm_addr(map_hash_16b),
 150	  __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
 151	: __clobber_all);
 152}
 153
 154SEC("socket")
 155__description("map access: known scalar += value_ptr const vs const (eq)")
 156__success __success_unpriv __retval(1)
 157__naked void ptr_const_vs_const_eq(void)
 158{
 159	asm volatile ("					\
 160	r0 = *(u32*)(r1 + %[__sk_buff_len]);		\
 161	r1 = 0;						\
 162	*(u64*)(r10 - 8) = r1;				\
 163	r2 = r10;					\
 164	r2 += -8;					\
 165	if r0 == 1 goto l0_%=;				\
 166	r1 = %[map_hash_16b] ll;			\
 167	if r0 != 1 goto l1_%=;				\
 168l0_%=:	r1 = %[map_array_48b] ll;			\
 169l1_%=:	call %[bpf_map_lookup_elem];			\
 170	if r0 == 0 goto l2_%=;				\
 171	r4 = *(u8*)(r0 + 0);				\
 172	if r4 == 1 goto l3_%=;				\
 173	r1 = 5;						\
 174	goto l4_%=;					\
 175l3_%=:	r1 = 5;						\
 176l4_%=:	r1 += r0;					\
 177	r0 = *(u8*)(r1 + 0);				\
 178l2_%=:	r0 = 1;						\
 179	exit;						\
 180"	:
 181	: __imm(bpf_map_lookup_elem),
 182	  __imm_addr(map_array_48b),
 183	  __imm_addr(map_hash_16b),
 184	  __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
 185	: __clobber_all);
 186}
 187
 188SEC("socket")
 189__description("map access: known scalar += value_ptr unknown vs unknown (eq)")
 190__success __success_unpriv __retval(1)
 191__naked void ptr_unknown_vs_unknown_eq(void)
 192{
 193	asm volatile ("					\
 194	r0 = *(u32*)(r1 + %[__sk_buff_len]);		\
 195	r1 = 0;						\
 196	*(u64*)(r10 - 8) = r1;				\
 197	r2 = r10;					\
 198	r2 += -8;					\
 199	if r0 == 1 goto l0_%=;				\
 200	r1 = %[map_hash_16b] ll;			\
 201	if r0 != 1 goto l1_%=;				\
 202l0_%=:	r1 = %[map_array_48b] ll;			\
 203l1_%=:	call %[bpf_map_lookup_elem];			\
 204	if r0 == 0 goto l2_%=;				\
 205	r4 = *(u8*)(r0 + 0);				\
 206	if r4 == 1 goto l3_%=;				\
 207	r1 = 6;						\
 208	r1 = -r1;					\
 209	r1 &= 0x7;					\
 210	goto l4_%=;					\
 211l3_%=:	r1 = 6;						\
 212	r1 = -r1;					\
 213	r1 &= 0x7;					\
 214l4_%=:	r1 += r0;					\
 215	r0 = *(u8*)(r1 + 0);				\
 216l2_%=:	r0 = 1;						\
 217	exit;						\
 218"	:
 219	: __imm(bpf_map_lookup_elem),
 220	  __imm_addr(map_array_48b),
 221	  __imm_addr(map_hash_16b),
 222	  __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
 223	: __clobber_all);
 224}
 225
 226SEC("socket")
 227__description("map access: known scalar += value_ptr unknown vs unknown (lt)")
 228__success __failure_unpriv
 229__msg_unpriv("R1 tried to add from different maps, paths or scalars")
 230__retval(1)
 231__naked void ptr_unknown_vs_unknown_lt(void)
 232{
 233	asm volatile ("					\
 234	r0 = *(u32*)(r1 + %[__sk_buff_len]);		\
 235	r1 = 0;						\
 236	*(u64*)(r10 - 8) = r1;				\
 237	r2 = r10;					\
 238	r2 += -8;					\
 239	if r0 == 1 goto l0_%=;				\
 240	r1 = %[map_hash_16b] ll;			\
 241	if r0 != 1 goto l1_%=;				\
 242l0_%=:	r1 = %[map_array_48b] ll;			\
 243l1_%=:	call %[bpf_map_lookup_elem];			\
 244	if r0 == 0 goto l2_%=;				\
 245	r4 = *(u8*)(r0 + 0);				\
 246	if r4 == 1 goto l3_%=;				\
 247	r1 = 6;						\
 248	r1 = -r1;					\
 249	r1 &= 0x3;					\
 250	goto l4_%=;					\
 251l3_%=:	r1 = 6;						\
 252	r1 = -r1;					\
 253	r1 &= 0x7;					\
 254l4_%=:	r1 += r0;					\
 255	r0 = *(u8*)(r1 + 0);				\
 256l2_%=:	r0 = 1;						\
 257	exit;						\
 258"	:
 259	: __imm(bpf_map_lookup_elem),
 260	  __imm_addr(map_array_48b),
 261	  __imm_addr(map_hash_16b),
 262	  __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
 263	: __clobber_all);
 264}
 265
 266SEC("socket")
 267__description("map access: known scalar += value_ptr unknown vs unknown (gt)")
 268__success __failure_unpriv
 269__msg_unpriv("R1 tried to add from different maps, paths or scalars")
 270__retval(1)
 271__naked void ptr_unknown_vs_unknown_gt(void)
 272{
 273	asm volatile ("					\
 274	r0 = *(u32*)(r1 + %[__sk_buff_len]);		\
 275	r1 = 0;						\
 276	*(u64*)(r10 - 8) = r1;				\
 277	r2 = r10;					\
 278	r2 += -8;					\
 279	if r0 == 1 goto l0_%=;				\
 280	r1 = %[map_hash_16b] ll;			\
 281	if r0 != 1 goto l1_%=;				\
 282l0_%=:	r1 = %[map_array_48b] ll;			\
 283l1_%=:	call %[bpf_map_lookup_elem];			\
 284	if r0 == 0 goto l2_%=;				\
 285	r4 = *(u8*)(r0 + 0);				\
 286	if r4 == 1 goto l3_%=;				\
 287	r1 = 6;						\
 288	r1 = -r1;					\
 289	r1 &= 0x7;					\
 290	goto l4_%=;					\
 291l3_%=:	r1 = 6;						\
 292	r1 = -r1;					\
 293	r1 &= 0x3;					\
 294l4_%=:	r1 += r0;					\
 295	r0 = *(u8*)(r1 + 0);				\
 296l2_%=:	r0 = 1;						\
 297	exit;						\
 298"	:
 299	: __imm(bpf_map_lookup_elem),
 300	  __imm_addr(map_array_48b),
 301	  __imm_addr(map_hash_16b),
 302	  __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
 303	: __clobber_all);
 304}
 305
 306SEC("socket")
 307__description("map access: known scalar += value_ptr from different maps")
 308__success __success_unpriv __retval(1)
 309__naked void value_ptr_from_different_maps(void)
 310{
 311	asm volatile ("					\
 312	r0 = *(u32*)(r1 + %[__sk_buff_len]);		\
 313	r1 = 0;						\
 314	*(u64*)(r10 - 8) = r1;				\
 315	r2 = r10;					\
 316	r2 += -8;					\
 317	if r0 == 1 goto l0_%=;				\
 318	r1 = %[map_hash_16b] ll;			\
 319	if r0 != 1 goto l1_%=;				\
 320l0_%=:	r1 = %[map_array_48b] ll;			\
 321l1_%=:	call %[bpf_map_lookup_elem];			\
 322	if r0 == 0 goto l2_%=;				\
 323	r1 = 4;						\
 324	r1 += r0;					\
 325	r0 = *(u8*)(r1 + 0);				\
 326l2_%=:	r0 = 1;						\
 327	exit;						\
 328"	:
 329	: __imm(bpf_map_lookup_elem),
 330	  __imm_addr(map_array_48b),
 331	  __imm_addr(map_hash_16b),
 332	  __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
 333	: __clobber_all);
 334}
 335
 336SEC("socket")
 337__description("map access: value_ptr -= known scalar from different maps")
 338__success __failure_unpriv
 339__msg_unpriv("R0 min value is outside of the allowed memory range")
 340__retval(1)
 341__naked void known_scalar_from_different_maps(void)
 342{
 343	asm volatile ("					\
 344	r0 = *(u32*)(r1 + %[__sk_buff_len]);		\
 345	r1 = 0;						\
 346	*(u64*)(r10 - 8) = r1;				\
 347	r2 = r10;					\
 348	r2 += -8;					\
 349	if r0 == 1 goto l0_%=;				\
 350	r1 = %[map_hash_16b] ll;			\
 351	if r0 != 1 goto l1_%=;				\
 352l0_%=:	r1 = %[map_array_48b] ll;			\
 353l1_%=:	call %[bpf_map_lookup_elem];			\
 354	if r0 == 0 goto l2_%=;				\
 355	r1 = 4;						\
 356	r0 -= r1;					\
 357	r0 += r1;					\
 358	r0 = *(u8*)(r0 + 0);				\
 359l2_%=:	r0 = 1;						\
 360	exit;						\
 361"	:
 362	: __imm(bpf_map_lookup_elem),
 363	  __imm_addr(map_array_48b),
 364	  __imm_addr(map_hash_16b),
 365	  __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
 366	: __clobber_all);
 367}
 368
 369SEC("socket")
 370__description("map access: known scalar += value_ptr from different maps, but same value properties")
 371__success __success_unpriv __retval(1)
 372__naked void maps_but_same_value_properties(void)
 373{
 374	asm volatile ("					\
 375	r0 = *(u32*)(r1 + %[__sk_buff_len]);		\
 376	r1 = 0;						\
 377	*(u64*)(r10 - 8) = r1;				\
 378	r2 = r10;					\
 379	r2 += -8;					\
 380	if r0 == 1 goto l0_%=;				\
 381	r1 = %[map_hash_48b] ll;			\
 382	if r0 != 1 goto l1_%=;				\
 383l0_%=:	r1 = %[map_array_48b] ll;			\
 384l1_%=:	call %[bpf_map_lookup_elem];			\
 385	if r0 == 0 goto l2_%=;				\
 386	r1 = 4;						\
 387	r1 += r0;					\
 388	r0 = *(u8*)(r1 + 0);				\
 389l2_%=:	r0 = 1;						\
 390	exit;						\
 391"	:
 392	: __imm(bpf_map_lookup_elem),
 393	  __imm_addr(map_array_48b),
 394	  __imm_addr(map_hash_48b),
 395	  __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
 396	: __clobber_all);
 397}
 398
 399SEC("socket")
 400__description("map access: mixing value pointer and scalar, 1")
 401__success __failure_unpriv __msg_unpriv("R2 pointer comparison prohibited")
 402__retval(0)
 403__naked void value_pointer_and_scalar_1(void)
 404{
 405	asm volatile ("					\
 406	/* load map value pointer into r0 and r2 */	\
 407	r0 = 1;						\
 408	r1 = %[map_array_48b] ll;			\
 409	r2 = r10;					\
 410	r2 += -16;					\
 411	r6 = 0;						\
 412	*(u64*)(r10 - 16) = r6;				\
 413	call %[bpf_map_lookup_elem];			\
 414	if r0 != 0 goto l0_%=;				\
 415	exit;						\
 416l0_%=:	/* load some number from the map into r1 */	\
 417	r1 = *(u8*)(r0 + 0);				\
 418	/* depending on r1, branch: */			\
 419	if r1 != 0 goto l1_%=;				\
 420	/* branch A */					\
 421	r2 = r0;					\
 422	r3 = 0;						\
 423	goto l2_%=;					\
 424l1_%=:	/* branch B */					\
 425	r2 = 0;						\
 426	r3 = 0x100000;					\
 427l2_%=:	/* common instruction */			\
 428	r2 += r3;					\
 429	/* depending on r1, branch: */			\
 430	if r1 != 0 goto l3_%=;				\
 431	/* branch A */					\
 432	goto l4_%=;					\
 433l3_%=:	/* branch B */					\
 434	r0 = 0x13371337;				\
 435	/* verifier follows fall-through */		\
 436	if r2 != 0x100000 goto l4_%=;			\
 437	r0 = 0;						\
 438	exit;						\
 439l4_%=:	/* fake-dead code; targeted from branch A to	\
 440	 * prevent dead code sanitization		\
 441	 */						\
 442	r0 = *(u8*)(r0 + 0);				\
 443	r0 = 0;						\
 444	exit;						\
 445"	:
 446	: __imm(bpf_map_lookup_elem),
 447	  __imm_addr(map_array_48b)
 448	: __clobber_all);
 449}
 450
 451SEC("socket")
 452__description("map access: mixing value pointer and scalar, 2")
 453__success __failure_unpriv __msg_unpriv("R0 invalid mem access 'scalar'")
 454__retval(0)
 455__naked void value_pointer_and_scalar_2(void)
 456{
 457	asm volatile ("					\
 458	/* load map value pointer into r0 and r2 */	\
 459	r0 = 1;						\
 460	r1 = %[map_array_48b] ll;			\
 461	r2 = r10;					\
 462	r2 += -16;					\
 463	r6 = 0;						\
 464	*(u64*)(r10 - 16) = r6;				\
 465	call %[bpf_map_lookup_elem];			\
 466	if r0 != 0 goto l0_%=;				\
 467	exit;						\
 468l0_%=:	/* load some number from the map into r1 */	\
 469	r1 = *(u8*)(r0 + 0);				\
 470	/* depending on r1, branch: */			\
 471	if r1 == 0 goto l1_%=;				\
 472	/* branch A */					\
 473	r2 = 0;						\
 474	r3 = 0x100000;					\
 475	goto l2_%=;					\
 476l1_%=:	/* branch B */					\
 477	r2 = r0;					\
 478	r3 = 0;						\
 479l2_%=:	/* common instruction */			\
 480	r2 += r3;					\
 481	/* depending on r1, branch: */			\
 482	if r1 != 0 goto l3_%=;				\
 483	/* branch A */					\
 484	goto l4_%=;					\
 485l3_%=:	/* branch B */					\
 486	r0 = 0x13371337;				\
 487	/* verifier follows fall-through */		\
 488	if r2 != 0x100000 goto l4_%=;			\
 489	r0 = 0;						\
 490	exit;						\
 491l4_%=:	/* fake-dead code; targeted from branch A to	\
 492	 * prevent dead code sanitization, rejected	\
 493	 * via branch B however				\
 494	 */						\
 495	r0 = *(u8*)(r0 + 0);				\
 496	r0 = 0;						\
 497	exit;						\
 498"	:
 499	: __imm(bpf_map_lookup_elem),
 500	  __imm_addr(map_array_48b)
 501	: __clobber_all);
 502}
 503
 504SEC("socket")
 505__description("sanitation: alu with different scalars 1")
 506__success __success_unpriv __retval(0x100000)
 507__naked void alu_with_different_scalars_1(void)
 508{
 509	asm volatile ("					\
 510	r0 = 1;						\
 511	r1 = %[map_array_48b] ll;			\
 512	r2 = r10;					\
 513	r2 += -16;					\
 514	r6 = 0;						\
 515	*(u64*)(r10 - 16) = r6;				\
 516	call %[bpf_map_lookup_elem];			\
 517	if r0 != 0 goto l0_%=;				\
 518	exit;						\
 519l0_%=:	r1 = *(u32*)(r0 + 0);				\
 520	if r1 == 0 goto l1_%=;				\
 521	r2 = 0;						\
 522	r3 = 0x100000;					\
 523	goto l2_%=;					\
 524l1_%=:	r2 = 42;					\
 525	r3 = 0x100001;					\
 526l2_%=:	r2 += r3;					\
 527	r0 = r2;					\
 528	exit;						\
 529"	:
 530	: __imm(bpf_map_lookup_elem),
 531	  __imm_addr(map_array_48b)
 532	: __clobber_all);
 533}
 534
 535SEC("socket")
 536__description("sanitation: alu with different scalars 2")
 537__success __success_unpriv __retval(0)
 538__naked void alu_with_different_scalars_2(void)
 539{
 540	asm volatile ("					\
 541	r0 = 1;						\
 542	r1 = %[map_array_48b] ll;			\
 543	r6 = r1;					\
 544	r2 = r10;					\
 545	r2 += -16;					\
 546	r7 = 0;						\
 547	*(u64*)(r10 - 16) = r7;				\
 548	call %[bpf_map_delete_elem];			\
 549	r7 = r0;					\
 550	r1 = r6;					\
 551	r2 = r10;					\
 552	r2 += -16;					\
 553	call %[bpf_map_delete_elem];			\
 554	r6 = r0;					\
 555	r8 = r6;					\
 556	r8 += r7;					\
 557	r0 = r8;					\
 558	r0 += %[einval];				\
 559	r0 += %[einval];				\
 560	exit;						\
 561"	:
 562	: __imm(bpf_map_delete_elem),
 563	  __imm_addr(map_array_48b),
 564	  __imm_const(einval, EINVAL)
 565	: __clobber_all);
 566}
 567
 568SEC("socket")
 569__description("sanitation: alu with different scalars 3")
 570__success __success_unpriv __retval(0)
 571__naked void alu_with_different_scalars_3(void)
 572{
 573	asm volatile ("					\
 574	r0 = %[einval];					\
 575	r0 *= -1;					\
 576	r7 = r0;					\
 577	r0 = %[einval];					\
 578	r0 *= -1;					\
 579	r6 = r0;					\
 580	r8 = r6;					\
 581	r8 += r7;					\
 582	r0 = r8;					\
 583	r0 += %[einval];				\
 584	r0 += %[einval];				\
 585	exit;						\
 586"	:
 587	: __imm_const(einval, EINVAL)
 588	: __clobber_all);
 589}
 590
 591SEC("socket")
 592__description("map access: value_ptr += known scalar, upper oob arith, test 1")
 593__success __failure_unpriv
 594__msg_unpriv("R0 pointer arithmetic of map value goes out of range")
 595__retval(1)
 596__naked void upper_oob_arith_test_1(void)
 597{
 598	asm volatile ("					\
 599	r1 = 0;						\
 600	*(u64*)(r10 - 8) = r1;				\
 601	r2 = r10;					\
 602	r2 += -8;					\
 603	r1 = %[map_array_48b] ll;			\
 604	call %[bpf_map_lookup_elem];			\
 605	if r0 == 0 goto l0_%=;				\
 606	r1 = 48;					\
 607	r0 += r1;					\
 608	r0 -= r1;					\
 609	r0 = *(u8*)(r0 + 0);				\
 610l0_%=:	r0 = 1;						\
 611	exit;						\
 612"	:
 613	: __imm(bpf_map_lookup_elem),
 614	  __imm_addr(map_array_48b)
 615	: __clobber_all);
 616}
 617
 618SEC("socket")
 619__description("map access: value_ptr += known scalar, upper oob arith, test 2")
 620__success __failure_unpriv
 621__msg_unpriv("R0 pointer arithmetic of map value goes out of range")
 622__retval(1)
 623__naked void upper_oob_arith_test_2(void)
 624{
 625	asm volatile ("					\
 626	r1 = 0;						\
 627	*(u64*)(r10 - 8) = r1;				\
 628	r2 = r10;					\
 629	r2 += -8;					\
 630	r1 = %[map_array_48b] ll;			\
 631	call %[bpf_map_lookup_elem];			\
 632	if r0 == 0 goto l0_%=;				\
 633	r1 = 49;					\
 634	r0 += r1;					\
 635	r0 -= r1;					\
 636	r0 = *(u8*)(r0 + 0);				\
 637l0_%=:	r0 = 1;						\
 638	exit;						\
 639"	:
 640	: __imm(bpf_map_lookup_elem),
 641	  __imm_addr(map_array_48b)
 642	: __clobber_all);
 643}
 644
 645SEC("socket")
 646__description("map access: value_ptr += known scalar, upper oob arith, test 3")
 647__success __success_unpriv __retval(1)
 648__naked void upper_oob_arith_test_3(void)
 649{
 650	asm volatile ("					\
 651	r1 = 0;						\
 652	*(u64*)(r10 - 8) = r1;				\
 653	r2 = r10;					\
 654	r2 += -8;					\
 655	r1 = %[map_array_48b] ll;			\
 656	call %[bpf_map_lookup_elem];			\
 657	if r0 == 0 goto l0_%=;				\
 658	r1 = 47;					\
 659	r0 += r1;					\
 660	r0 -= r1;					\
 661	r0 = *(u8*)(r0 + 0);				\
 662l0_%=:	r0 = 1;						\
 663	exit;						\
 664"	:
 665	: __imm(bpf_map_lookup_elem),
 666	  __imm_addr(map_array_48b)
 667	: __clobber_all);
 668}
 669
 670SEC("socket")
 671__description("map access: value_ptr -= known scalar, lower oob arith, test 1")
 672__failure __msg("R0 min value is outside of the allowed memory range")
 673__failure_unpriv
 674__msg_unpriv("R0 pointer arithmetic of map value goes out of range")
 675__naked void lower_oob_arith_test_1(void)
 676{
 677	asm volatile ("					\
 678	r1 = 0;						\
 679	*(u64*)(r10 - 8) = r1;				\
 680	r2 = r10;					\
 681	r2 += -8;					\
 682	r1 = %[map_array_48b] ll;			\
 683	call %[bpf_map_lookup_elem];			\
 684	if r0 == 0 goto l0_%=;				\
 685	r1 = 47;					\
 686	r0 += r1;					\
 687	r1 = 48;					\
 688	r0 -= r1;					\
 689	r0 = *(u8*)(r0 + 0);				\
 690l0_%=:	r0 = 1;						\
 691	exit;						\
 692"	:
 693	: __imm(bpf_map_lookup_elem),
 694	  __imm_addr(map_array_48b)
 695	: __clobber_all);
 696}
 697
 698SEC("socket")
 699__description("map access: value_ptr -= known scalar, lower oob arith, test 2")
 700__success __failure_unpriv
 701__msg_unpriv("R0 pointer arithmetic of map value goes out of range")
 702__retval(1)
 703__naked void lower_oob_arith_test_2(void)
 704{
 705	asm volatile ("					\
 706	r1 = 0;						\
 707	*(u64*)(r10 - 8) = r1;				\
 708	r2 = r10;					\
 709	r2 += -8;					\
 710	r1 = %[map_array_48b] ll;			\
 711	call %[bpf_map_lookup_elem];			\
 712	if r0 == 0 goto l0_%=;				\
 713	r1 = 47;					\
 714	r0 += r1;					\
 715	r1 = 48;					\
 716	r0 -= r1;					\
 717	r1 = 1;						\
 718	r0 += r1;					\
 719	r0 = *(u8*)(r0 + 0);				\
 720l0_%=:	r0 = 1;						\
 721	exit;						\
 722"	:
 723	: __imm(bpf_map_lookup_elem),
 724	  __imm_addr(map_array_48b)
 725	: __clobber_all);
 726}
 727
 728SEC("socket")
 729__description("map access: value_ptr -= known scalar, lower oob arith, test 3")
 730__success __success_unpriv __retval(1)
 731__naked void lower_oob_arith_test_3(void)
 732{
 733	asm volatile ("					\
 734	r1 = 0;						\
 735	*(u64*)(r10 - 8) = r1;				\
 736	r2 = r10;					\
 737	r2 += -8;					\
 738	r1 = %[map_array_48b] ll;			\
 739	call %[bpf_map_lookup_elem];			\
 740	if r0 == 0 goto l0_%=;				\
 741	r1 = 47;					\
 742	r0 += r1;					\
 743	r1 = 47;					\
 744	r0 -= r1;					\
 745	r0 = *(u8*)(r0 + 0);				\
 746l0_%=:	r0 = 1;						\
 747	exit;						\
 748"	:
 749	: __imm(bpf_map_lookup_elem),
 750	  __imm_addr(map_array_48b)
 751	: __clobber_all);
 752}
 753
 754SEC("socket")
 755__description("map access: known scalar += value_ptr")
 756__success __success_unpriv __retval(1)
 757__naked void access_known_scalar_value_ptr_1(void)
 758{
 759	asm volatile ("					\
 760	r1 = 0;						\
 761	*(u64*)(r10 - 8) = r1;				\
 762	r2 = r10;					\
 763	r2 += -8;					\
 764	r1 = %[map_array_48b] ll;			\
 765	call %[bpf_map_lookup_elem];			\
 766	if r0 == 0 goto l0_%=;				\
 767	r1 = 4;						\
 768	r1 += r0;					\
 769	r0 = *(u8*)(r1 + 0);				\
 770l0_%=:	r0 = 1;						\
 771	exit;						\
 772"	:
 773	: __imm(bpf_map_lookup_elem),
 774	  __imm_addr(map_array_48b)
 775	: __clobber_all);
 776}
 777
 778SEC("socket")
 779__description("map access: value_ptr += known scalar, 1")
 780__success __success_unpriv __retval(1)
 781__naked void value_ptr_known_scalar_1(void)
 782{
 783	asm volatile ("					\
 784	r1 = 0;						\
 785	*(u64*)(r10 - 8) = r1;				\
 786	r2 = r10;					\
 787	r2 += -8;					\
 788	r1 = %[map_array_48b] ll;			\
 789	call %[bpf_map_lookup_elem];			\
 790	if r0 == 0 goto l0_%=;				\
 791	r1 = 4;						\
 792	r0 += r1;					\
 793	r1 = *(u8*)(r0 + 0);				\
 794l0_%=:	r0 = 1;						\
 795	exit;						\
 796"	:
 797	: __imm(bpf_map_lookup_elem),
 798	  __imm_addr(map_array_48b)
 799	: __clobber_all);
 800}
 801
 802SEC("socket")
 803__description("map access: value_ptr += known scalar, 2")
 804__failure __msg("invalid access to map value")
 805__failure_unpriv
 806__naked void value_ptr_known_scalar_2_1(void)
 807{
 808	asm volatile ("					\
 809	r1 = 0;						\
 810	*(u64*)(r10 - 8) = r1;				\
 811	r2 = r10;					\
 812	r2 += -8;					\
 813	r1 = %[map_array_48b] ll;			\
 814	call %[bpf_map_lookup_elem];			\
 815	if r0 == 0 goto l0_%=;				\
 816	r1 = 49;					\
 817	r0 += r1;					\
 818	r1 = *(u8*)(r0 + 0);				\
 819l0_%=:	r0 = 1;						\
 820	exit;						\
 821"	:
 822	: __imm(bpf_map_lookup_elem),
 823	  __imm_addr(map_array_48b)
 824	: __clobber_all);
 825}
 826
 827SEC("socket")
 828__description("map access: value_ptr += known scalar, 3")
 829__failure __msg("invalid access to map value")
 830__failure_unpriv
 831__naked void value_ptr_known_scalar_3(void)
 832{
 833	asm volatile ("					\
 834	r1 = 0;						\
 835	*(u64*)(r10 - 8) = r1;				\
 836	r2 = r10;					\
 837	r2 += -8;					\
 838	r1 = %[map_array_48b] ll;			\
 839	call %[bpf_map_lookup_elem];			\
 840	if r0 == 0 goto l0_%=;				\
 841	r1 = -1;					\
 842	r0 += r1;					\
 843	r1 = *(u8*)(r0 + 0);				\
 844l0_%=:	r0 = 1;						\
 845	exit;						\
 846"	:
 847	: __imm(bpf_map_lookup_elem),
 848	  __imm_addr(map_array_48b)
 849	: __clobber_all);
 850}
 851
 852SEC("socket")
 853__description("map access: value_ptr += known scalar, 4")
 854__success __success_unpriv __retval(1)
 855__naked void value_ptr_known_scalar_4(void)
 856{
 857	asm volatile ("					\
 858	r1 = 0;						\
 859	*(u64*)(r10 - 8) = r1;				\
 860	r2 = r10;					\
 861	r2 += -8;					\
 862	r1 = %[map_array_48b] ll;			\
 863	call %[bpf_map_lookup_elem];			\
 864	if r0 == 0 goto l0_%=;				\
 865	r1 = 5;						\
 866	r0 += r1;					\
 867	r1 = -2;					\
 868	r0 += r1;					\
 869	r1 = -1;					\
 870	r0 += r1;					\
 871	r1 = *(u8*)(r0 + 0);				\
 872l0_%=:	r0 = 1;						\
 873	exit;						\
 874"	:
 875	: __imm(bpf_map_lookup_elem),
 876	  __imm_addr(map_array_48b)
 877	: __clobber_all);
 878}
 879
 880SEC("socket")
 881__description("map access: value_ptr += known scalar, 5")
 882__success __success_unpriv __retval(0xabcdef12)
 883__naked void value_ptr_known_scalar_5(void)
 884{
 885	asm volatile ("					\
 886	r1 = 0;						\
 887	*(u64*)(r10 - 8) = r1;				\
 888	r2 = r10;					\
 889	r2 += -8;					\
 890	r1 = %[map_array_48b] ll;			\
 891	call %[bpf_map_lookup_elem];			\
 892	if r0 == 0 goto l0_%=;				\
 893	r1 = %[__imm_0];				\
 894	r1 += r0;					\
 895	r0 = *(u32*)(r1 + 0);				\
 896l0_%=:	exit;						\
 897"	:
 898	: __imm(bpf_map_lookup_elem),
 899	  __imm_addr(map_array_48b),
 900	  __imm_const(__imm_0, (6 + 1) * sizeof(int))
 901	: __clobber_all);
 902}
 903
 904SEC("socket")
 905__description("map access: value_ptr += known scalar, 6")
 906__success __success_unpriv __retval(0xabcdef12)
 907__naked void value_ptr_known_scalar_6(void)
 908{
 909	asm volatile ("					\
 910	r1 = 0;						\
 911	*(u64*)(r10 - 8) = r1;				\
 912	r2 = r10;					\
 913	r2 += -8;					\
 914	r1 = %[map_array_48b] ll;			\
 915	call %[bpf_map_lookup_elem];			\
 916	if r0 == 0 goto l0_%=;				\
 917	r1 = %[__imm_0];				\
 918	r0 += r1;					\
 919	r1 = %[__imm_1];				\
 920	r0 += r1;					\
 921	r0 = *(u32*)(r0 + 0);				\
 922l0_%=:	exit;						\
 923"	:
 924	: __imm(bpf_map_lookup_elem),
 925	  __imm_addr(map_array_48b),
 926	  __imm_const(__imm_0, (3 + 1) * sizeof(int)),
 927	  __imm_const(__imm_1, 3 * sizeof(int))
 928	: __clobber_all);
 929}
 930
 931SEC("socket")
 932__description("map access: value_ptr += N, value_ptr -= N known scalar")
 933__success __success_unpriv __retval(0x12345678)
 934__naked void value_ptr_n_known_scalar(void)
 935{
 936	asm volatile ("					\
 937	r1 = 0;						\
 938	*(u64*)(r10 - 8) = r1;				\
 939	r2 = r10;					\
 940	r2 += -8;					\
 941	r1 = %[map_array_48b] ll;			\
 942	call %[bpf_map_lookup_elem];			\
 943	if r0 == 0 goto l0_%=;				\
 944	w1 = 0x12345678;				\
 945	*(u32*)(r0 + 0) = r1;				\
 946	r0 += 2;					\
 947	r1 = 2;						\
 948	r0 -= r1;					\
 949	r0 = *(u32*)(r0 + 0);				\
 950l0_%=:	exit;						\
 951"	:
 952	: __imm(bpf_map_lookup_elem),
 953	  __imm_addr(map_array_48b)
 954	: __clobber_all);
 955}
 956
 957SEC("socket")
 958__description("map access: unknown scalar += value_ptr, 1")
 959__success __success_unpriv __retval(1)
 960__naked void unknown_scalar_value_ptr_1(void)
 961{
 962	asm volatile ("					\
 963	r1 = 0;						\
 964	*(u64*)(r10 - 8) = r1;				\
 965	r2 = r10;					\
 966	r2 += -8;					\
 967	r1 = %[map_array_48b] ll;			\
 968	call %[bpf_map_lookup_elem];			\
 969	if r0 == 0 goto l0_%=;				\
 970	r1 = *(u8*)(r0 + 0);				\
 971	r1 &= 0xf;					\
 972	r1 += r0;					\
 973	r0 = *(u8*)(r1 + 0);				\
 974l0_%=:	r0 = 1;						\
 975	exit;						\
 976"	:
 977	: __imm(bpf_map_lookup_elem),
 978	  __imm_addr(map_array_48b)
 979	: __clobber_all);
 980}
 981
 982SEC("socket")
 983__description("map access: unknown scalar += value_ptr, 2")
 984__success __success_unpriv __retval(0xabcdef12) __flag(BPF_F_ANY_ALIGNMENT)
 985__naked void unknown_scalar_value_ptr_2(void)
 986{
 987	asm volatile ("					\
 988	r1 = 0;						\
 989	*(u64*)(r10 - 8) = r1;				\
 990	r2 = r10;					\
 991	r2 += -8;					\
 992	r1 = %[map_array_48b] ll;			\
 993	call %[bpf_map_lookup_elem];			\
 994	if r0 == 0 goto l0_%=;				\
 995	r1 = *(u32*)(r0 + 0);				\
 996	r1 &= 31;					\
 997	r1 += r0;					\
 998	r0 = *(u32*)(r1 + 0);				\
 999l0_%=:	exit;						\
1000"	:
1001	: __imm(bpf_map_lookup_elem),
1002	  __imm_addr(map_array_48b)
1003	: __clobber_all);
1004}
1005
1006SEC("socket")
1007__description("map access: unknown scalar += value_ptr, 3")
1008__success __failure_unpriv
1009__msg_unpriv("R0 pointer arithmetic of map value goes out of range")
1010__retval(0xabcdef12) __flag(BPF_F_ANY_ALIGNMENT)
1011__naked void unknown_scalar_value_ptr_3(void)
1012{
1013	asm volatile ("					\
1014	r1 = 0;						\
1015	*(u64*)(r10 - 8) = r1;				\
1016	r2 = r10;					\
1017	r2 += -8;					\
1018	r1 = %[map_array_48b] ll;			\
1019	call %[bpf_map_lookup_elem];			\
1020	if r0 == 0 goto l0_%=;				\
1021	r1 = -1;					\
1022	r0 += r1;					\
1023	r1 = 1;						\
1024	r0 += r1;					\
1025	r1 = *(u32*)(r0 + 0);				\
1026	r1 &= 31;					\
1027	r1 += r0;					\
1028	r0 = *(u32*)(r1 + 0);				\
1029l0_%=:	exit;						\
1030"	:
1031	: __imm(bpf_map_lookup_elem),
1032	  __imm_addr(map_array_48b)
1033	: __clobber_all);
1034}
1035
1036SEC("socket")
1037__description("map access: unknown scalar += value_ptr, 4")
1038__failure __msg("R1 max value is outside of the allowed memory range")
1039__msg_unpriv("R1 pointer arithmetic of map value goes out of range")
1040__flag(BPF_F_ANY_ALIGNMENT)
1041__naked void unknown_scalar_value_ptr_4(void)
1042{
1043	asm volatile ("					\
1044	r1 = 0;						\
1045	*(u64*)(r10 - 8) = r1;				\
1046	r2 = r10;					\
1047	r2 += -8;					\
1048	r1 = %[map_array_48b] ll;			\
1049	call %[bpf_map_lookup_elem];			\
1050	if r0 == 0 goto l0_%=;				\
1051	r1 = 19;					\
1052	r0 += r1;					\
1053	r1 = *(u32*)(r0 + 0);				\
1054	r1 &= 31;					\
1055	r1 += r0;					\
1056	r0 = *(u32*)(r1 + 0);				\
1057l0_%=:	exit;						\
1058"	:
1059	: __imm(bpf_map_lookup_elem),
1060	  __imm_addr(map_array_48b)
1061	: __clobber_all);
1062}
1063
1064SEC("socket")
1065__description("map access: value_ptr += unknown scalar, 1")
1066__success __success_unpriv __retval(1)
1067__naked void value_ptr_unknown_scalar_1(void)
1068{
1069	asm volatile ("					\
1070	r1 = 0;						\
1071	*(u64*)(r10 - 8) = r1;				\
1072	r2 = r10;					\
1073	r2 += -8;					\
1074	r1 = %[map_array_48b] ll;			\
1075	call %[bpf_map_lookup_elem];			\
1076	if r0 == 0 goto l0_%=;				\
1077	r1 = *(u8*)(r0 + 0);				\
1078	r1 &= 0xf;					\
1079	r0 += r1;					\
1080	r1 = *(u8*)(r0 + 0);				\
1081l0_%=:	r0 = 1;						\
1082	exit;						\
1083"	:
1084	: __imm(bpf_map_lookup_elem),
1085	  __imm_addr(map_array_48b)
1086	: __clobber_all);
1087}
1088
1089SEC("socket")
1090__description("map access: value_ptr += unknown scalar, 2")
1091__success __success_unpriv __retval(0xabcdef12) __flag(BPF_F_ANY_ALIGNMENT)
1092__naked void value_ptr_unknown_scalar_2_1(void)
1093{
1094	asm volatile ("					\
1095	r1 = 0;						\
1096	*(u64*)(r10 - 8) = r1;				\
1097	r2 = r10;					\
1098	r2 += -8;					\
1099	r1 = %[map_array_48b] ll;			\
1100	call %[bpf_map_lookup_elem];			\
1101	if r0 == 0 goto l0_%=;				\
1102	r1 = *(u32*)(r0 + 0);				\
1103	r1 &= 31;					\
1104	r0 += r1;					\
1105	r0 = *(u32*)(r0 + 0);				\
1106l0_%=:	exit;						\
1107"	:
1108	: __imm(bpf_map_lookup_elem),
1109	  __imm_addr(map_array_48b)
1110	: __clobber_all);
1111}
1112
1113SEC("socket")
1114__description("map access: value_ptr += unknown scalar, 3")
1115__success __success_unpriv __retval(1)
1116__naked void value_ptr_unknown_scalar_3(void)
1117{
1118	asm volatile ("					\
1119	r1 = 0;						\
1120	*(u64*)(r10 - 8) = r1;				\
1121	r2 = r10;					\
1122	r2 += -8;					\
1123	r1 = %[map_array_48b] ll;			\
1124	call %[bpf_map_lookup_elem];			\
1125	if r0 == 0 goto l0_%=;				\
1126	r1 = *(u64*)(r0 + 0);				\
1127	r2 = *(u64*)(r0 + 8);				\
1128	r3 = *(u64*)(r0 + 16);				\
1129	r1 &= 0xf;					\
1130	r3 &= 1;					\
1131	r3 |= 1;					\
1132	if r2 > r3 goto l0_%=;				\
1133	r0 += r3;					\
1134	r0 = *(u8*)(r0 + 0);				\
1135	r0 = 1;						\
1136l1_%=:	exit;						\
1137l0_%=:	r0 = 2;						\
1138	goto l1_%=;					\
1139"	:
1140	: __imm(bpf_map_lookup_elem),
1141	  __imm_addr(map_array_48b)
1142	: __clobber_all);
1143}
1144
1145SEC("socket")
1146__description("map access: value_ptr += value_ptr")
1147__failure __msg("R0 pointer += pointer prohibited")
1148__failure_unpriv
1149__naked void access_value_ptr_value_ptr_1(void)
1150{
1151	asm volatile ("					\
1152	r1 = 0;						\
1153	*(u64*)(r10 - 8) = r1;				\
1154	r2 = r10;					\
1155	r2 += -8;					\
1156	r1 = %[map_array_48b] ll;			\
1157	call %[bpf_map_lookup_elem];			\
1158	if r0 == 0 goto l0_%=;				\
1159	r0 += r0;					\
1160	r1 = *(u8*)(r0 + 0);				\
1161l0_%=:	r0 = 1;						\
1162	exit;						\
1163"	:
1164	: __imm(bpf_map_lookup_elem),
1165	  __imm_addr(map_array_48b)
1166	: __clobber_all);
1167}
1168
1169SEC("socket")
1170__description("map access: known scalar -= value_ptr")
1171__failure __msg("R1 tried to subtract pointer from scalar")
1172__failure_unpriv
1173__naked void access_known_scalar_value_ptr_2(void)
1174{
1175	asm volatile ("					\
1176	r1 = 0;						\
1177	*(u64*)(r10 - 8) = r1;				\
1178	r2 = r10;					\
1179	r2 += -8;					\
1180	r1 = %[map_array_48b] ll;			\
1181	call %[bpf_map_lookup_elem];			\
1182	if r0 == 0 goto l0_%=;				\
1183	r1 = 4;						\
1184	r1 -= r0;					\
1185	r0 = *(u8*)(r1 + 0);				\
1186l0_%=:	r0 = 1;						\
1187	exit;						\
1188"	:
1189	: __imm(bpf_map_lookup_elem),
1190	  __imm_addr(map_array_48b)
1191	: __clobber_all);
1192}
1193
1194SEC("socket")
1195__description("map access: value_ptr -= known scalar")
1196__failure __msg("R0 min value is outside of the allowed memory range")
1197__failure_unpriv
1198__naked void access_value_ptr_known_scalar(void)
1199{
1200	asm volatile ("					\
1201	r1 = 0;						\
1202	*(u64*)(r10 - 8) = r1;				\
1203	r2 = r10;					\
1204	r2 += -8;					\
1205	r1 = %[map_array_48b] ll;			\
1206	call %[bpf_map_lookup_elem];			\
1207	if r0 == 0 goto l0_%=;				\
1208	r1 = 4;						\
1209	r0 -= r1;					\
1210	r1 = *(u8*)(r0 + 0);				\
1211l0_%=:	r0 = 1;						\
1212	exit;						\
1213"	:
1214	: __imm(bpf_map_lookup_elem),
1215	  __imm_addr(map_array_48b)
1216	: __clobber_all);
1217}
1218
1219SEC("socket")
1220__description("map access: value_ptr -= known scalar, 2")
1221__success __success_unpriv __retval(1)
1222__naked void value_ptr_known_scalar_2_2(void)
1223{
1224	asm volatile ("					\
1225	r1 = 0;						\
1226	*(u64*)(r10 - 8) = r1;				\
1227	r2 = r10;					\
1228	r2 += -8;					\
1229	r1 = %[map_array_48b] ll;			\
1230	call %[bpf_map_lookup_elem];			\
1231	if r0 == 0 goto l0_%=;				\
1232	r1 = 6;						\
1233	r2 = 4;						\
1234	r0 += r1;					\
1235	r0 -= r2;					\
1236	r1 = *(u8*)(r0 + 0);				\
1237l0_%=:	r0 = 1;						\
1238	exit;						\
1239"	:
1240	: __imm(bpf_map_lookup_elem),
1241	  __imm_addr(map_array_48b)
1242	: __clobber_all);
1243}
1244
1245SEC("socket")
1246__description("map access: unknown scalar -= value_ptr")
1247__failure __msg("R1 tried to subtract pointer from scalar")
1248__failure_unpriv
1249__naked void access_unknown_scalar_value_ptr(void)
1250{
1251	asm volatile ("					\
1252	r1 = 0;						\
1253	*(u64*)(r10 - 8) = r1;				\
1254	r2 = r10;					\
1255	r2 += -8;					\
1256	r1 = %[map_array_48b] ll;			\
1257	call %[bpf_map_lookup_elem];			\
1258	if r0 == 0 goto l0_%=;				\
1259	r1 = *(u8*)(r0 + 0);				\
1260	r1 &= 0xf;					\
1261	r1 -= r0;					\
1262	r0 = *(u8*)(r1 + 0);				\
1263l0_%=:	r0 = 1;						\
1264	exit;						\
1265"	:
1266	: __imm(bpf_map_lookup_elem),
1267	  __imm_addr(map_array_48b)
1268	: __clobber_all);
1269}
1270
1271SEC("socket")
1272__description("map access: value_ptr -= unknown scalar")
1273__failure __msg("R0 min value is negative")
1274__failure_unpriv
1275__naked void access_value_ptr_unknown_scalar(void)
1276{
1277	asm volatile ("					\
1278	r1 = 0;						\
1279	*(u64*)(r10 - 8) = r1;				\
1280	r2 = r10;					\
1281	r2 += -8;					\
1282	r1 = %[map_array_48b] ll;			\
1283	call %[bpf_map_lookup_elem];			\
1284	if r0 == 0 goto l0_%=;				\
1285	r1 = *(u8*)(r0 + 0);				\
1286	r1 &= 0xf;					\
1287	r0 -= r1;					\
1288	r1 = *(u8*)(r0 + 0);				\
1289l0_%=:	r0 = 1;						\
1290	exit;						\
1291"	:
1292	: __imm(bpf_map_lookup_elem),
1293	  __imm_addr(map_array_48b)
1294	: __clobber_all);
1295}
1296
1297SEC("socket")
1298__description("map access: value_ptr -= unknown scalar, 2")
1299__success __failure_unpriv
1300__msg_unpriv("R0 pointer arithmetic of map value goes out of range")
1301__retval(1)
1302__naked void value_ptr_unknown_scalar_2_2(void)
1303{
1304	asm volatile ("					\
1305	r1 = 0;						\
1306	*(u64*)(r10 - 8) = r1;				\
1307	r2 = r10;					\
1308	r2 += -8;					\
1309	r1 = %[map_array_48b] ll;			\
1310	call %[bpf_map_lookup_elem];			\
1311	if r0 == 0 goto l0_%=;				\
1312	r1 = *(u8*)(r0 + 0);				\
1313	r1 &= 0xf;					\
1314	r1 |= 0x7;					\
1315	r0 += r1;					\
1316	r1 = *(u8*)(r0 + 0);				\
1317	r1 &= 0x7;					\
1318	r0 -= r1;					\
1319	r1 = *(u8*)(r0 + 0);				\
1320l0_%=:	r0 = 1;						\
1321	exit;						\
1322"	:
1323	: __imm(bpf_map_lookup_elem),
1324	  __imm_addr(map_array_48b)
1325	: __clobber_all);
1326}
1327
1328SEC("socket")
1329__description("map access: value_ptr -= value_ptr")
1330__failure __msg("R0 invalid mem access 'scalar'")
1331__msg_unpriv("R0 pointer -= pointer prohibited")
1332__naked void access_value_ptr_value_ptr_2(void)
1333{
1334	asm volatile ("					\
1335	r1 = 0;						\
1336	*(u64*)(r10 - 8) = r1;				\
1337	r2 = r10;					\
1338	r2 += -8;					\
1339	r1 = %[map_array_48b] ll;			\
1340	call %[bpf_map_lookup_elem];			\
1341	if r0 == 0 goto l0_%=;				\
1342	r0 -= r0;					\
1343	r1 = *(u8*)(r0 + 0);				\
1344l0_%=:	r0 = 1;						\
1345	exit;						\
1346"	:
1347	: __imm(bpf_map_lookup_elem),
1348	  __imm_addr(map_array_48b)
1349	: __clobber_all);
1350}
1351
1352SEC("socket")
1353__description("map access: trying to leak tainted dst reg")
1354__failure __msg("math between map_value pointer and 4294967295 is not allowed")
1355__failure_unpriv
1356__naked void to_leak_tainted_dst_reg(void)
1357{
1358	asm volatile ("					\
1359	r0 = 0;						\
1360	r1 = 0;						\
1361	*(u64*)(r10 - 8) = r1;				\
1362	r2 = r10;					\
1363	r2 += -8;					\
1364	r1 = %[map_array_48b] ll;			\
1365	call %[bpf_map_lookup_elem];			\
1366	if r0 != 0 goto l0_%=;				\
1367	exit;						\
1368l0_%=:	r2 = r0;					\
1369	w1 = 0xFFFFFFFF;				\
1370	w1 = w1;					\
1371	r2 -= r1;					\
1372	*(u64*)(r0 + 0) = r2;				\
1373	r0 = 0;						\
1374	exit;						\
1375"	:
1376	: __imm(bpf_map_lookup_elem),
1377	  __imm_addr(map_array_48b)
1378	: __clobber_all);
1379}
1380
1381SEC("tc")
1382__description("32bit pkt_ptr -= scalar")
1383__success __retval(0) __flag(BPF_F_ANY_ALIGNMENT)
1384__naked void _32bit_pkt_ptr_scalar(void)
1385{
1386	asm volatile ("					\
1387	r8 = *(u32*)(r1 + %[__sk_buff_data_end]);	\
1388	r7 = *(u32*)(r1 + %[__sk_buff_data]);		\
1389	r6 = r7;					\
1390	r6 += 40;					\
1391	if r6 > r8 goto l0_%=;				\
1392	w4 = w7;					\
1393	w6 -= w4;					\
1394l0_%=:	r0 = 0;						\
1395	exit;						\
1396"	:
1397	: __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
1398	  __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
1399	: __clobber_all);
1400}
1401
1402SEC("tc")
1403__description("32bit scalar -= pkt_ptr")
1404__success __retval(0) __flag(BPF_F_ANY_ALIGNMENT)
1405__naked void _32bit_scalar_pkt_ptr(void)
1406{
1407	asm volatile ("					\
1408	r8 = *(u32*)(r1 + %[__sk_buff_data_end]);	\
1409	r7 = *(u32*)(r1 + %[__sk_buff_data]);		\
1410	r6 = r7;					\
1411	r6 += 40;					\
1412	if r6 > r8 goto l0_%=;				\
1413	w4 = w6;					\
1414	w4 -= w7;					\
1415l0_%=:	r0 = 0;						\
1416	exit;						\
1417"	:
1418	: __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
1419	  __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
1420	: __clobber_all);
1421}
1422
1423char _license[] SEC("license") = "GPL";