555 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Converted from tools/testing/selftests/bpf/verifier/bounds_mix_sign_unsign.c */3 4#include <linux/bpf.h>5#include <bpf/bpf_helpers.h>6#include "bpf_misc.h"7 8struct {9 __uint(type, BPF_MAP_TYPE_HASH);10 __uint(max_entries, 1);11 __type(key, long long);12 __type(value, long long);13} map_hash_8b SEC(".maps");14 15SEC("socket")16__description("bounds checks mixing signed and unsigned, positive bounds")17__failure __msg("unbounded min value")18__failure_unpriv19__naked void signed_and_unsigned_positive_bounds(void)20{21 asm volatile (" \22 call %[bpf_ktime_get_ns]; \23 *(u64*)(r10 - 16) = r0; \24 r1 = 0; \25 *(u64*)(r10 - 8) = r1; \26 r2 = r10; \27 r2 += -8; \28 r1 = %[map_hash_8b] ll; \29 call %[bpf_map_lookup_elem]; \30 if r0 == 0 goto l0_%=; \31 r1 = *(u64*)(r10 - 16); \32 r2 = 2; \33 if r2 >= r1 goto l0_%=; \34 if r1 s> 4 goto l0_%=; \35 r0 += r1; \36 r1 = 0; \37 *(u8*)(r0 + 0) = r1; \38l0_%=: r0 = 0; \39 exit; \40" :41 : __imm(bpf_ktime_get_ns),42 __imm(bpf_map_lookup_elem),43 __imm_addr(map_hash_8b)44 : __clobber_all);45}46 47SEC("socket")48__description("bounds checks mixing signed and unsigned")49__failure __msg("unbounded min value")50__failure_unpriv51__naked void checks_mixing_signed_and_unsigned(void)52{53 asm volatile (" \54 call %[bpf_ktime_get_ns]; \55 *(u64*)(r10 - 16) = r0; \56 r1 = 0; \57 *(u64*)(r10 - 8) = r1; \58 r2 = r10; \59 r2 += -8; \60 r1 = %[map_hash_8b] ll; \61 call %[bpf_map_lookup_elem]; \62 if r0 == 0 goto l0_%=; \63 r1 = *(u64*)(r10 - 16); \64 r2 = -1; \65 if r1 > r2 goto l0_%=; \66 if r1 s> 1 goto l0_%=; \67 r0 += r1; \68 r1 = 0; \69 *(u8*)(r0 + 0) = r1; \70l0_%=: r0 = 0; \71 exit; \72" :73 : __imm(bpf_ktime_get_ns),74 __imm(bpf_map_lookup_elem),75 __imm_addr(map_hash_8b)76 : __clobber_all);77}78 79SEC("socket")80__description("bounds checks mixing signed and unsigned, variant 2")81__failure __msg("unbounded min value")82__failure_unpriv83__naked void signed_and_unsigned_variant_2(void)84{85 asm volatile (" \86 call %[bpf_ktime_get_ns]; \87 *(u64*)(r10 - 16) = r0; \88 r1 = 0; \89 *(u64*)(r10 - 8) = r1; \90 r2 = r10; \91 r2 += -8; \92 r1 = %[map_hash_8b] ll; \93 call %[bpf_map_lookup_elem]; \94 if r0 == 0 goto l0_%=; \95 r1 = *(u64*)(r10 - 16); \96 r2 = -1; \97 if r1 > r2 goto l0_%=; \98 r8 = 0; \99 r8 += r1; \100 if r8 s> 1 goto l0_%=; \101 r0 += r8; \102 r0 = 0; \103 *(u8*)(r8 + 0) = r0; \104l0_%=: r0 = 0; \105 exit; \106" :107 : __imm(bpf_ktime_get_ns),108 __imm(bpf_map_lookup_elem),109 __imm_addr(map_hash_8b)110 : __clobber_all);111}112 113SEC("socket")114__description("bounds checks mixing signed and unsigned, variant 3")115__failure __msg("unbounded min value")116__failure_unpriv117__naked void signed_and_unsigned_variant_3(void)118{119 asm volatile (" \120 call %[bpf_ktime_get_ns]; \121 *(u64*)(r10 - 16) = r0; \122 r1 = 0; \123 *(u64*)(r10 - 8) = r1; \124 r2 = r10; \125 r2 += -8; \126 r1 = %[map_hash_8b] ll; \127 call %[bpf_map_lookup_elem]; \128 if r0 == 0 goto l0_%=; \129 r1 = *(u64*)(r10 - 16); \130 r2 = -1; \131 if r1 > r2 goto l0_%=; \132 r8 = r1; \133 if r8 s> 1 goto l0_%=; \134 r0 += r8; \135 r0 = 0; \136 *(u8*)(r8 + 0) = r0; \137l0_%=: r0 = 0; \138 exit; \139" :140 : __imm(bpf_ktime_get_ns),141 __imm(bpf_map_lookup_elem),142 __imm_addr(map_hash_8b)143 : __clobber_all);144}145 146SEC("socket")147__description("bounds checks mixing signed and unsigned, variant 4")148__success __success_unpriv __retval(0)149__naked void signed_and_unsigned_variant_4(void)150{151 asm volatile (" \152 call %[bpf_ktime_get_ns]; \153 *(u64*)(r10 - 16) = r0; \154 r1 = 0; \155 *(u64*)(r10 - 8) = r1; \156 r2 = r10; \157 r2 += -8; \158 r1 = %[map_hash_8b] ll; \159 call %[bpf_map_lookup_elem]; \160 if r0 == 0 goto l0_%=; \161 r1 = *(u64*)(r10 - 16); \162 r2 = 1; \163 r1 &= r2; \164 if r1 s> 1 goto l0_%=; \165 r0 += r1; \166 r1 = 0; \167 *(u8*)(r0 + 0) = r1; \168l0_%=: r0 = 0; \169 exit; \170" :171 : __imm(bpf_ktime_get_ns),172 __imm(bpf_map_lookup_elem),173 __imm_addr(map_hash_8b)174 : __clobber_all);175}176 177SEC("socket")178__description("bounds checks mixing signed and unsigned, variant 5")179__failure __msg("unbounded min value")180__failure_unpriv181__naked void signed_and_unsigned_variant_5(void)182{183 asm volatile (" \184 call %[bpf_ktime_get_ns]; \185 *(u64*)(r10 - 16) = r0; \186 r1 = 0; \187 *(u64*)(r10 - 8) = r1; \188 r2 = r10; \189 r2 += -8; \190 r1 = %[map_hash_8b] ll; \191 call %[bpf_map_lookup_elem]; \192 if r0 == 0 goto l0_%=; \193 r1 = *(u64*)(r10 - 16); \194 r2 = -1; \195 if r1 > r2 goto l0_%=; \196 if r1 s> 1 goto l0_%=; \197 r0 += 4; \198 r0 -= r1; \199 r1 = 0; \200 *(u8*)(r0 + 0) = r1; \201 r0 = 0; \202l0_%=: exit; \203" :204 : __imm(bpf_ktime_get_ns),205 __imm(bpf_map_lookup_elem),206 __imm_addr(map_hash_8b)207 : __clobber_all);208}209 210SEC("socket")211__description("bounds checks mixing signed and unsigned, variant 6")212__failure __msg("R4 min value is negative, either use unsigned")213__failure_unpriv214__naked void signed_and_unsigned_variant_6(void)215{216 asm volatile (" \217 r9 = r1; \218 call %[bpf_ktime_get_ns]; \219 *(u64*)(r10 - 16) = r0; \220 r1 = r9; \221 r2 = 0; \222 r3 = r10; \223 r3 += -512; \224 r4 = *(u64*)(r10 - 16); \225 r6 = -1; \226 if r4 > r6 goto l0_%=; \227 if r4 s> 1 goto l0_%=; \228 r4 += 1; \229 r5 = 0; \230 r6 = 0; \231 *(u16*)(r10 - 512) = r6; \232 call %[bpf_skb_load_bytes]; \233l0_%=: r0 = 0; \234 exit; \235" :236 : __imm(bpf_ktime_get_ns),237 __imm(bpf_skb_load_bytes)238 : __clobber_all);239}240 241SEC("socket")242__description("bounds checks mixing signed and unsigned, variant 7")243__success __success_unpriv __retval(0)244__naked void signed_and_unsigned_variant_7(void)245{246 asm volatile (" \247 call %[bpf_ktime_get_ns]; \248 *(u64*)(r10 - 16) = r0; \249 r1 = 0; \250 *(u64*)(r10 - 8) = r1; \251 r2 = r10; \252 r2 += -8; \253 r1 = %[map_hash_8b] ll; \254 call %[bpf_map_lookup_elem]; \255 if r0 == 0 goto l0_%=; \256 r1 = *(u64*)(r10 - 16); \257 r2 = %[__imm_0]; \258 if r1 > r2 goto l0_%=; \259 if r1 s> 1 goto l0_%=; \260 r0 += r1; \261 r1 = 0; \262 *(u8*)(r0 + 0) = r1; \263l0_%=: r0 = 0; \264 exit; \265" :266 : __imm(bpf_ktime_get_ns),267 __imm(bpf_map_lookup_elem),268 __imm_addr(map_hash_8b),269 __imm_const(__imm_0, 1024 * 1024 * 1024)270 : __clobber_all);271}272 273SEC("socket")274__description("bounds checks mixing signed and unsigned, variant 8")275__failure __msg("unbounded min value")276__failure_unpriv277__naked void signed_and_unsigned_variant_8(void)278{279 asm volatile (" \280 call %[bpf_ktime_get_ns]; \281 *(u64*)(r10 - 16) = r0; \282 r1 = 0; \283 *(u64*)(r10 - 8) = r1; \284 r2 = r10; \285 r2 += -8; \286 r1 = %[map_hash_8b] ll; \287 call %[bpf_map_lookup_elem]; \288 if r0 == 0 goto l0_%=; \289 r1 = *(u64*)(r10 - 16); \290 r2 = -1; \291 if r2 > r1 goto l1_%=; \292 r0 = 0; \293 exit; \294l1_%=: if r1 s> 1 goto l0_%=; \295 r0 += r1; \296 r1 = 0; \297 *(u8*)(r0 + 0) = r1; \298l0_%=: r0 = 0; \299 exit; \300" :301 : __imm(bpf_ktime_get_ns),302 __imm(bpf_map_lookup_elem),303 __imm_addr(map_hash_8b)304 : __clobber_all);305}306 307SEC("socket")308__description("bounds checks mixing signed and unsigned, variant 9")309__success __success_unpriv __retval(0)310__naked void signed_and_unsigned_variant_9(void)311{312 asm volatile (" \313 call %[bpf_ktime_get_ns]; \314 *(u64*)(r10 - 16) = r0; \315 r1 = 0; \316 *(u64*)(r10 - 8) = r1; \317 r2 = r10; \318 r2 += -8; \319 r1 = %[map_hash_8b] ll; \320 call %[bpf_map_lookup_elem]; \321 if r0 == 0 goto l0_%=; \322 r1 = *(u64*)(r10 - 16); \323 r2 = -9223372036854775808ULL ll; \324 if r2 > r1 goto l1_%=; \325 r0 = 0; \326 exit; \327l1_%=: if r1 s> 1 goto l0_%=; \328 r0 += r1; \329 r1 = 0; \330 *(u8*)(r0 + 0) = r1; \331l0_%=: r0 = 0; \332 exit; \333" :334 : __imm(bpf_ktime_get_ns),335 __imm(bpf_map_lookup_elem),336 __imm_addr(map_hash_8b)337 : __clobber_all);338}339 340SEC("socket")341__description("bounds checks mixing signed and unsigned, variant 10")342__failure __msg("unbounded min value")343__failure_unpriv344__naked void signed_and_unsigned_variant_10(void)345{346 asm volatile (" \347 call %[bpf_ktime_get_ns]; \348 *(u64*)(r10 - 16) = r0; \349 r1 = 0; \350 *(u64*)(r10 - 8) = r1; \351 r2 = r10; \352 r2 += -8; \353 r1 = %[map_hash_8b] ll; \354 call %[bpf_map_lookup_elem]; \355 if r0 == 0 goto l0_%=; \356 r1 = *(u64*)(r10 - 16); \357 r2 = -1; \358 if r2 > r1 goto l1_%=; \359 r0 = 0; \360 exit; \361l1_%=: if r1 s> 1 goto l0_%=; \362 r0 += r1; \363 r1 = 0; \364 *(u8*)(r0 + 0) = r1; \365l0_%=: r0 = 0; \366 exit; \367" :368 : __imm(bpf_ktime_get_ns),369 __imm(bpf_map_lookup_elem),370 __imm_addr(map_hash_8b)371 : __clobber_all);372}373 374SEC("socket")375__description("bounds checks mixing signed and unsigned, variant 11")376__failure __msg("unbounded min value")377__failure_unpriv378__naked void signed_and_unsigned_variant_11(void)379{380 asm volatile (" \381 call %[bpf_ktime_get_ns]; \382 *(u64*)(r10 - 16) = r0; \383 r1 = 0; \384 *(u64*)(r10 - 8) = r1; \385 r2 = r10; \386 r2 += -8; \387 r1 = %[map_hash_8b] ll; \388 call %[bpf_map_lookup_elem]; \389 if r0 == 0 goto l0_%=; \390 r1 = *(u64*)(r10 - 16); \391 r2 = -1; \392 if r2 >= r1 goto l1_%=; \393 /* Dead branch. */ \394 r0 = 0; \395 exit; \396l1_%=: if r1 s> 1 goto l0_%=; \397 r0 += r1; \398 r1 = 0; \399 *(u8*)(r0 + 0) = r1; \400l0_%=: r0 = 0; \401 exit; \402" :403 : __imm(bpf_ktime_get_ns),404 __imm(bpf_map_lookup_elem),405 __imm_addr(map_hash_8b)406 : __clobber_all);407}408 409SEC("socket")410__description("bounds checks mixing signed and unsigned, variant 12")411__failure __msg("unbounded min value")412__failure_unpriv413__naked void signed_and_unsigned_variant_12(void)414{415 asm volatile (" \416 call %[bpf_ktime_get_ns]; \417 *(u64*)(r10 - 16) = r0; \418 r1 = 0; \419 *(u64*)(r10 - 8) = r1; \420 r2 = r10; \421 r2 += -8; \422 r1 = %[map_hash_8b] ll; \423 call %[bpf_map_lookup_elem]; \424 if r0 == 0 goto l0_%=; \425 r1 = *(u64*)(r10 - 16); \426 r2 = -6; \427 if r2 >= r1 goto l1_%=; \428 r0 = 0; \429 exit; \430l1_%=: if r1 s> 1 goto l0_%=; \431 r0 += r1; \432 r1 = 0; \433 *(u8*)(r0 + 0) = r1; \434l0_%=: r0 = 0; \435 exit; \436" :437 : __imm(bpf_ktime_get_ns),438 __imm(bpf_map_lookup_elem),439 __imm_addr(map_hash_8b)440 : __clobber_all);441}442 443SEC("socket")444__description("bounds checks mixing signed and unsigned, variant 13")445__failure __msg("unbounded min value")446__failure_unpriv447__naked void signed_and_unsigned_variant_13(void)448{449 asm volatile (" \450 call %[bpf_ktime_get_ns]; \451 *(u64*)(r10 - 16) = r0; \452 r1 = 0; \453 *(u64*)(r10 - 8) = r1; \454 r2 = r10; \455 r2 += -8; \456 r1 = %[map_hash_8b] ll; \457 call %[bpf_map_lookup_elem]; \458 if r0 == 0 goto l0_%=; \459 r1 = *(u64*)(r10 - 16); \460 r2 = 2; \461 if r2 >= r1 goto l0_%=; \462 r7 = 1; \463 if r7 s> 0 goto l1_%=; \464l0_%=: r0 = 0; \465 exit; \466l1_%=: r7 += r1; \467 if r7 s> 4 goto l2_%=; \468 r0 += r7; \469 r1 = 0; \470 *(u8*)(r0 + 0) = r1; \471l2_%=: r0 = 0; \472 exit; \473" :474 : __imm(bpf_ktime_get_ns),475 __imm(bpf_map_lookup_elem),476 __imm_addr(map_hash_8b)477 : __clobber_all);478}479 480SEC("socket")481__description("bounds checks mixing signed and unsigned, variant 14")482__failure __msg("unbounded min value")483__failure_unpriv484__naked void signed_and_unsigned_variant_14(void)485{486 asm volatile (" \487 r9 = *(u32*)(r1 + %[__sk_buff_mark]); \488 call %[bpf_ktime_get_ns]; \489 *(u64*)(r10 - 16) = r0; \490 r1 = 0; \491 *(u64*)(r10 - 8) = r1; \492 r2 = r10; \493 r2 += -8; \494 r1 = %[map_hash_8b] ll; \495 call %[bpf_map_lookup_elem]; \496 if r0 == 0 goto l0_%=; \497 r1 = *(u64*)(r10 - 16); \498 r2 = -1; \499 r8 = 2; \500 if r9 == 42 goto l1_%=; \501 if r8 s> r1 goto l2_%=; \502l3_%=: if r1 s> 1 goto l2_%=; \503 r0 += r1; \504l0_%=: r1 = 0; \505 *(u8*)(r0 + 0) = r1; \506l2_%=: r0 = 0; \507 exit; \508l1_%=: if r1 > r2 goto l2_%=; \509 goto l3_%=; \510" :511 : __imm(bpf_ktime_get_ns),512 __imm(bpf_map_lookup_elem),513 __imm_addr(map_hash_8b),514 __imm_const(__sk_buff_mark, offsetof(struct __sk_buff, mark))515 : __clobber_all);516}517 518SEC("socket")519__description("bounds checks mixing signed and unsigned, variant 15")520__failure __msg("unbounded min value")521__failure_unpriv522__naked void signed_and_unsigned_variant_15(void)523{524 asm volatile (" \525 call %[bpf_ktime_get_ns]; \526 *(u64*)(r10 - 16) = r0; \527 r1 = 0; \528 *(u64*)(r10 - 8) = r1; \529 r2 = r10; \530 r2 += -8; \531 r1 = %[map_hash_8b] ll; \532 call %[bpf_map_lookup_elem]; \533 if r0 == 0 goto l0_%=; \534 r1 = *(u64*)(r10 - 16); \535 r2 = -6; \536 if r2 >= r1 goto l1_%=; \537l0_%=: r0 = 0; \538 exit; \539l1_%=: r0 += r1; \540 if r0 > 1 goto l2_%=; \541 r0 = 0; \542 exit; \543l2_%=: r1 = 0; \544 *(u8*)(r0 + 0) = r1; \545 r0 = 0; \546 exit; \547" :548 : __imm(bpf_ktime_get_ns),549 __imm(bpf_map_lookup_elem),550 __imm_addr(map_hash_8b)551 : __clobber_all);552}553 554char _license[] SEC("license") = "GPL";555