xref: /linux/tools/testing/selftests/bpf/progs/test_ringbuf_overwrite.c (revision 6dfafbd0299a60bfb5d5e277fdf100037c7ded07)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2025. Huawei Technologies Co., Ltd */
3 
4 #include <linux/bpf.h>
5 #include <bpf/bpf_helpers.h>
6 #include "bpf_misc.h"
7 
8 char _license[] SEC("license") = "GPL";
9 
10 struct {
11 	__uint(type, BPF_MAP_TYPE_RINGBUF);
12 	__uint(map_flags, BPF_F_RB_OVERWRITE);
13 } ringbuf SEC(".maps");
14 
15 int pid;
16 
17 const volatile unsigned long LEN1;
18 const volatile unsigned long LEN2;
19 const volatile unsigned long LEN3;
20 const volatile unsigned long LEN4;
21 const volatile unsigned long LEN5;
22 
23 long reserve1_fail = 0;
24 long reserve2_fail = 0;
25 long reserve3_fail = 0;
26 long reserve4_fail = 0;
27 long reserve5_fail = 0;
28 
29 unsigned long avail_data = 0;
30 unsigned long ring_size = 0;
31 unsigned long cons_pos = 0;
32 unsigned long prod_pos = 0;
33 unsigned long over_pos = 0;
34 
35 SEC("fentry/" SYS_PREFIX "sys_getpgid")
36 int test_overwrite_ringbuf(void *ctx)
37 {
38 	char *rec1, *rec2, *rec3, *rec4, *rec5;
39 	int cur_pid = bpf_get_current_pid_tgid() >> 32;
40 
41 	if (cur_pid != pid)
42 		return 0;
43 
44 	rec1 = bpf_ringbuf_reserve(&ringbuf, LEN1, 0);
45 	if (!rec1) {
46 		reserve1_fail = 1;
47 		return 0;
48 	}
49 
50 	rec2 = bpf_ringbuf_reserve(&ringbuf, LEN2, 0);
51 	if (!rec2) {
52 		bpf_ringbuf_discard(rec1, 0);
53 		reserve2_fail = 1;
54 		return 0;
55 	}
56 
57 	rec3 = bpf_ringbuf_reserve(&ringbuf, LEN3, 0);
58 	/* expect failure */
59 	if (!rec3) {
60 		reserve3_fail = 1;
61 	} else {
62 		bpf_ringbuf_discard(rec1, 0);
63 		bpf_ringbuf_discard(rec2, 0);
64 		bpf_ringbuf_discard(rec3, 0);
65 		return 0;
66 	}
67 
68 	rec4 = bpf_ringbuf_reserve(&ringbuf, LEN4, 0);
69 	if (!rec4) {
70 		reserve4_fail = 1;
71 		bpf_ringbuf_discard(rec1, 0);
72 		bpf_ringbuf_discard(rec2, 0);
73 		return 0;
74 	}
75 
76 	bpf_ringbuf_submit(rec1, 0);
77 	bpf_ringbuf_submit(rec2, 0);
78 	bpf_ringbuf_submit(rec4, 0);
79 
80 	rec5 = bpf_ringbuf_reserve(&ringbuf, LEN5, 0);
81 	if (!rec5) {
82 		reserve5_fail = 1;
83 		return 0;
84 	}
85 
86 	for (int i = 0; i < LEN3; i++)
87 		rec5[i] = 0xdd;
88 
89 	bpf_ringbuf_submit(rec5, 0);
90 
91 	ring_size = bpf_ringbuf_query(&ringbuf, BPF_RB_RING_SIZE);
92 	avail_data = bpf_ringbuf_query(&ringbuf, BPF_RB_AVAIL_DATA);
93 	cons_pos = bpf_ringbuf_query(&ringbuf, BPF_RB_CONS_POS);
94 	prod_pos = bpf_ringbuf_query(&ringbuf, BPF_RB_PROD_POS);
95 	over_pos = bpf_ringbuf_query(&ringbuf, BPF_RB_OVERWRITE_POS);
96 
97 	return 0;
98 }
99