804 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Converted from tools/testing/selftests/bpf/verifier/direct_packet_access.c */3 4#include <linux/bpf.h>5#include <bpf/bpf_helpers.h>6#include "bpf_misc.h"7 8SEC("tc")9__description("pkt_end - pkt_start is allowed")10__success __retval(TEST_DATA_LEN)11__naked void end_pkt_start_is_allowed(void)12{13 asm volatile (" \14 r0 = *(u32*)(r1 + %[__sk_buff_data_end]); \15 r2 = *(u32*)(r1 + %[__sk_buff_data]); \16 r0 -= r2; \17 exit; \18" :19 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),20 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))21 : __clobber_all);22}23 24SEC("tc")25__description("direct packet access: test1")26__success __retval(0)27__naked void direct_packet_access_test1(void)28{29 asm volatile (" \30 r2 = *(u32*)(r1 + %[__sk_buff_data]); \31 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \32 r0 = r2; \33 r0 += 8; \34 if r0 > r3 goto l0_%=; \35 r0 = *(u8*)(r2 + 0); \36l0_%=: r0 = 0; \37 exit; \38" :39 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),40 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))41 : __clobber_all);42}43 44SEC("tc")45__description("direct packet access: test2")46__success __retval(0)47__naked void direct_packet_access_test2(void)48{49 asm volatile (" \50 r0 = 1; \51 r4 = *(u32*)(r1 + %[__sk_buff_data_end]); \52 r3 = *(u32*)(r1 + %[__sk_buff_data]); \53 r5 = r3; \54 r5 += 14; \55 if r5 > r4 goto l0_%=; \56 r0 = *(u8*)(r3 + 7); \57 r4 = *(u8*)(r3 + 12); \58 r4 *= 14; \59 r3 = *(u32*)(r1 + %[__sk_buff_data]); \60 r3 += r4; \61 r2 = *(u32*)(r1 + %[__sk_buff_len]); \62 r2 <<= 49; \63 r2 >>= 49; \64 r3 += r2; \65 r2 = r3; \66 r2 += 8; \67 r1 = *(u32*)(r1 + %[__sk_buff_data_end]); \68 if r2 > r1 goto l1_%=; \69 r1 = *(u8*)(r3 + 4); \70l1_%=: r0 = 0; \71l0_%=: exit; \72" :73 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),74 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)),75 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))76 : __clobber_all);77}78 79SEC("socket")80__description("direct packet access: test3")81__failure __msg("invalid bpf_context access off=76")82__failure_unpriv83__naked void direct_packet_access_test3(void)84{85 asm volatile (" \86 r2 = *(u32*)(r1 + %[__sk_buff_data]); \87 r0 = 0; \88 exit; \89" :90 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data))91 : __clobber_all);92}93 94SEC("tc")95__description("direct packet access: test4 (write)")96__success __retval(0)97__naked void direct_packet_access_test4_write(void)98{99 asm volatile (" \100 r2 = *(u32*)(r1 + %[__sk_buff_data]); \101 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \102 r0 = r2; \103 r0 += 8; \104 if r0 > r3 goto l0_%=; \105 *(u8*)(r2 + 0) = r2; \106l0_%=: r0 = 0; \107 exit; \108" :109 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),110 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))111 : __clobber_all);112}113 114SEC("tc")115__description("direct packet access: test5 (pkt_end >= reg, good access)")116__success __retval(0)117__naked void pkt_end_reg_good_access(void)118{119 asm volatile (" \120 r2 = *(u32*)(r1 + %[__sk_buff_data]); \121 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \122 r0 = r2; \123 r0 += 8; \124 if r3 >= r0 goto l0_%=; \125 r0 = 1; \126 exit; \127l0_%=: r0 = *(u8*)(r2 + 0); \128 r0 = 0; \129 exit; \130" :131 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),132 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))133 : __clobber_all);134}135 136SEC("tc")137__description("direct packet access: test6 (pkt_end >= reg, bad access)")138__failure __msg("invalid access to packet")139__naked void pkt_end_reg_bad_access(void)140{141 asm volatile (" \142 r2 = *(u32*)(r1 + %[__sk_buff_data]); \143 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \144 r0 = r2; \145 r0 += 8; \146 if r3 >= r0 goto l0_%=; \147 r0 = *(u8*)(r2 + 0); \148 r0 = 1; \149 exit; \150l0_%=: r0 = 0; \151 exit; \152" :153 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),154 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))155 : __clobber_all);156}157 158SEC("tc")159__description("direct packet access: test7 (pkt_end >= reg, both accesses)")160__failure __msg("invalid access to packet")161__naked void pkt_end_reg_both_accesses(void)162{163 asm volatile (" \164 r2 = *(u32*)(r1 + %[__sk_buff_data]); \165 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \166 r0 = r2; \167 r0 += 8; \168 if r3 >= r0 goto l0_%=; \169 r0 = *(u8*)(r2 + 0); \170 r0 = 1; \171 exit; \172l0_%=: r0 = *(u8*)(r2 + 0); \173 r0 = 0; \174 exit; \175" :176 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),177 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))178 : __clobber_all);179}180 181SEC("tc")182__description("direct packet access: test8 (double test, variant 1)")183__success __retval(0)184__naked void test8_double_test_variant_1(void)185{186 asm volatile (" \187 r2 = *(u32*)(r1 + %[__sk_buff_data]); \188 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \189 r0 = r2; \190 r0 += 8; \191 if r3 >= r0 goto l0_%=; \192 if r0 > r3 goto l1_%=; \193 r0 = *(u8*)(r2 + 0); \194l1_%=: r0 = 1; \195 exit; \196l0_%=: r0 = *(u8*)(r2 + 0); \197 r0 = 0; \198 exit; \199" :200 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),201 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))202 : __clobber_all);203}204 205SEC("tc")206__description("direct packet access: test9 (double test, variant 2)")207__success __retval(0)208__naked void test9_double_test_variant_2(void)209{210 asm volatile (" \211 r2 = *(u32*)(r1 + %[__sk_buff_data]); \212 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \213 r0 = r2; \214 r0 += 8; \215 if r3 >= r0 goto l0_%=; \216 r0 = 1; \217 exit; \218l0_%=: if r0 > r3 goto l1_%=; \219 r0 = *(u8*)(r2 + 0); \220l1_%=: r0 = *(u8*)(r2 + 0); \221 r0 = 0; \222 exit; \223" :224 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),225 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))226 : __clobber_all);227}228 229SEC("tc")230__description("direct packet access: test10 (write invalid)")231__failure __msg("invalid access to packet")232__naked void packet_access_test10_write_invalid(void)233{234 asm volatile (" \235 r2 = *(u32*)(r1 + %[__sk_buff_data]); \236 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \237 r0 = r2; \238 r0 += 8; \239 if r0 > r3 goto l0_%=; \240 r0 = 0; \241 exit; \242l0_%=: *(u8*)(r2 + 0) = r2; \243 r0 = 0; \244 exit; \245" :246 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),247 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))248 : __clobber_all);249}250 251SEC("tc")252__description("direct packet access: test11 (shift, good access)")253__success __retval(1)254__naked void access_test11_shift_good_access(void)255{256 asm volatile (" \257 r2 = *(u32*)(r1 + %[__sk_buff_data]); \258 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \259 r0 = r2; \260 r0 += 22; \261 if r0 > r3 goto l0_%=; \262 r3 = 144; \263 r5 = r3; \264 r5 += 23; \265 r5 >>= 3; \266 r6 = r2; \267 r6 += r5; \268 r0 = 1; \269 exit; \270l0_%=: r0 = 0; \271 exit; \272" :273 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),274 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))275 : __clobber_all);276}277 278SEC("tc")279__description("direct packet access: test12 (and, good access)")280__success __retval(1)281__naked void access_test12_and_good_access(void)282{283 asm volatile (" \284 r2 = *(u32*)(r1 + %[__sk_buff_data]); \285 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \286 r0 = r2; \287 r0 += 22; \288 if r0 > r3 goto l0_%=; \289 r3 = 144; \290 r5 = r3; \291 r5 += 23; \292 r5 &= 15; \293 r6 = r2; \294 r6 += r5; \295 r0 = 1; \296 exit; \297l0_%=: r0 = 0; \298 exit; \299" :300 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),301 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))302 : __clobber_all);303}304 305SEC("tc")306__description("direct packet access: test13 (branches, good access)")307__success __retval(1)308__naked void access_test13_branches_good_access(void)309{310 asm volatile (" \311 r2 = *(u32*)(r1 + %[__sk_buff_data]); \312 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \313 r0 = r2; \314 r0 += 22; \315 if r0 > r3 goto l0_%=; \316 r3 = *(u32*)(r1 + %[__sk_buff_mark]); \317 r4 = 1; \318 if r3 > r4 goto l1_%=; \319 r3 = 14; \320 goto l2_%=; \321l1_%=: r3 = 24; \322l2_%=: r5 = r3; \323 r5 += 23; \324 r5 &= 15; \325 r6 = r2; \326 r6 += r5; \327 r0 = 1; \328 exit; \329l0_%=: r0 = 0; \330 exit; \331" :332 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),333 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)),334 __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark))335 : __clobber_all);336}337 338SEC("tc")339__description("direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)")340__success __retval(1)341__naked void _0_const_imm_good_access(void)342{343 asm volatile (" \344 r2 = *(u32*)(r1 + %[__sk_buff_data]); \345 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \346 r0 = r2; \347 r0 += 22; \348 if r0 > r3 goto l0_%=; \349 r5 = 12; \350 r5 >>= 4; \351 r6 = r2; \352 r6 += r5; \353 r0 = *(u8*)(r6 + 0); \354 r0 = 1; \355 exit; \356l0_%=: r0 = 0; \357 exit; \358" :359 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),360 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))361 : __clobber_all);362}363 364SEC("tc")365__description("direct packet access: test15 (spill with xadd)")366__failure __msg("R2 invalid mem access 'scalar'")367__flag(BPF_F_ANY_ALIGNMENT)368__naked void access_test15_spill_with_xadd(void)369{370 asm volatile (" \371 r2 = *(u32*)(r1 + %[__sk_buff_data]); \372 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \373 r0 = r2; \374 r0 += 8; \375 if r0 > r3 goto l0_%=; \376 r5 = 4096; \377 r4 = r10; \378 r4 += -8; \379 *(u64*)(r4 + 0) = r2; \380 lock *(u64 *)(r4 + 0) += r5; \381 r2 = *(u64*)(r4 + 0); \382 *(u32*)(r2 + 0) = r5; \383 r0 = 0; \384l0_%=: exit; \385" :386 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),387 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))388 : __clobber_all);389}390 391SEC("tc")392__description("direct packet access: test16 (arith on data_end)")393__failure __msg("R3 pointer arithmetic on pkt_end")394__naked void test16_arith_on_data_end(void)395{396 asm volatile (" \397 r2 = *(u32*)(r1 + %[__sk_buff_data]); \398 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \399 r0 = r2; \400 r0 += 8; \401 r3 += 16; \402 if r0 > r3 goto l0_%=; \403 *(u8*)(r2 + 0) = r2; \404l0_%=: r0 = 0; \405 exit; \406" :407 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),408 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))409 : __clobber_all);410}411 412SEC("tc")413__description("direct packet access: test17 (pruning, alignment)")414__failure __msg("misaligned packet access off 2+0+15+-4 size 4")415__flag(BPF_F_STRICT_ALIGNMENT)416__naked void packet_access_test17_pruning_alignment(void)417{418 asm volatile (" \419 r2 = *(u32*)(r1 + %[__sk_buff_data]); \420 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \421 r7 = *(u32*)(r1 + %[__sk_buff_mark]); \422 r0 = r2; \423 r0 += 14; \424 if r7 > 1 goto l0_%=; \425l2_%=: if r0 > r3 goto l1_%=; \426 *(u32*)(r0 - 4) = r0; \427l1_%=: r0 = 0; \428 exit; \429l0_%=: r0 += 1; \430 goto l2_%=; \431" :432 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),433 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)),434 __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark))435 : __clobber_all);436}437 438SEC("tc")439__description("direct packet access: test18 (imm += pkt_ptr, 1)")440__success __retval(0)441__naked void test18_imm_pkt_ptr_1(void)442{443 asm volatile (" \444 r2 = *(u32*)(r1 + %[__sk_buff_data]); \445 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \446 r0 = 8; \447 r0 += r2; \448 if r0 > r3 goto l0_%=; \449 *(u8*)(r2 + 0) = r2; \450l0_%=: r0 = 0; \451 exit; \452" :453 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),454 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))455 : __clobber_all);456}457 458SEC("tc")459__description("direct packet access: test19 (imm += pkt_ptr, 2)")460__success __retval(0)461__naked void test19_imm_pkt_ptr_2(void)462{463 asm volatile (" \464 r2 = *(u32*)(r1 + %[__sk_buff_data]); \465 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \466 r0 = r2; \467 r0 += 8; \468 if r0 > r3 goto l0_%=; \469 r4 = 4; \470 r4 += r2; \471 *(u8*)(r4 + 0) = r4; \472l0_%=: r0 = 0; \473 exit; \474" :475 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),476 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))477 : __clobber_all);478}479 480SEC("tc")481__description("direct packet access: test20 (x += pkt_ptr, 1)")482__success __retval(0) __flag(BPF_F_ANY_ALIGNMENT)483__naked void test20_x_pkt_ptr_1(void)484{485 asm volatile (" \486 r2 = *(u32*)(r1 + %[__sk_buff_data]); \487 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \488 r0 = 0xffffffff; \489 *(u64*)(r10 - 8) = r0; \490 r0 = *(u64*)(r10 - 8); \491 r0 &= 0x7fff; \492 r4 = r0; \493 r4 += r2; \494 r5 = r4; \495 r4 += %[__imm_0]; \496 if r4 > r3 goto l0_%=; \497 *(u64*)(r5 + 0) = r4; \498l0_%=: r0 = 0; \499 exit; \500" :501 : __imm_const(__imm_0, 0x7fff - 1),502 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),503 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))504 : __clobber_all);505}506 507SEC("tc")508__description("direct packet access: test21 (x += pkt_ptr, 2)")509__success __retval(0) __flag(BPF_F_ANY_ALIGNMENT)510__naked void test21_x_pkt_ptr_2(void)511{512 asm volatile (" \513 r2 = *(u32*)(r1 + %[__sk_buff_data]); \514 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \515 r0 = r2; \516 r0 += 8; \517 if r0 > r3 goto l0_%=; \518 r4 = 0xffffffff; \519 *(u64*)(r10 - 8) = r4; \520 r4 = *(u64*)(r10 - 8); \521 r4 &= 0x7fff; \522 r4 += r2; \523 r5 = r4; \524 r4 += %[__imm_0]; \525 if r4 > r3 goto l0_%=; \526 *(u64*)(r5 + 0) = r4; \527l0_%=: r0 = 0; \528 exit; \529" :530 : __imm_const(__imm_0, 0x7fff - 1),531 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),532 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))533 : __clobber_all);534}535 536SEC("tc")537__description("direct packet access: test22 (x += pkt_ptr, 3)")538__success __retval(0) __flag(BPF_F_ANY_ALIGNMENT)539__naked void test22_x_pkt_ptr_3(void)540{541 asm volatile (" \542 r2 = *(u32*)(r1 + %[__sk_buff_data]); \543 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \544 r0 = r2; \545 r0 += 8; \546 *(u64*)(r10 - 8) = r2; \547 *(u64*)(r10 - 16) = r3; \548 r3 = *(u64*)(r10 - 16); \549 if r0 > r3 goto l0_%=; \550 r2 = *(u64*)(r10 - 8); \551 r4 = 0xffffffff; \552 lock *(u64 *)(r10 - 8) += r4; \553 r4 = *(u64*)(r10 - 8); \554 r4 >>= 49; \555 r4 += r2; \556 r0 = r4; \557 r0 += 2; \558 if r0 > r3 goto l0_%=; \559 r2 = 1; \560 *(u16*)(r4 + 0) = r2; \561l0_%=: r0 = 0; \562 exit; \563" :564 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),565 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))566 : __clobber_all);567}568 569SEC("tc")570__description("direct packet access: test23 (x += pkt_ptr, 4)")571__failure __msg("invalid access to packet, off=0 size=8, R5(id=3,off=0,r=0)")572__flag(BPF_F_ANY_ALIGNMENT)573__naked void test23_x_pkt_ptr_4(void)574{575 asm volatile (" \576 r2 = *(u32*)(r1 + %[__sk_buff_data]); \577 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \578 r0 = *(u32*)(r1 + %[__sk_buff_mark]); \579 *(u64*)(r10 - 8) = r0; \580 r0 = *(u64*)(r10 - 8); \581 r0 &= 0xffff; \582 r4 = r0; \583 r0 = 31; \584 r0 += r4; \585 r0 += r2; \586 r5 = r0; \587 r0 += %[__imm_0]; \588 if r0 > r3 goto l0_%=; \589 *(u64*)(r5 + 0) = r0; \590l0_%=: r0 = 0; \591 exit; \592" :593 : __imm_const(__imm_0, 0xffff - 1),594 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),595 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end)),596 __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark))597 : __clobber_all);598}599 600SEC("tc")601__description("direct packet access: test24 (x += pkt_ptr, 5)")602__success __retval(0) __flag(BPF_F_ANY_ALIGNMENT)603__naked void test24_x_pkt_ptr_5(void)604{605 asm volatile (" \606 r2 = *(u32*)(r1 + %[__sk_buff_data]); \607 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \608 r0 = 0xffffffff; \609 *(u64*)(r10 - 8) = r0; \610 r0 = *(u64*)(r10 - 8); \611 r0 &= 0xff; \612 r4 = r0; \613 r0 = 64; \614 r0 += r4; \615 r0 += r2; \616 r5 = r0; \617 r0 += %[__imm_0]; \618 if r0 > r3 goto l0_%=; \619 *(u64*)(r5 + 0) = r0; \620l0_%=: r0 = 0; \621 exit; \622" :623 : __imm_const(__imm_0, 0x7fff - 1),624 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),625 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))626 : __clobber_all);627}628 629SEC("tc")630__description("direct packet access: test25 (marking on <, good access)")631__success __retval(0)632__naked void test25_marking_on_good_access(void)633{634 asm volatile (" \635 r2 = *(u32*)(r1 + %[__sk_buff_data]); \636 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \637 r0 = r2; \638 r0 += 8; \639 if r0 < r3 goto l0_%=; \640l1_%=: r0 = 0; \641 exit; \642l0_%=: r0 = *(u8*)(r2 + 0); \643 goto l1_%=; \644" :645 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),646 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))647 : __clobber_all);648}649 650SEC("tc")651__description("direct packet access: test26 (marking on <, bad access)")652__failure __msg("invalid access to packet")653__naked void test26_marking_on_bad_access(void)654{655 asm volatile (" \656 r2 = *(u32*)(r1 + %[__sk_buff_data]); \657 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \658 r0 = r2; \659 r0 += 8; \660 if r0 < r3 goto l0_%=; \661 r0 = *(u8*)(r2 + 0); \662l1_%=: r0 = 0; \663 exit; \664l0_%=: goto l1_%=; \665" :666 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),667 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))668 : __clobber_all);669}670 671SEC("tc")672__description("direct packet access: test27 (marking on <=, good access)")673__success __retval(1)674__naked void test27_marking_on_good_access(void)675{676 asm volatile (" \677 r2 = *(u32*)(r1 + %[__sk_buff_data]); \678 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \679 r0 = r2; \680 r0 += 8; \681 if r3 <= r0 goto l0_%=; \682 r0 = *(u8*)(r2 + 0); \683l0_%=: r0 = 1; \684 exit; \685" :686 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),687 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))688 : __clobber_all);689}690 691SEC("tc")692__description("direct packet access: test28 (marking on <=, bad access)")693__failure __msg("invalid access to packet")694__naked void test28_marking_on_bad_access(void)695{696 asm volatile (" \697 r2 = *(u32*)(r1 + %[__sk_buff_data]); \698 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \699 r0 = r2; \700 r0 += 8; \701 if r3 <= r0 goto l0_%=; \702l1_%=: r0 = 1; \703 exit; \704l0_%=: r0 = *(u8*)(r2 + 0); \705 goto l1_%=; \706" :707 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),708 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))709 : __clobber_all);710}711 712SEC("tc")713__description("direct packet access: test29 (reg > pkt_end in subprog)")714__success __retval(0)715__naked void reg_pkt_end_in_subprog(void)716{717 asm volatile (" \718 r6 = *(u32*)(r1 + %[__sk_buff_data]); \719 r2 = *(u32*)(r1 + %[__sk_buff_data_end]); \720 r3 = r6; \721 r3 += 8; \722 call reg_pkt_end_in_subprog__1; \723 if r0 == 0 goto l0_%=; \724 r0 = *(u8*)(r6 + 0); \725l0_%=: r0 = 0; \726 exit; \727" :728 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),729 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))730 : __clobber_all);731}732 733static __naked __noinline __attribute__((used))734void reg_pkt_end_in_subprog__1(void)735{736 asm volatile (" \737 r0 = 0; \738 if r3 > r2 goto l0_%=; \739 r0 = 1; \740l0_%=: exit; \741" ::: __clobber_all);742}743 744SEC("tc")745__description("direct packet access: test30 (check_id() in regsafe(), bad access)")746__failure __msg("invalid access to packet, off=0 size=1, R2")747__flag(BPF_F_TEST_STATE_FREQ)748__naked void id_in_regsafe_bad_access(void)749{750 asm volatile (" \751 /* r9 = ctx */ \752 r9 = r1; \753 /* r7 = ktime_get_ns() */ \754 call %[bpf_ktime_get_ns]; \755 r7 = r0; \756 /* r6 = ktime_get_ns() */ \757 call %[bpf_ktime_get_ns]; \758 r6 = r0; \759 /* r2 = ctx->data \760 * r3 = ctx->data \761 * r4 = ctx->data_end \762 */ \763 r2 = *(u32*)(r9 + %[__sk_buff_data]); \764 r3 = *(u32*)(r9 + %[__sk_buff_data]); \765 r4 = *(u32*)(r9 + %[__sk_buff_data_end]); \766 /* if r6 > 100 goto exit \767 * if r7 > 100 goto exit \768 */ \769 if r6 > 100 goto l0_%=; \770 if r7 > 100 goto l0_%=; \771 /* r2 += r6 ; this forces assignment of ID to r2\772 * r2 += 1 ; get some fixed off for r2\773 * r3 += r7 ; this forces assignment of ID to r3\774 * r3 += 1 ; get some fixed off for r3\775 */ \776 r2 += r6; \777 r2 += 1; \778 r3 += r7; \779 r3 += 1; \780 /* if r6 > r7 goto +1 ; no new information about the state is derived from\781 * ; this check, thus produced verifier states differ\782 * ; only in 'insn_idx' \783 * r2 = r3 ; optionally share ID between r2 and r3\784 */ \785 if r6 != r7 goto l1_%=; \786 r2 = r3; \787l1_%=: /* if r3 > ctx->data_end goto exit */ \788 if r3 > r4 goto l0_%=; \789 /* r5 = *(u8 *) (r2 - 1) ; access packet memory using r2,\790 * ; this is not always safe\791 */ \792 r5 = *(u8*)(r2 - 1); \793l0_%=: /* exit(0) */ \794 r0 = 0; \795 exit; \796" :797 : __imm(bpf_ktime_get_ns),798 __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),799 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))800 : __clobber_all);801}802 803char _license[] SEC("license") = "GPL";804