Skip to content

Add kfunc/helper <-> program type exceptions#252

Merged
dylandreimerink merged 5 commits intomasterfrom
feature/helper-kfunc-exceptions
Feb 5, 2026
Merged

Add kfunc/helper <-> program type exceptions#252
dylandreimerink merged 5 commits intomasterfrom
feature/helper-kfunc-exceptions

Conversation

@dylandreimerink
Copy link
Collaborator

For both helper functions and kfuncs we try to model the kernels approach of which functions can be used from which program types. Usually you start with no functions allowed and gradually add more. However, the verifier can also implement logic to effectively block the usage of helpers / kfuncs for certain program types. This PR add notation to our data files so we can model this same sort of exception on top of the normal mapping and applies this to all cases defined in check_map_prog_compatibility

The helper-ref-gen tool reads a data file which models the C methods
used to implement which helpers are allowed for which program types.
However, the verifier sometimes also adds exceptions outside of this
model, directly in the verifier logic, instead of on the ops of
program type definitions. For the user this effectively means the same
but for us to model it, we have to be able to exclude certain helpers
from program types, even if a helper was included before via a group.

Signed-off-by: Dylan Reimerink <dylan.reimerink@isovalent.com>
@dylandreimerink dylandreimerink force-pushed the feature/helper-kfunc-exceptions branch from 31b81ec to 481758a Compare February 4, 2026 11:59
dylandreimerink and others added 4 commits February 4, 2026 13:00
The verifier asserts that in tracing programs (kprobe, tracepoint,
raw_tracepoint, raw_tracepoint_writable, perf_event) you cannot have
a map with `struct bpf_res_spin_lock`. When it detects such a map
exists, it raises an error as if the helpers are blocked.

This nuance can now be modeled by our tooling. So lets update the
the data file to match reality so the reference lists are accurate.

Co-authored-by: AliGhaffarian <alighaffarian9@gmail.com>
Signed-off-by: Dylan Reimerink <dylan.reimerink@isovalent.com>
The verifier has logic that excludes certain kfuncs in addition to the
normal kfunc <-> program type mapping. This change allows us to specify
these exceptions on a per-kfunc basis in the kfunc data file.

Signed-off-by: Dylan Reimerink <dylan.reimerink@isovalent.com>
The verifier applies additional restrictions on certain kfuncs
when used in combination with specific program types. This commit
adds exclusions so the reference lists are accurate.

Co-authored-by: AliGhaffarian <alighaffarian9@gmail.com>
Signed-off-by: Dylan Reimerink <dylan.reimerink@isovalent.com>
The verifier restricts the use of bpf_timer_* helper functions in
certain program types, on top of the normal program type <-> helper
function mappings. This commit adds these exceptions to
the documentation.

Signed-off-by: Dylan Reimerink <dylan.reimerink@isovalent.com>
@dylandreimerink dylandreimerink force-pushed the feature/helper-kfunc-exceptions branch from 481758a to ccb239c Compare February 4, 2026 12:00
@dylandreimerink dylandreimerink marked this pull request as ready for review February 4, 2026 12:02
@dylandreimerink
Copy link
Collaborator Author

@AliGhaffarian please check if this matches what you had in mind

* [`BPF_PROG_TYPE_SOCK_OPS`](../program-type/BPF_PROG_TYPE_SOCK_OPS.md)
* [`BPF_PROG_TYPE_STRUCT_OPS`](../program-type/BPF_PROG_TYPE_STRUCT_OPS.md)
* [`BPF_PROG_TYPE_SYSCALL`](../program-type/BPF_PROG_TYPE_SYSCALL.md)
* [`BPF_PROG_TYPE_TRACING`](../program-type/BPF_PROG_TYPE_TRACING.md)
Copy link
Contributor

@AliGhaffarian AliGhaffarian Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we exclude program types from helper functions too?
Currently, BPF_PROG_TYPE_TRACING is still in the bpf_spin_lock.md.

Or instead of having a exclude field for functions themselves, maybe can go through each helper function and for each one, check which program types have the current helper function excluded, this will remove the need to have exclusion for both program types and functions in the data file.
This approach looks something like this

