On Mon, Apr 6, 2026 at 8:14 PM Yafang Shao <[email protected]> wrote:
[...]
> > We can define the struct_ops in an OOT kernel module. Then we
> > can attach BPF programs to the struct_ops. We may need
> > livepatch to connect the new struct_ops to original kernel logic.
> >
> > I think kernel side of this solution is mostly available, but we may
> > need some work on the toolchain side.
> >
> > Does this make sense?
>
> Are there actual benefits to using struct_ops instead of
> bpf_override_return? So far, I’ve only found it adds complexity
> without much gain.
Yes, struct_ops can be more powerful. For example, we can use
something like the following to modify the content of /proc/cmdline
with a bpf program. AFAICT, this is not possible with
bpf_override_return.
Note that this example doesn't require kernel changes. This is
actually a fun example. I will send the full code as a new self test.
Thanks,
Song
======= key logic of the livepatch module =======
static int livepatch_cmdline_proc_show(struct seq_file *m, void *v)
{
struct klp_bpf_cmdline_ops *ops = READ_ONCE(active_ops);
if (ops && ops->set_cmdline)
return ops->set_cmdline(m);
seq_printf(m, "%s: no struct_ops attached\n", THIS_MODULE->name);
return 0;
}
static struct klp_func funcs[] = {
{
.old_name = "cmdline_proc_show",
.new_func = livepatch_cmdline_proc_show,
}, { }
};
========== key logic of the bpf program =========
SEC("struct_ops/set_cmdline")
int BPF_PROG(set_cmdline, struct seq_file *m)
{
char custom[] = "klp_bpf: custom cmdline\n";
bpf_klp_seq_write(m, custom, sizeof(custom) - 1);
return 0;
}
SEC(".struct_ops.link")
struct klp_bpf_cmdline_ops cmdline_ops = {
.set_cmdline = (void *)set_cmdline,
};