1// SPDX-License-Identifier: GPL-2.0 2/* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */ 3 4#include <linux/bpf.h> 5#include <time.h> 6#include <errno.h> 7#include <bpf/bpf_helpers.h> 8#include "bpf_misc.h" 9#include "bpf_tcp_helpers.h" 10 11char _license[] SEC("license") = "GPL"; 12 13struct elem { 14 struct bpf_timer t; 15}; 16 17struct { 18 __uint(type, BPF_MAP_TYPE_ARRAY); 19 __uint(max_entries, 1); 20 __type(key, int); 21 __type(value, struct elem); 22} timer_map SEC(".maps"); 23 24__naked __noinline __used 25static unsigned long timer_cb_ret_bad() 26{ 27 asm volatile ( 28 "call %[bpf_get_prandom_u32];" 29 "if r0 s> 1000 goto 1f;" 30 "r0 = 0;" 31 "1:" 32 "goto +0;" /* checkpoint */ 33 /* async callback is expected to return 0, so branch above 34 * skipping r0 = 0; should lead to a failure, but if exit 35 * instruction doesn't enforce r0's precision, this callback 36 * will be successfully verified 37 */ 38 "exit;" 39 : 40 : __imm(bpf_get_prandom_u32) 41 : __clobber_common 42 ); 43} 44 45SEC("fentry/bpf_fentry_test1") 46__log_level(2) 47__flag(BPF_F_TEST_STATE_FREQ) 48__failure 49/* check that fallthrough code path marks r0 as precise */ 50__msg("mark_precise: frame0: regs=r0 stack= before") 51__msg(": (85) call bpf_get_prandom_u32#7") /* anchor message */ 52/* check that branch code path marks r0 as precise */ 53__msg("mark_precise: frame0: regs=r0 stack= before ") __msg(": (85) call bpf_get_prandom_u32#7") 54__msg("should have been in [0, 0]") 55long BPF_PROG2(test_bad_ret, int, a) 56{ 57 int key = 0; 58 struct bpf_timer *timer; 59 60 timer = bpf_map_lookup_elem(&timer_map, &key); 61 if (timer) { 62 bpf_timer_init(timer, &timer_map, CLOCK_BOOTTIME); 63 bpf_timer_set_callback(timer, timer_cb_ret_bad); 64 bpf_timer_start(timer, 1000, 0); 65 } 66 67 return 0; 68} 69