bpf: don't infer PTR_TO_CTX for programs with unnamed context type
For program types that don't have named context type name (e.g., BPF
iterator programs or tracepoint programs), ctx_tname will be a non-NULL
empty string. For such programs it shouldn't be possible to have
PTR_TO_CTX argument for global subprogs based on type name alone.
arg:ctx tag is the only way to have PTR_TO_CTX passed into global
subprog for such program types.
Fix this loophole, which currently would assume PTR_TO_CTX whenever
user uses a pointer to anonymous struct as an argument to their global
subprogs. This happens in practice with the following (quite common, in
practice) approach:
typedef struct { /* anonymous */
int x;
} my_type_t;
int my_subprog(my_type_t *arg) { ... }
User's intent is to have PTR_TO_MEM argument for `arg`, but verifier
will complain about expecting PTR_TO_CTX.
This fix also closes unintended s390x-specific KPROBE handling of
PTR_TO_CTX case. Selftest change is necessary to accommodate this.
Fixes: 91cc1a9974
("bpf: Annotate context types")
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20240212233221.2575350-4-andrii@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
824c58fb10
commit
879bbe7aa4
@ -5746,6 +5746,9 @@ again:
|
||||
bpf_log(log, "Please fix kernel include/linux/bpf_types.h\n");
|
||||
return false;
|
||||
}
|
||||
/* program types without named context types work only with arg:ctx tag */
|
||||
if (ctx_tname[0] == '\0')
|
||||
return false;
|
||||
/* only compare that prog's ctx type name is the same as
|
||||
* kernel expects. No need to compare field by field.
|
||||
* It's ok for bpf prog to do:
|
||||
|
@ -26,6 +26,23 @@ int kprobe_typedef_ctx(void *ctx)
|
||||
return kprobe_typedef_ctx_subprog(ctx);
|
||||
}
|
||||
|
||||
/* s390x defines:
|
||||
*
|
||||
* typedef user_pt_regs bpf_user_pt_regs_t;
|
||||
* typedef struct { ... } user_pt_regs;
|
||||
*
|
||||
* And so "canonical" underlying struct type is anonymous.
|
||||
* So on s390x only valid ways to have PTR_TO_CTX argument in global subprogs
|
||||
* are:
|
||||
* - bpf_user_pt_regs_t *ctx (typedef);
|
||||
* - struct bpf_user_pt_regs_t *ctx (backwards compatible struct hack);
|
||||
* - void *ctx __arg_ctx (arg:ctx tag)
|
||||
*
|
||||
* Other architectures also allow using underlying struct types (e.g.,
|
||||
* `struct pt_regs *ctx` for x86-64)
|
||||
*/
|
||||
#ifndef bpf_target_s390
|
||||
|
||||
#define pt_regs_struct_t typeof(*(__PT_REGS_CAST((struct pt_regs *)NULL)))
|
||||
|
||||
__weak int kprobe_struct_ctx_subprog(pt_regs_struct_t *ctx)
|
||||
@ -40,6 +57,8 @@ int kprobe_resolved_ctx(void *ctx)
|
||||
return kprobe_struct_ctx_subprog(ctx);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* this is current hack to make this work on old kernels */
|
||||
struct bpf_user_pt_regs_t {};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user