diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 6ba9d3ed8f0b0313eb32353faac7620524f766be..95459e959472b08a71399f9025e2c9c2f320a4f6 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -2053,14 +2053,17 @@ static inline bool bpf_allow_uninit_stack(void) return perfmon_capable(); } +extern int bpf_spec_v1; +extern int bpf_spec_v4; + static inline bool bpf_bypass_spec_v1(void) { - return perfmon_capable(); + return !(bpf_spec_v1 == 2 || !perfmon_capable()); } static inline bool bpf_bypass_spec_v4(void) { - return perfmon_capable(); + return !(bpf_spec_v4 == 2 || !perfmon_capable()); } int bpf_map_new_fd(struct bpf_map *map, int flags); diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 1480b6cf12f060d2309c0c3fa5a24f3e56baa7f3..c8ce04d942be18ae78a40b7b06659ff44f39c08b 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -58,6 +58,9 @@ static DEFINE_SPINLOCK(link_idr_lock); int sysctl_unprivileged_bpf_disabled __read_mostly = IS_BUILTIN(CONFIG_BPF_UNPRIV_DEFAULT_OFF) ? 2 : 0; +int bpf_spec_v1 = 0; +int bpf_spec_v4 = 0; + static const struct bpf_map_ops * const bpf_map_types[] = { #define BPF_PROG_TYPE(_id, _name, prog_ctx_type, kern_ctx_type) #define BPF_MAP_TYPE(_id, _ops) \ @@ -5481,7 +5484,25 @@ static struct ctl_table bpf_syscall_table[] = { .mode = 0644, .proc_handler = bpf_stats_handler, }, - { } + { + .procname = "bpf_spec_v1", + .data = &bpf_spec_v1, + .maxlen = sizeof(bpf_spec_v1), + .mode = 0644, + .proc_handler = proc_dointvec, /* TODO: minmax with the following causes kernel panic */ + /* .extra1 = SYSCTL_ZERO, */ + /* .extra2 = SYSCTL_ONE, */ + }, + { + .procname = "bpf_spec_v4", + .data = &bpf_spec_v4, + .maxlen = sizeof(bpf_spec_v4), + .mode = 0644, + .proc_handler = proc_dointvec, /* TODO */ + /* .extra1 = SYSCTL_ZERO, */ + /* .extra2 = SYSCTL_ONE, */ + }, + {} }; static int __init bpf_syscall_sysctl_init(void) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 104681258d24f1d93e366902d787b17c7f3102a4..f50d3837914d605630fe317c796b753c96405b78 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -19467,6 +19467,8 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3 env->allow_uninit_stack = bpf_allow_uninit_stack(); env->bypass_spec_v1 = bpf_bypass_spec_v1(); env->bypass_spec_v4 = bpf_bypass_spec_v4(); + verbose(env, "bypass_spec_v1 = %d; bypass_spec_v4 = %d\n", + env->bypass_spec_v1, env->bypass_spec_v4); env->bpf_capable = bpf_capable(); if (is_priv)