Linux Audio

Check our new training course

Loading...
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0
  2#include <vmlinux.h>
  3#include <bpf/bpf_tracing.h>
  4#include <bpf/bpf_helpers.h>
  5#include "../bpf_testmod/bpf_testmod_kfunc.h"
  6
  7struct map_value {
  8	struct prog_test_ref_kfunc __kptr *ptr;
  9};
 10
 11struct {
 12	__uint(type, BPF_MAP_TYPE_ARRAY);
 13	__type(key, int);
 14	__type(value, struct map_value);
 15	__uint(max_entries, 16);
 16} array_map SEC(".maps");
 17
 18static __noinline int cb1(void *map, void *key, void *value, void *ctx)
 19{
 20	void *p = *(void **)ctx;
 21	bpf_kfunc_call_test_release(p);
 22	/* Without the fix this would cause underflow */
 23	return 0;
 24}
 25
 26SEC("?tc")
 27int underflow_prog(void *ctx)
 28{
 29	struct prog_test_ref_kfunc *p;
 30	unsigned long sl = 0;
 31
 32	p = bpf_kfunc_call_test_acquire(&sl);
 33	if (!p)
 34		return 0;
 35	bpf_for_each_map_elem(&array_map, cb1, &p, 0);
 36	bpf_kfunc_call_test_release(p);
 37	return 0;
 38}
 39
 40static __always_inline int cb2(void *map, void *key, void *value, void *ctx)
 41{
 42	unsigned long sl = 0;
 43
 44	*(void **)ctx = bpf_kfunc_call_test_acquire(&sl);
 45	/* Without the fix this would leak memory */
 46	return 0;
 47}
 48
 49SEC("?tc")
 50int leak_prog(void *ctx)
 51{
 52	struct prog_test_ref_kfunc *p;
 53	struct map_value *v;
 54
 55	v = bpf_map_lookup_elem(&array_map, &(int){0});
 56	if (!v)
 57		return 0;
 58
 59	p = NULL;
 60	bpf_for_each_map_elem(&array_map, cb2, &p, 0);
 61	p = bpf_kptr_xchg(&v->ptr, p);
 62	if (p)
 63		bpf_kfunc_call_test_release(p);
 64	return 0;
 65}
 66
 67static __always_inline int cb(void *map, void *key, void *value, void *ctx)
 68{
 69	return 0;
 70}
 71
 72static __always_inline int cb3(void *map, void *key, void *value, void *ctx)
 73{
 74	unsigned long sl = 0;
 75	void *p;
 76
 77	bpf_kfunc_call_test_acquire(&sl);
 78	bpf_for_each_map_elem(&array_map, cb, &p, 0);
 79	/* It should only complain here, not in cb. This is why we need
 80	 * callback_ref to be set to frameno.
 81	 */
 82	return 0;
 83}
 84
 85SEC("?tc")
 86int nested_cb(void *ctx)
 87{
 88	struct prog_test_ref_kfunc *p;
 89	unsigned long sl = 0;
 90	int sp = 0;
 91
 92	p = bpf_kfunc_call_test_acquire(&sl);
 93	if (!p)
 94		return 0;
 95	bpf_for_each_map_elem(&array_map, cb3, &sp, 0);
 96	bpf_kfunc_call_test_release(p);
 97	return 0;
 98}
 99
100SEC("?tc")
101int non_cb_transfer_ref(void *ctx)
102{
103	struct prog_test_ref_kfunc *p;
104	unsigned long sl = 0;
105
106	p = bpf_kfunc_call_test_acquire(&sl);
107	if (!p)
108		return 0;
109	cb1(NULL, NULL, NULL, &p);
110	bpf_kfunc_call_test_acquire(&sl);
111	return 0;
112}
113
114char _license[] SEC("license") = "GPL";
v6.8
  1// SPDX-License-Identifier: GPL-2.0
  2#include <vmlinux.h>
  3#include <bpf/bpf_tracing.h>
  4#include <bpf/bpf_helpers.h>
  5#include "../bpf_testmod/bpf_testmod_kfunc.h"
  6
  7struct map_value {
  8	struct prog_test_ref_kfunc __kptr *ptr;
  9};
 10
 11struct {
 12	__uint(type, BPF_MAP_TYPE_ARRAY);
 13	__type(key, int);
 14	__type(value, struct map_value);
 15	__uint(max_entries, 16);
 16} array_map SEC(".maps");
 17
 18static __noinline int cb1(void *map, void *key, void *value, void *ctx)
 19{
 20	void *p = *(void **)ctx;
 21	bpf_kfunc_call_test_release(p);
 22	/* Without the fix this would cause underflow */
 23	return 0;
 24}
 25
 26SEC("?tc")
 27int underflow_prog(void *ctx)
 28{
 29	struct prog_test_ref_kfunc *p;
 30	unsigned long sl = 0;
 31
 32	p = bpf_kfunc_call_test_acquire(&sl);
 33	if (!p)
 34		return 0;
 35	bpf_for_each_map_elem(&array_map, cb1, &p, 0);
 36	bpf_kfunc_call_test_release(p);
 37	return 0;
 38}
 39
 40static __always_inline int cb2(void *map, void *key, void *value, void *ctx)
 41{
 42	unsigned long sl = 0;
 43
 44	*(void **)ctx = bpf_kfunc_call_test_acquire(&sl);
 45	/* Without the fix this would leak memory */
 46	return 0;
 47}
 48
 49SEC("?tc")
 50int leak_prog(void *ctx)
 51{
 52	struct prog_test_ref_kfunc *p;
 53	struct map_value *v;
 54
 55	v = bpf_map_lookup_elem(&array_map, &(int){0});
 56	if (!v)
 57		return 0;
 58
 59	p = NULL;
 60	bpf_for_each_map_elem(&array_map, cb2, &p, 0);
 61	p = bpf_kptr_xchg(&v->ptr, p);
 62	if (p)
 63		bpf_kfunc_call_test_release(p);
 64	return 0;
 65}
 66
 67static __always_inline int cb(void *map, void *key, void *value, void *ctx)
 68{
 69	return 0;
 70}
 71
 72static __always_inline int cb3(void *map, void *key, void *value, void *ctx)
 73{
 74	unsigned long sl = 0;
 75	void *p;
 76
 77	bpf_kfunc_call_test_acquire(&sl);
 78	bpf_for_each_map_elem(&array_map, cb, &p, 0);
 79	/* It should only complain here, not in cb. This is why we need
 80	 * callback_ref to be set to frameno.
 81	 */
 82	return 0;
 83}
 84
 85SEC("?tc")
 86int nested_cb(void *ctx)
 87{
 88	struct prog_test_ref_kfunc *p;
 89	unsigned long sl = 0;
 90	int sp = 0;
 91
 92	p = bpf_kfunc_call_test_acquire(&sl);
 93	if (!p)
 94		return 0;
 95	bpf_for_each_map_elem(&array_map, cb3, &sp, 0);
 96	bpf_kfunc_call_test_release(p);
 97	return 0;
 98}
 99
100SEC("?tc")
101int non_cb_transfer_ref(void *ctx)
102{
103	struct prog_test_ref_kfunc *p;
104	unsigned long sl = 0;
105
106	p = bpf_kfunc_call_test_acquire(&sl);
107	if (!p)
108		return 0;
109	cb1(NULL, NULL, NULL, &p);
110	bpf_kfunc_call_test_acquire(&sl);
111	return 0;
112}
113
114char _license[] SEC("license") = "GPL";