for helper_function in helper_funcs:
	exclusions = []
	for prog_type in prog_types:
		if helper_function in prog_type.exclusions:
			exclusions.append(prog_type)

I can put the time to implement it, using your patches as reference. it would take some time as i'm not very familiar with golang though.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, BPF_PROG_TYPE_TRACING is still in the bpf_spin_lock.md

Yes. But oddly enough BPF_PROG_TYPE_TRACING is not considered a tracing program according to is_tracing_prog_type and so would be allowed as far as I can see? Unless there is yet another bit of logic somewhere that blocks it.

I have not yet tried using spinlocks in fentry/fexit programs yet to see what happens.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just tried it, seems like you can.

#include "vmlinux.h"
#include "bpf_helpers.h"
#include "bpf_tracing.h"

struct data
{
    int data;
    struct bpf_spin_lock lock;
};

struct
{
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 1024);
    __type(key, __u32);
    __type(value, struct data);
} test_map SEC(".maps");

SEC("fentry/security_inode_getattr")
int BPF_PROG(d_path_check_rdonly_mem, struct path *path, struct kstat *stat,
             __u32 request_mask, unsigned int query_flags)
{
    __u32 zero = 0;
    struct data *elem = bpf_map_lookup_elem(&test_map, &zero);

    if (!elem)
        return 0;

    bpf_spin_lock(&elem->lock);
    bpf_spin_unlock(&elem->lock);
    return 0;
}

char __license[] SEC("license") = "GPL";
$ sudo bpftool prog show id 17592
17592: tracing  name d_path_check_rdonly_mem  tag 7e7ebeefb37c74d9  gpl
	loaded_at 2026-02-05T10:41:41+0100  uid 0
	xlated 144B  jited 89B  memlock 4096B  map_ids 4639
	btf_id 12836

$ sudo bpftool prog dump xlated id 17592
int d_path_check_rdonly_mem(unsigned long long * ctx):
; int BPF_PROG(d_path_check_rdonly_mem, struct path *path, struct kstat *stat,
   0: (b7) r1 = 0
; __u32 zero = 0;
   1: (63) *(u32 *)(r10 -4) = r1
   2: (bf) r2 = r10
; 
   3: (07) r2 += -4
; struct data *elem = bpf_map_lookup_elem(&test_map, &zero);
   4: (18) r1 = map[id:4639]
   6: (85) call __htab_map_lookup_elem#294448
   7: (15) if r0 == 0x0 goto pc+1
   8: (07) r0 += 56
   9: (bf) r6 = r0
; if (!elem)
  10: (15) if r6 == 0x0 goto pc+5
; bpf_spin_lock(&elem->lock);
  11: (07) r6 += 4
; bpf_spin_lock(&elem->lock);
  12: (bf) r1 = r6
  13: (85) call bpf_spin_lock#253520
; bpf_spin_unlock(&elem->lock);
  14: (bf) r1 = r6
  15: (85) call bpf_spin_unlock#256064
; int BPF_PROG(d_path_check_rdonly_mem, struct path *path, struct kstat *stat,
  16: (b7) r0 = 0
  17: (95) exit
$ uname -srv
Linux 6.8.0-52-generic #53~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Jan 15 19:18:46 UTC 2

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. But oddly enough BPF_PROG_TYPE_TRACING is not considered a tracing program according to is_tracing_prog_type and so would be allowed as far as I can see

Oh, that was a misunderstanding on my part, guess they had a hard time naming things.

Copy link
Collaborator Author

@dylandreimerink dylandreimerink Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are 2 hard problems in computer science: cache invalidation, naming things, and off-by-1 errors

😄

@AliGhaffarian
Copy link
Contributor

@AliGhaffarian please check if this matches what you had in mind

My suggestion was more complex, it would need to port parts of check_map_prog_compatibility to [helper-fer/kfunc]-gen tools, your approach is more maintainable in my opinion.

@dylandreimerink dylandreimerink merged commit 6c6eacb into master Feb 5, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants