Message ID | 20250108225140.3467654-6-song@kernel.org (mailing list archive) |
---|---|
State | Handled Elsewhere |
Delegated to: | Paul Moore |
Headers | show |
Series | Enable writing xattr from BPF programs | expand |
Hi Song, kernel test robot noticed the following build errors: [auto build test ERROR on bpf-next/master] url: https://github.com/intel-lab-lkp/linux/commits/Song-Liu/fs-xattr-bpf-Introduce-security-bpf-xattr-name-prefix/20250109-065503 base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master patch link: https://lore.kernel.org/r/20250108225140.3467654-6-song%40kernel.org patch subject: [PATCH v8 bpf-next 5/7] bpf: Use btf_kfunc_id_set.remap logic for bpf_dynptr_from_skb config: i386-buildonly-randconfig-005-20250110 (https://download.01.org/0day-ci/archive/20250110/202501100757.HDb5slrv-lkp@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250110/202501100757.HDb5slrv-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202501100757.HDb5slrv-lkp@intel.com/ All error/warnings (new ones prefixed by >>): >> net/core/filter.c:12071:1: error: return type defaults to 'int' [-Werror=implicit-int] 12071 | BTF_HIDDEN_KFUNCS_START(bpf_kfunc_check_hidden_set_skb) | ^~~~~~~~~~~~~~~~~~~~~~~ >> net/core/filter.c:12071:1: error: function declaration isn't a prototype [-Werror=strict-prototypes] In file included from include/linux/btf.h:10, from include/linux/bpf.h:28, from include/linux/bpf_verifier.h:7, from net/core/filter.c:21: net/core/filter.c: In function 'BTF_HIDDEN_KFUNCS_START': >> net/core/filter.c:12075:18: error: storage class specified for parameter 'bpf_kfunc_check_set_xdp' 12075 | BTF_KFUNCS_START(bpf_kfunc_check_set_xdp) | ^~~~~~~~~~~~~~~~~~~~~~~ include/linux/btf_ids.h:235:73: note: in definition of macro 'BTF_KFUNCS_START' 235 | #define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS }; | ^~~~ >> include/linux/btf_ids.h:235:46: error: parameter 'bpf_kfunc_check_set_xdp' is initialized 235 | #define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS }; | ^~~~~~~~~~~ net/core/filter.c:12075:1: note: in expansion of macro 'BTF_KFUNCS_START' 12075 | BTF_KFUNCS_START(bpf_kfunc_check_set_xdp) | ^~~~~~~~~~~~~~~~ >> net/core/filter.c:12079:18: error: storage class specified for parameter 'bpf_kfunc_check_set_sock_addr' 12079 | BTF_KFUNCS_START(bpf_kfunc_check_set_sock_addr) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/btf_ids.h:235:73: note: in definition of macro 'BTF_KFUNCS_START' 235 | #define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS }; | ^~~~ >> include/linux/btf_ids.h:235:46: error: parameter 'bpf_kfunc_check_set_sock_addr' is initialized 235 | #define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS }; | ^~~~~~~~~~~ net/core/filter.c:12079:1: note: in expansion of macro 'BTF_KFUNCS_START' 12079 | BTF_KFUNCS_START(bpf_kfunc_check_set_sock_addr) | ^~~~~~~~~~~~~~~~ >> net/core/filter.c:12083:18: error: storage class specified for parameter 'bpf_kfunc_check_set_tcp_reqsk' 12083 | BTF_KFUNCS_START(bpf_kfunc_check_set_tcp_reqsk) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/btf_ids.h:235:73: note: in definition of macro 'BTF_KFUNCS_START' 235 | #define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS }; | ^~~~ >> include/linux/btf_ids.h:235:46: error: parameter 'bpf_kfunc_check_set_tcp_reqsk' is initialized 235 | #define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS }; | ^~~~~~~~~~~ net/core/filter.c:12083:1: note: in expansion of macro 'BTF_KFUNCS_START' 12083 | BTF_KFUNCS_START(bpf_kfunc_check_set_tcp_reqsk) | ^~~~~~~~~~~~~~~~ >> net/core/filter.c:12087:13: error: storage class specified for parameter 'bpf_dynptr_from_skb_list' 12087 | BTF_ID_LIST(bpf_dynptr_from_skb_list) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/btf_ids.h:223:53: note: in definition of macro 'BTF_ID_LIST' 223 | #define BTF_ID_LIST(name) static u32 __maybe_unused name[64]; | ^~~~ >> net/core/filter.c:12092:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token 12092 | { | ^ >> net/core/filter.c:12122:38: error: storage class specified for parameter 'bpf_kfunc_set_skb' 12122 | static const struct btf_kfunc_id_set bpf_kfunc_set_skb = { | ^~~~~~~~~~~~~~~~~ >> net/core/filter.c:12122:21: error: parameter 'bpf_kfunc_set_skb' is initialized 12122 | static const struct btf_kfunc_id_set bpf_kfunc_set_skb = { | ^~~~~~~~~~~~~~~~ >> net/core/filter.c:12125:24: error: 'bpf_kfunc_check_hidden_set_skb' undeclared (first use in this function); did you mean 'bpf_kfunc_check_set_skb'? 12125 | .hidden_set = &bpf_kfunc_check_hidden_set_skb, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | bpf_kfunc_check_set_skb net/core/filter.c:12125:24: note: each undeclared identifier is reported only once for each function it appears in >> net/core/filter.c:12126:19: error: 'bpf_kfunc_set_skb_remap' undeclared (first use in this function); did you mean 'bpf_kfunc_set_skb'? 12126 | .remap = &bpf_kfunc_set_skb_remap, | ^~~~~~~~~~~~~~~~~~~~~~~ | bpf_kfunc_set_skb >> net/core/filter.c:12129:38: error: storage class specified for parameter 'bpf_kfunc_set_xdp' 12129 | static const struct btf_kfunc_id_set bpf_kfunc_set_xdp = { | ^~~~~~~~~~~~~~~~~ >> net/core/filter.c:12129:21: error: parameter 'bpf_kfunc_set_xdp' is initialized 12129 | static const struct btf_kfunc_id_set bpf_kfunc_set_xdp = { | ^~~~~~~~~~~~~~~~ >> net/core/filter.c:12134:38: error: storage class specified for parameter 'bpf_kfunc_set_sock_addr' 12134 | static const struct btf_kfunc_id_set bpf_kfunc_set_sock_addr = { | ^~~~~~~~~~~~~~~~~~~~~~~ >> net/core/filter.c:12134:21: error: parameter 'bpf_kfunc_set_sock_addr' is initialized 12134 | static const struct btf_kfunc_id_set bpf_kfunc_set_sock_addr = { | ^~~~~~~~~~~~~~~~ >> net/core/filter.c:12139:38: error: storage class specified for parameter 'bpf_kfunc_set_tcp_reqsk' 12139 | static const struct btf_kfunc_id_set bpf_kfunc_set_tcp_reqsk = { | ^~~~~~~~~~~~~~~~~~~~~~~ >> net/core/filter.c:12139:21: error: parameter 'bpf_kfunc_set_tcp_reqsk' is initialized 12139 | static const struct btf_kfunc_id_set bpf_kfunc_set_tcp_reqsk = { | ^~~~~~~~~~~~~~~~ net/core/filter.c:12145:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token 12145 | { | ^ In file included from <command-line>: include/linux/compiler.h:189:45: error: storage class specified for parameter '__UNIQUE_ID___addressable_bpf_kfunc_init1505' 189 | #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) | ^~~~~~~~~~~~ include/linux/compiler_types.h:83:23: note: in definition of macro '___PASTE' 83 | #define ___PASTE(a,b) a##b | ^ include/linux/compiler.h:189:29: note: in expansion of macro '__PASTE' 189 | #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) | ^~~~~~~ include/linux/compiler_types.h:84:22: note: in expansion of macro '___PASTE' 84 | #define __PASTE(a,b) ___PASTE(a,b) | ^~~~~~~~ include/linux/compiler.h:189:37: note: in expansion of macro '__PASTE' 189 | #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) | ^~~~~~~ include/linux/compiler.h:227:9: note: in expansion of macro '__UNIQUE_ID' 227 | __UNIQUE_ID(__PASTE(__addressable_,sym)) = (void *)(uintptr_t)&sym; | ^~~~~~~~~~~ include/linux/compiler.h:229:9: note: in expansion of macro '___ADDRESSABLE' 229 | ___ADDRESSABLE(sym, __section(".discard.addressable")) | ^~~~~~~~~~~~~~ include/linux/init.h:256:9: note: in expansion of macro '__ADDRESSABLE' 256 | __ADDRESSABLE(fn) | ^~~~~~~~~~~~~ include/linux/init.h:261:9: note: in expansion of macro '__define_initcall_stub' 261 | __define_initcall_stub(__stub, fn) \ | ^~~~~~~~~~~~~~~~~~~~~~ include/linux/init.h:274:9: note: in expansion of macro '____define_initcall' 274 | ____define_initcall(fn, \ | ^~~~~~~~~~~~~~~~~~~ include/linux/init.h:280:9: note: in expansion of macro '__unique_initcall' 280 | __unique_initcall(fn, id, __sec, __initcall_id(fn)) | ^~~~~~~~~~~~~~~~~ include/linux/init.h:282:35: note: in expansion of macro '___define_initcall' 282 | #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id) | ^~~~~~~~~~~~~~~~~~ include/linux/init.h:313:41: note: in expansion of macro '__define_initcall' 313 | #define late_initcall(fn) __define_initcall(fn, 7) | ^~~~~~~~~~~~~~~~~ net/core/filter.c:12164:1: note: in expansion of macro 'late_initcall' 12164 | late_initcall(bpf_kfunc_init); | ^~~~~~~~~~~~~ net/core/filter.c:12164:1: error: parameter '__UNIQUE_ID___addressable_bpf_kfunc_init1505' is initialized net/core/filter.c:12164:1: warning: 'used' attribute ignored [-Wattributes] include/linux/compiler.h:189:45: error: section attribute not allowed for '__UNIQUE_ID___addressable_bpf_kfunc_init1505' 189 | #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) | ^~~~~~~~~~~~ include/linux/compiler_types.h:83:23: note: in definition of macro '___PASTE' 83 | #define ___PASTE(a,b) a##b | ^ include/linux/compiler.h:189:29: note: in expansion of macro '__PASTE' 189 | #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) | ^~~~~~~ include/linux/compiler_types.h:84:22: note: in expansion of macro '___PASTE' 84 | #define __PASTE(a,b) ___PASTE(a,b) | ^~~~~~~~ include/linux/compiler.h:189:37: note: in expansion of macro '__PASTE' 189 | #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) | ^~~~~~~ include/linux/compiler.h:227:9: note: in expansion of macro '__UNIQUE_ID' 227 | __UNIQUE_ID(__PASTE(__addressable_,sym)) = (void *)(uintptr_t)&sym; | ^~~~~~~~~~~ include/linux/compiler.h:229:9: note: in expansion of macro '___ADDRESSABLE' 229 | ___ADDRESSABLE(sym, __section(".discard.addressable")) | ^~~~~~~~~~~~~~ include/linux/init.h:256:9: note: in expansion of macro '__ADDRESSABLE' 256 | __ADDRESSABLE(fn) | ^~~~~~~~~~~~~ include/linux/init.h:261:9: note: in expansion of macro '__define_initcall_stub' 261 | __define_initcall_stub(__stub, fn) \ | ^~~~~~~~~~~~~~~~~~~~~~ include/linux/init.h:274:9: note: in expansion of macro '____define_initcall' 274 | ____define_initcall(fn, \ | ^~~~~~~~~~~~~~~~~~~ include/linux/init.h:280:9: note: in expansion of macro '__unique_initcall' 280 | __unique_initcall(fn, id, __sec, __initcall_id(fn)) | ^~~~~~~~~~~~~~~~~ include/linux/init.h:282:35: note: in expansion of macro '___define_initcall' 282 | #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id) | ^~~~~~~~~~~~~~~~~~ include/linux/init.h:313:41: note: in expansion of macro '__define_initcall' 313 | #define late_initcall(fn) __define_initcall(fn, 7) | ^~~~~~~~~~~~~~~~~ net/core/filter.c:12164:1: note: in expansion of macro 'late_initcall' 12164 | late_initcall(bpf_kfunc_init); | ^~~~~~~~~~~~~ In file included from arch/x86/include/asm/atomic.h:5, from include/linux/atomic.h:7, from net/core/filter.c:20: net/core/filter.c:12164:15: error: 'bpf_kfunc_init' undeclared (first use in this function); did you mean 'bpf_func_info'? 12164 | late_initcall(bpf_kfunc_init); | ^~~~~~~~~~~~~~ include/linux/compiler.h:227:72: note: in definition of macro '___ADDRESSABLE' 227 | __UNIQUE_ID(__PASTE(__addressable_,sym)) = (void *)(uintptr_t)&sym; vim +/int +12071 net/core/filter.c 12070 12071 BTF_HIDDEN_KFUNCS_START(bpf_kfunc_check_hidden_set_skb) 12072 BTF_ID_FLAGS(func, bpf_dynptr_from_skb_rdonly, KF_TRUSTED_ARGS) 12073 BTF_KFUNCS_END(bpf_kfunc_check_hidden_set_skb) 12074 12075 BTF_KFUNCS_START(bpf_kfunc_check_set_xdp) 12076 BTF_ID_FLAGS(func, bpf_dynptr_from_xdp) 12077 BTF_KFUNCS_END(bpf_kfunc_check_set_xdp) 12078 12079 BTF_KFUNCS_START(bpf_kfunc_check_set_sock_addr) 12080 BTF_ID_FLAGS(func, bpf_sock_addr_set_sun_path) 12081 BTF_KFUNCS_END(bpf_kfunc_check_set_sock_addr) 12082 12083 BTF_KFUNCS_START(bpf_kfunc_check_set_tcp_reqsk) 12084 BTF_ID_FLAGS(func, bpf_sk_assign_tcp_reqsk, KF_TRUSTED_ARGS) 12085 BTF_KFUNCS_END(bpf_kfunc_check_set_tcp_reqsk) 12086 12087 BTF_ID_LIST(bpf_dynptr_from_skb_list) 12088 BTF_ID(func, bpf_dynptr_from_skb) 12089 BTF_ID(func, bpf_dynptr_from_skb_rdonly) 12090 12091 static u32 bpf_kfunc_set_skb_remap(const struct bpf_prog *prog, u32 kfunc_id) 12092 { 12093 if (kfunc_id != bpf_dynptr_from_skb_list[0]) 12094 return 0; 12095 12096 switch (resolve_prog_type(prog)) { 12097 /* Program types only with direct read access go here! */ 12098 case BPF_PROG_TYPE_LWT_IN: 12099 case BPF_PROG_TYPE_LWT_OUT: 12100 case BPF_PROG_TYPE_LWT_SEG6LOCAL: 12101 case BPF_PROG_TYPE_SK_REUSEPORT: 12102 case BPF_PROG_TYPE_FLOW_DISSECTOR: 12103 case BPF_PROG_TYPE_CGROUP_SKB: 12104 return bpf_dynptr_from_skb_list[1]; 12105 12106 /* Program types with direct read + write access go here! */ 12107 case BPF_PROG_TYPE_SCHED_CLS: 12108 case BPF_PROG_TYPE_SCHED_ACT: 12109 case BPF_PROG_TYPE_XDP: 12110 case BPF_PROG_TYPE_LWT_XMIT: 12111 case BPF_PROG_TYPE_SK_SKB: 12112 case BPF_PROG_TYPE_SK_MSG: 12113 case BPF_PROG_TYPE_CGROUP_SOCKOPT: 12114 return kfunc_id; 12115 12116 default: 12117 break; 12118 } 12119 return bpf_dynptr_from_skb_list[1]; 12120 } 12121 12122 static const struct btf_kfunc_id_set bpf_kfunc_set_skb = { 12123 .owner = THIS_MODULE, 12124 .set = &bpf_kfunc_check_set_skb, 12125 .hidden_set = &bpf_kfunc_check_hidden_set_skb, 12126 .remap = &bpf_kfunc_set_skb_remap, 12127 }; 12128 12129 static const struct btf_kfunc_id_set bpf_kfunc_set_xdp = { 12130 .owner = THIS_MODULE, 12131 .set = &bpf_kfunc_check_set_xdp, 12132 }; 12133 12134 static const struct btf_kfunc_id_set bpf_kfunc_set_sock_addr = { 12135 .owner = THIS_MODULE, 12136 .set = &bpf_kfunc_check_set_sock_addr, 12137 }; 12138 12139 static const struct btf_kfunc_id_set bpf_kfunc_set_tcp_reqsk = { 12140 .owner = THIS_MODULE, 12141 .set = &bpf_kfunc_check_set_tcp_reqsk, 12142 }; 12143 12144 static int __init bpf_kfunc_init(void) 12145 { 12146 int ret; 12147 12148 ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, &bpf_kfunc_set_skb); 12149 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_ACT, &bpf_kfunc_set_skb); 12150 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SK_SKB, &bpf_kfunc_set_skb); 12151 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SOCKET_FILTER, &bpf_kfunc_set_skb); 12152 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_CGROUP_SKB, &bpf_kfunc_set_skb); 12153 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_LWT_OUT, &bpf_kfunc_set_skb); 12154 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_LWT_IN, &bpf_kfunc_set_skb); 12155 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_LWT_XMIT, &bpf_kfunc_set_skb); 12156 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_LWT_SEG6LOCAL, &bpf_kfunc_set_skb); 12157 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_NETFILTER, &bpf_kfunc_set_skb); 12158 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &bpf_kfunc_set_skb); 12159 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP, &bpf_kfunc_set_xdp); 12160 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_CGROUP_SOCK_ADDR, 12161 &bpf_kfunc_set_sock_addr); 12162 return ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, &bpf_kfunc_set_tcp_reqsk); 12163 } 12164 late_initcall(bpf_kfunc_init); 12165 12166 __bpf_kfunc_start_defs(); 12167 12168 /* bpf_sock_destroy: Destroy the given socket with ECONNABORTED error code. 12169 * 12170 * The function expects a non-NULL pointer to a socket, and invokes the 12171 * protocol specific socket destroy handlers. 12172 * 12173 * The helper can only be called from BPF contexts that have acquired the socket 12174 * locks. 12175 * 12176 * Parameters: 12177 * @sock: Pointer to socket to be destroyed 12178 * 12179 * Return: 12180 * On error, may return EPROTONOSUPPORT, EINVAL. 12181 * EPROTONOSUPPORT if protocol specific destroy handler is not supported. 12182 * 0 otherwise 12183 */ 12184 __bpf_kfunc int bpf_sock_destroy(struct sock_common *sock) 12185 { 12186 struct sock *sk = (struct sock *)sock; 12187 12188 /* The locking semantics that allow for synchronous execution of the 12189 * destroy handlers are only supported for TCP and UDP. 12190 * Supporting protocols will need to acquire sock lock in the BPF context 12191 * prior to invoking this kfunc. 12192 */ 12193 if (!sk->sk_prot->diag_destroy || (sk->sk_protocol != IPPROTO_TCP && 12194 sk->sk_protocol != IPPROTO_UDP)) 12195 return -EOPNOTSUPP; 12196 12197 return sk->sk_prot->diag_destroy(sk, ECONNABORTED); 12198 } 12199 12200 __bpf_kfunc_end_defs(); 12201 12202 BTF_KFUNCS_START(bpf_sk_iter_kfunc_ids) 12203 BTF_ID_FLAGS(func, bpf_sock_destroy, KF_TRUSTED_ARGS) 12204 BTF_KFUNCS_END(bpf_sk_iter_kfunc_ids) 12205 12206 static int tracing_iter_filter(const struct bpf_prog *prog, u32 kfunc_id) 12207 { 12208 if (btf_id_set8_contains(&bpf_sk_iter_kfunc_ids, kfunc_id) && 12209 prog->expected_attach_type != BPF_TRACE_ITER) 12210 return -EACCES; 12211 return 0; 12212 } 12213 12214 static const struct btf_kfunc_id_set bpf_sk_iter_kfunc_set = { 12215 .owner = THIS_MODULE, 12216 .set = &bpf_sk_iter_kfunc_ids, 12217 .filter = tracing_iter_filter, 12218 }; 12219 12220 static int init_subsystem(void) 12221 { 12222 return register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &bpf_sk_iter_kfunc_set); 12223 } 12224 late_initcall(init_subsystem);
On Thu, Jan 9, 2025 at 3:56 PM kernel test robot <lkp@intel.com> wrote: > > Hi Song, > > kernel test robot noticed the following build errors: > > [auto build test ERROR on bpf-next/master] > > url: https://github.com/intel-lab-lkp/linux/commits/Song-Liu/fs-xattr-bpf-Introduce-security-bpf-xattr-name-prefix/20250109-065503 > base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master > patch link: https://lore.kernel.org/r/20250108225140.3467654-6-song%40kernel.org > patch subject: [PATCH v8 bpf-next 5/7] bpf: Use btf_kfunc_id_set.remap logic for bpf_dynptr_from_skb > config: i386-buildonly-randconfig-005-20250110 (https://download.01.org/0day-ci/archive/20250110/202501100757.HDb5slrv-lkp@intel.com/config) > compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250110/202501100757.HDb5slrv-lkp@intel.com/reproduce) > > If you fix the issue in a separate patch/commit (i.e. not just a new version of > the same patch/commit), kindly add following tags > | Reported-by: kernel test robot <lkp@intel.com> > | Closes: https://lore.kernel.org/oe-kbuild-all/202501100757.HDb5slrv-lkp@intel.com/ > > All error/warnings (new ones prefixed by >>): > > >> net/core/filter.c:12071:1: error: return type defaults to 'int' [-Werror=implicit-int] > 12071 | BTF_HIDDEN_KFUNCS_START(bpf_kfunc_check_hidden_set_skb) > | ^~~~~~~~~~~~~~~~~~~~~~~ Good catch.. Fixing this in v9. Thanks, Song
Hi Song, kernel test robot noticed the following build errors: [auto build test ERROR on bpf-next/master] url: https://github.com/intel-lab-lkp/linux/commits/Song-Liu/fs-xattr-bpf-Introduce-security-bpf-xattr-name-prefix/20250109-065503 base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master patch link: https://lore.kernel.org/r/20250108225140.3467654-6-song%40kernel.org patch subject: [PATCH v8 bpf-next 5/7] bpf: Use btf_kfunc_id_set.remap logic for bpf_dynptr_from_skb config: s390-randconfig-002-20250110 (https://download.01.org/0day-ci/archive/20250110/202501100813.5dE7y99c-lkp@intel.com/config) compiler: s390-linux-gcc (GCC) 14.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250110/202501100813.5dE7y99c-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202501100813.5dE7y99c-lkp@intel.com/ All errors (new ones prefixed by >>): net/core/filter.c:12071:1: error: return type defaults to 'int' [-Wimplicit-int] 12071 | BTF_HIDDEN_KFUNCS_START(bpf_kfunc_check_hidden_set_skb) | ^~~~~~~~~~~~~~~~~~~~~~~ net/core/filter.c:12071:1: error: function declaration isn't a prototype [-Werror=strict-prototypes] In file included from include/linux/btf.h:10, from include/linux/bpf.h:28, from include/linux/bpf_verifier.h:7, from net/core/filter.c:21: net/core/filter.c: In function 'BTF_HIDDEN_KFUNCS_START': net/core/filter.c:12075:18: error: storage class specified for parameter 'bpf_kfunc_check_set_xdp' 12075 | BTF_KFUNCS_START(bpf_kfunc_check_set_xdp) | ^~~~~~~~~~~~~~~~~~~~~~~ include/linux/btf_ids.h:235:73: note: in definition of macro 'BTF_KFUNCS_START' 235 | #define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS }; | ^~~~ include/linux/btf_ids.h:235:46: error: parameter 'bpf_kfunc_check_set_xdp' is initialized 235 | #define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS }; | ^~~~~~~~~~~ net/core/filter.c:12075:1: note: in expansion of macro 'BTF_KFUNCS_START' 12075 | BTF_KFUNCS_START(bpf_kfunc_check_set_xdp) | ^~~~~~~~~~~~~~~~ net/core/filter.c:12079:18: error: storage class specified for parameter 'bpf_kfunc_check_set_sock_addr' 12079 | BTF_KFUNCS_START(bpf_kfunc_check_set_sock_addr) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/btf_ids.h:235:73: note: in definition of macro 'BTF_KFUNCS_START' 235 | #define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS }; | ^~~~ include/linux/btf_ids.h:235:46: error: parameter 'bpf_kfunc_check_set_sock_addr' is initialized 235 | #define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS }; | ^~~~~~~~~~~ net/core/filter.c:12079:1: note: in expansion of macro 'BTF_KFUNCS_START' 12079 | BTF_KFUNCS_START(bpf_kfunc_check_set_sock_addr) | ^~~~~~~~~~~~~~~~ net/core/filter.c:12083:18: error: storage class specified for parameter 'bpf_kfunc_check_set_tcp_reqsk' 12083 | BTF_KFUNCS_START(bpf_kfunc_check_set_tcp_reqsk) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/btf_ids.h:235:73: note: in definition of macro 'BTF_KFUNCS_START' 235 | #define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS }; | ^~~~ include/linux/btf_ids.h:235:46: error: parameter 'bpf_kfunc_check_set_tcp_reqsk' is initialized 235 | #define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS }; | ^~~~~~~~~~~ net/core/filter.c:12083:1: note: in expansion of macro 'BTF_KFUNCS_START' 12083 | BTF_KFUNCS_START(bpf_kfunc_check_set_tcp_reqsk) | ^~~~~~~~~~~~~~~~ net/core/filter.c:12087:13: error: storage class specified for parameter 'bpf_dynptr_from_skb_list' 12087 | BTF_ID_LIST(bpf_dynptr_from_skb_list) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/btf_ids.h:223:53: note: in definition of macro 'BTF_ID_LIST' 223 | #define BTF_ID_LIST(name) static u32 __maybe_unused name[64]; | ^~~~ net/core/filter.c:12092:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token 12092 | { | ^ net/core/filter.c:12122:38: error: storage class specified for parameter 'bpf_kfunc_set_skb' 12122 | static const struct btf_kfunc_id_set bpf_kfunc_set_skb = { | ^~~~~~~~~~~~~~~~~ net/core/filter.c:12122:21: error: parameter 'bpf_kfunc_set_skb' is initialized 12122 | static const struct btf_kfunc_id_set bpf_kfunc_set_skb = { | ^~~~~~~~~~~~~~~~ net/core/filter.c:12125:24: error: 'bpf_kfunc_check_hidden_set_skb' undeclared (first use in this function); did you mean 'bpf_kfunc_check_set_skb'? 12125 | .hidden_set = &bpf_kfunc_check_hidden_set_skb, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | bpf_kfunc_check_set_skb net/core/filter.c:12125:24: note: each undeclared identifier is reported only once for each function it appears in net/core/filter.c:12126:19: error: 'bpf_kfunc_set_skb_remap' undeclared (first use in this function); did you mean 'bpf_kfunc_set_skb'? 12126 | .remap = &bpf_kfunc_set_skb_remap, | ^~~~~~~~~~~~~~~~~~~~~~~ | bpf_kfunc_set_skb net/core/filter.c:12129:38: error: storage class specified for parameter 'bpf_kfunc_set_xdp' 12129 | static const struct btf_kfunc_id_set bpf_kfunc_set_xdp = { | ^~~~~~~~~~~~~~~~~ net/core/filter.c:12129:21: error: parameter 'bpf_kfunc_set_xdp' is initialized 12129 | static const struct btf_kfunc_id_set bpf_kfunc_set_xdp = { | ^~~~~~~~~~~~~~~~ net/core/filter.c:12134:38: error: storage class specified for parameter 'bpf_kfunc_set_sock_addr' 12134 | static const struct btf_kfunc_id_set bpf_kfunc_set_sock_addr = { | ^~~~~~~~~~~~~~~~~~~~~~~ net/core/filter.c:12134:21: error: parameter 'bpf_kfunc_set_sock_addr' is initialized 12134 | static const struct btf_kfunc_id_set bpf_kfunc_set_sock_addr = { | ^~~~~~~~~~~~~~~~ net/core/filter.c:12139:38: error: storage class specified for parameter 'bpf_kfunc_set_tcp_reqsk' 12139 | static const struct btf_kfunc_id_set bpf_kfunc_set_tcp_reqsk = { | ^~~~~~~~~~~~~~~~~~~~~~~ net/core/filter.c:12139:21: error: parameter 'bpf_kfunc_set_tcp_reqsk' is initialized 12139 | static const struct btf_kfunc_id_set bpf_kfunc_set_tcp_reqsk = { | ^~~~~~~~~~~~~~~~ net/core/filter.c:12145:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token 12145 | { | ^ In file included from include/linux/printk.h:6, from include/asm-generic/bug.h:22, from arch/s390/include/asm/bug.h:69, from include/linux/bug.h:5, from include/linux/mmdebug.h:5, from arch/s390/include/asm/cmpxchg.h:11, from arch/s390/include/asm/atomic.h:16, from include/linux/atomic.h:7, from net/core/filter.c:20: >> include/linux/init.h:218:17: error: storage class specified for parameter '__initcall__kmod_filter__1641_12164_bpf_kfunc_init7' 218 | __PASTE(__, \ | ^~ include/linux/init.h:269:27: note: in definition of macro '____define_initcall' 269 | static initcall_t __name __used \ | ^~~~~~ include/linux/compiler_types.h:84:22: note: in expansion of macro '___PASTE' 84 | #define __PASTE(a,b) ___PASTE(a,b) | ^~~~~~~~ include/linux/init.h:218:9: note: in expansion of macro '__PASTE' 218 | __PASTE(__, \ | ^~~~~~~ include/linux/init.h:276:17: note: in expansion of macro '__initcall_name' 276 | __initcall_name(initcall, __iid, id), \ | ^~~~~~~~~~~~~~~ include/linux/init.h:280:9: note: in expansion of macro '__unique_initcall' 280 | __unique_initcall(fn, id, __sec, __initcall_id(fn)) | ^~~~~~~~~~~~~~~~~ include/linux/init.h:282:35: note: in expansion of macro '___define_initcall' 282 | #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id) | ^~~~~~~~~~~~~~~~~~ include/linux/init.h:313:41: note: in expansion of macro '__define_initcall' 313 | #define late_initcall(fn) __define_initcall(fn, 7) | ^~~~~~~~~~~~~~~~~ net/core/filter.c:12164:1: note: in expansion of macro 'late_initcall' 12164 | late_initcall(bpf_kfunc_init); | ^~~~~~~~~~~~~ >> net/core/filter.c:12164:1: error: parameter '__initcall__kmod_filter__1641_12164_bpf_kfunc_init7' is initialized net/core/filter.c:12164:1: warning: 'used' attribute ignored [-Wattributes] >> include/linux/init.h:218:17: error: section attribute not allowed for '__initcall__kmod_filter__1641_12164_bpf_kfunc_init7' 218 | __PASTE(__, \ | ^~ include/linux/init.h:269:27: note: in definition of macro '____define_initcall' 269 | static initcall_t __name __used \ | ^~~~~~ include/linux/compiler_types.h:84:22: note: in expansion of macro '___PASTE' 84 | #define __PASTE(a,b) ___PASTE(a,b) | ^~~~~~~~ include/linux/init.h:218:9: note: in expansion of macro '__PASTE' 218 | __PASTE(__, \ | ^~~~~~~ include/linux/init.h:276:17: note: in expansion of macro '__initcall_name' 276 | __initcall_name(initcall, __iid, id), \ | ^~~~~~~~~~~~~~~ include/linux/init.h:280:9: note: in expansion of macro '__unique_initcall' 280 | __unique_initcall(fn, id, __sec, __initcall_id(fn)) | ^~~~~~~~~~~~~~~~~ include/linux/init.h:282:35: note: in expansion of macro '___define_initcall' 282 | #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id) | ^~~~~~~~~~~~~~~~~~ include/linux/init.h:313:41: note: in expansion of macro '__define_initcall' 313 | #define late_initcall(fn) __define_initcall(fn, 7) | ^~~~~~~~~~~~~~~~~ net/core/filter.c:12164:1: note: in expansion of macro 'late_initcall' 12164 | late_initcall(bpf_kfunc_init); | ^~~~~~~~~~~~~ net/core/filter.c:12164:15: error: 'bpf_kfunc_init' undeclared (first use in this function); did you mean 'bpf_func_info'? 12164 | late_initcall(bpf_kfunc_init); | ^~~~~~~~~~~~~~ include/linux/init.h:270:55: note: in definition of macro '____define_initcall' 270 | __attribute__((__section__(__sec))) = fn; | ^~ include/linux/init.h:280:9: note: in expansion of macro '__unique_initcall' 280 | __unique_initcall(fn, id, __sec, __initcall_id(fn)) | ^~~~~~~~~~~~~~~~~ include/linux/init.h:282:35: note: in expansion of macro '___define_initcall' 282 | #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id) | ^~~~~~~~~~~~~~~~~~ include/linux/init.h:313:41: note: in expansion of macro '__define_initcall' 313 | #define late_initcall(fn) __define_initcall(fn, 7) | ^~~~~~~~~~~~~~~~~ net/core/filter.c:12164:1: note: in expansion of macro 'late_initcall' 12164 | late_initcall(bpf_kfunc_init); | ^~~~~~~~~~~~~ net/core/filter.c:12164:30: error: expected declaration specifiers before ';' token 12164 | late_initcall(bpf_kfunc_init); | ^ In file included from include/linux/compiler_types.h:174, from <command-line>: include/linux/compiler-gcc.h:134:33: error: expected declaration specifiers before '#pragma' 134 | #define __diag(s) _Pragma(__diag_str(GCC diagnostic s)) | ^~~~~~~ include/linux/compiler_types.h:557:25: note: in expansion of macro '__diag' 557 | #define __diag_push() __diag(push) | ^~~~~~ include/linux/btf.h:89:9: note: in expansion of macro '__diag_push' 89 | __diag_push(); \ | ^~~~~~~~~~~ net/core/filter.c:12166:1: note: in expansion of macro '__bpf_kfunc_start_defs' 12166 | __bpf_kfunc_start_defs(); | ^~~~~~~~~~~~~~~~~~~~~~ include/linux/compiler-gcc.h:134:33: error: expected declaration specifiers before '#pragma' 134 | #define __diag(s) _Pragma(__diag_str(GCC diagnostic s)) | ^~~~~~~ include/linux/compiler-gcc.h:143:9: note: in expansion of macro '__diag' 143 | __diag(__diag_GCC_ignore option) | ^~~~~~ include/linux/btf.h:90:9: note: in expansion of macro '__diag_ignore_all' 90 | __diag_ignore_all("-Wmissing-declarations", \ | ^~~~~~~~~~~~~~~~~ net/core/filter.c:12166:1: note: in expansion of macro '__bpf_kfunc_start_defs' 12166 | __bpf_kfunc_start_defs(); | ^~~~~~~~~~~~~~~~~~~~~~ include/linux/compiler-gcc.h:134:33: error: expected declaration specifiers before '#pragma' 134 | #define __diag(s) _Pragma(__diag_str(GCC diagnostic s)) | ^~~~~~~ include/linux/compiler-gcc.h:143:9: note: in expansion of macro '__diag' 143 | __diag(__diag_GCC_ignore option) | ^~~~~~ include/linux/btf.h:92:9: note: in expansion of macro '__diag_ignore_all' 92 | __diag_ignore_all("-Wmissing-prototypes", \ | ^~~~~~~~~~~~~~~~~ net/core/filter.c:12166:1: note: in expansion of macro '__bpf_kfunc_start_defs' 12166 | __bpf_kfunc_start_defs(); | ^~~~~~~~~~~~~~~~~~~~~~ In file included from include/linux/compiler_types.h:89: include/linux/compiler_attributes.h:349:41: error: expected declaration specifiers before '__attribute__' 349 | #define __used __attribute__((__used__)) | ^~~~~~~~~~~~~ include/linux/btf.h:86:21: note: in expansion of macro '__used' 86 | #define __bpf_kfunc __used __retain noinline | ^~~~~~ net/core/filter.c:12184:1: note: in expansion of macro '__bpf_kfunc' 12184 | __bpf_kfunc int bpf_sock_destroy(struct sock_common *sock) | ^~~~~~~~~~~ include/linux/compiler-gcc.h:134:33: error: expected declaration specifiers before '#pragma' 134 | #define __diag(s) _Pragma(__diag_str(GCC diagnostic s)) | ^~~~~~~ include/linux/compiler_types.h:558:25: note: in expansion of macro '__diag' 558 | #define __diag_pop() __diag(pop) | ^~~~~~ include/linux/btf.h:95:32: note: in expansion of macro '__diag_pop' 95 | #define __bpf_kfunc_end_defs() __diag_pop() | ^~~~~~~~~~ net/core/filter.c:12200:1: note: in expansion of macro '__bpf_kfunc_end_defs' 12200 | __bpf_kfunc_end_defs(); | ^~~~~~~~~~~~~~~~~~~~ net/core/filter.c:12202:18: error: storage class specified for parameter 'bpf_sk_iter_kfunc_ids' 12202 | BTF_KFUNCS_START(bpf_sk_iter_kfunc_ids) | ^~~~~~~~~~~~~~~~~~~~~ include/linux/btf_ids.h:235:73: note: in definition of macro 'BTF_KFUNCS_START' 235 | #define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS }; | ^~~~ include/linux/btf_ids.h:235:46: error: parameter 'bpf_sk_iter_kfunc_ids' is initialized 235 | #define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS }; | ^~~~~~~~~~~ net/core/filter.c:12202:1: note: in expansion of macro 'BTF_KFUNCS_START' 12202 | BTF_KFUNCS_START(bpf_sk_iter_kfunc_ids) | ^~~~~~~~~~~~~~~~ net/core/filter.c:12207:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token 12207 | { | ^ net/core/filter.c:12214:38: error: storage class specified for parameter 'bpf_sk_iter_kfunc_set' 12214 | static const struct btf_kfunc_id_set bpf_sk_iter_kfunc_set = { | ^~~~~~~~~~~~~~~~~~~~~ net/core/filter.c:12214:21: error: parameter 'bpf_sk_iter_kfunc_set' is initialized 12214 | static const struct btf_kfunc_id_set bpf_sk_iter_kfunc_set = { | ^~~~~~~~~~~~~~~~ net/core/filter.c:12217:19: error: 'tracing_iter_filter' undeclared (first use in this function) 12217 | .filter = tracing_iter_filter, | ^~~~~~~~~~~~~~~~~~~ net/core/filter.c:12221:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token 12221 | { | ^ >> include/linux/init.h:218:17: error: storage class specified for parameter '__initcall__kmod_filter__1642_12224_init_subsystem7' 218 | __PASTE(__, \ | ^~ include/linux/init.h:269:27: note: in definition of macro '____define_initcall' 269 | static initcall_t __name __used \ | ^~~~~~ include/linux/compiler_types.h:84:22: note: in expansion of macro '___PASTE' 84 | #define __PASTE(a,b) ___PASTE(a,b) | ^~~~~~~~ include/linux/init.h:218:9: note: in expansion of macro '__PASTE' 218 | __PASTE(__, \ | ^~~~~~~ include/linux/init.h:276:17: note: in expansion of macro '__initcall_name' 276 | __initcall_name(initcall, __iid, id), \ | ^~~~~~~~~~~~~~~ include/linux/init.h:280:9: note: in expansion of macro '__unique_initcall' 280 | __unique_initcall(fn, id, __sec, __initcall_id(fn)) | ^~~~~~~~~~~~~~~~~ include/linux/init.h:282:35: note: in expansion of macro '___define_initcall' 282 | #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id) | ^~~~~~~~~~~~~~~~~~ include/linux/init.h:313:41: note: in expansion of macro '__define_initcall' 313 | #define late_initcall(fn) __define_initcall(fn, 7) | ^~~~~~~~~~~~~~~~~ net/core/filter.c:12224:1: note: in expansion of macro 'late_initcall' 12224 | late_initcall(init_subsystem); | ^~~~~~~~~~~~~ >> net/core/filter.c:12224:1: error: parameter '__initcall__kmod_filter__1642_12224_init_subsystem7' is initialized net/core/filter.c:12224:1: warning: 'used' attribute ignored [-Wattributes] >> include/linux/init.h:218:17: error: section attribute not allowed for '__initcall__kmod_filter__1642_12224_init_subsystem7' 218 | __PASTE(__, \ | ^~ include/linux/init.h:269:27: note: in definition of macro '____define_initcall' 269 | static initcall_t __name __used \ | ^~~~~~ include/linux/compiler_types.h:84:22: note: in expansion of macro '___PASTE' 84 | #define __PASTE(a,b) ___PASTE(a,b) | ^~~~~~~~ include/linux/init.h:218:9: note: in expansion of macro '__PASTE' 218 | __PASTE(__, \ | ^~~~~~~ include/linux/init.h:276:17: note: in expansion of macro '__initcall_name' 276 | __initcall_name(initcall, __iid, id), \ | ^~~~~~~~~~~~~~~ include/linux/init.h:280:9: note: in expansion of macro '__unique_initcall' 280 | __unique_initcall(fn, id, __sec, __initcall_id(fn)) | ^~~~~~~~~~~~~~~~~ include/linux/init.h:282:35: note: in expansion of macro '___define_initcall' 282 | #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id) | ^~~~~~~~~~~~~~~~~~ include/linux/init.h:313:41: note: in expansion of macro '__define_initcall' 313 | #define late_initcall(fn) __define_initcall(fn, 7) | ^~~~~~~~~~~~~~~~~ net/core/filter.c:12224:1: note: in expansion of macro 'late_initcall' 12224 | late_initcall(init_subsystem); | ^~~~~~~~~~~~~ net/core/filter.c:12224:15: error: 'init_subsystem' undeclared (first use in this function) 12224 | late_initcall(init_subsystem); | ^~~~~~~~~~~~~~ include/linux/init.h:270:55: note: in definition of macro '____define_initcall' 270 | __attribute__((__section__(__sec))) = fn; | ^~ include/linux/init.h:280:9: note: in expansion of macro '__unique_initcall' 280 | __unique_initcall(fn, id, __sec, __initcall_id(fn)) | ^~~~~~~~~~~~~~~~~ include/linux/init.h:282:35: note: in expansion of macro '___define_initcall' 282 | #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id) | ^~~~~~~~~~~~~~~~~~ include/linux/init.h:313:41: note: in expansion of macro '__define_initcall' 313 | #define late_initcall(fn) __define_initcall(fn, 7) | ^~~~~~~~~~~~~~~~~ net/core/filter.c:12224:1: note: in expansion of macro 'late_initcall' 12224 | late_initcall(init_subsystem); | ^~~~~~~~~~~~~ net/core/filter.c:12224:30: error: expected declaration specifiers before ';' token 12224 | late_initcall(init_subsystem); | ^ >> include/linux/init.h:218:17: error: declaration for parameter '__initcall__kmod_filter__1642_12224_init_subsystem7' but no such parameter 218 | __PASTE(__, \ | ^~ include/linux/init.h:269:27: note: in definition of macro '____define_initcall' 269 | static initcall_t __name __used \ | ^~~~~~ include/linux/compiler_types.h:84:22: note: in expansion of macro '___PASTE' 84 | #define __PASTE(a,b) ___PASTE(a,b) | ^~~~~~~~ include/linux/init.h:218:9: note: in expansion of macro '__PASTE' 218 | __PASTE(__, \ | ^~~~~~~ include/linux/init.h:276:17: note: in expansion of macro '__initcall_name' 276 | __initcall_name(initcall, __iid, id), \ | ^~~~~~~~~~~~~~~ include/linux/init.h:280:9: note: in expansion of macro '__unique_initcall' 280 | __unique_initcall(fn, id, __sec, __initcall_id(fn)) | ^~~~~~~~~~~~~~~~~ include/linux/init.h:282:35: note: in expansion of macro '___define_initcall' 282 | #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id) | ^~~~~~~~~~~~~~~~~~ include/linux/init.h:313:41: note: in expansion of macro '__define_initcall' 313 | #define late_initcall(fn) __define_initcall(fn, 7) | ^~~~~~~~~~~~~~~~~ net/core/filter.c:12224:1: note: in expansion of macro 'late_initcall' 12224 | late_initcall(init_subsystem); | ^~~~~~~~~~~~~ net/core/filter.c:12214:38: error: declaration for parameter 'bpf_sk_iter_kfunc_set' but no such parameter 12214 | static const struct btf_kfunc_id_set bpf_sk_iter_kfunc_set = { | ^~~~~~~~~~~~~~~~~~~~~ net/core/filter.c:12202:18: error: declaration for parameter 'bpf_sk_iter_kfunc_ids' but no such parameter 12202 | BTF_KFUNCS_START(bpf_sk_iter_kfunc_ids) | ^~~~~~~~~~~~~~~~~~~~~ include/linux/btf_ids.h:235:73: note: in definition of macro 'BTF_KFUNCS_START' 235 | #define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS }; | ^~~~ >> include/linux/init.h:218:17: error: declaration for parameter '__initcall__kmod_filter__1641_12164_bpf_kfunc_init7' but no such parameter 218 | __PASTE(__, \ | ^~ include/linux/init.h:269:27: note: in definition of macro '____define_initcall' 269 | static initcall_t __name __used \ | ^~~~~~ include/linux/compiler_types.h:84:22: note: in expansion of macro '___PASTE' 84 | #define __PASTE(a,b) ___PASTE(a,b) | ^~~~~~~~ include/linux/init.h:218:9: note: in expansion of macro '__PASTE' 218 | __PASTE(__, \ | ^~~~~~~ include/linux/init.h:276:17: note: in expansion of macro '__initcall_name' 276 | __initcall_name(initcall, __iid, id), \ | ^~~~~~~~~~~~~~~ include/linux/init.h:280:9: note: in expansion of macro '__unique_initcall' 280 | __unique_initcall(fn, id, __sec, __initcall_id(fn)) | ^~~~~~~~~~~~~~~~~ include/linux/init.h:282:35: note: in expansion of macro '___define_initcall' 282 | #define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id) | ^~~~~~~~~~~~~~~~~~ include/linux/init.h:313:41: note: in expansion of macro '__define_initcall' 313 | #define late_initcall(fn) __define_initcall(fn, 7) | ^~~~~~~~~~~~~~~~~ net/core/filter.c:12164:1: note: in expansion of macro 'late_initcall' 12164 | late_initcall(bpf_kfunc_init); | ^~~~~~~~~~~~~ net/core/filter.c:12139:38: error: declaration for parameter 'bpf_kfunc_set_tcp_reqsk' but no such parameter 12139 | static const struct btf_kfunc_id_set bpf_kfunc_set_tcp_reqsk = { | ^~~~~~~~~~~~~~~~~~~~~~~ net/core/filter.c:12134:38: error: declaration for parameter 'bpf_kfunc_set_sock_addr' but no such parameter 12134 | static const struct btf_kfunc_id_set bpf_kfunc_set_sock_addr = { | ^~~~~~~~~~~~~~~~~~~~~~~ net/core/filter.c:12129:38: error: declaration for parameter 'bpf_kfunc_set_xdp' but no such parameter 12129 | static const struct btf_kfunc_id_set bpf_kfunc_set_xdp = { | ^~~~~~~~~~~~~~~~~ net/core/filter.c:12122:38: error: declaration for parameter 'bpf_kfunc_set_skb' but no such parameter 12122 | static const struct btf_kfunc_id_set bpf_kfunc_set_skb = { | ^~~~~~~~~~~~~~~~~ net/core/filter.c:12087:13: error: declaration for parameter 'bpf_dynptr_from_skb_list' but no such parameter 12087 | BTF_ID_LIST(bpf_dynptr_from_skb_list) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/btf_ids.h:223:53: note: in definition of macro 'BTF_ID_LIST' 223 | #define BTF_ID_LIST(name) static u32 __maybe_unused name[64]; | ^~~~ net/core/filter.c:12083:18: error: declaration for parameter 'bpf_kfunc_check_set_tcp_reqsk' but no such parameter 12083 | BTF_KFUNCS_START(bpf_kfunc_check_set_tcp_reqsk) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/btf_ids.h:235:73: note: in definition of macro 'BTF_KFUNCS_START' 235 | #define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS }; | ^~~~ net/core/filter.c:12079:18: error: declaration for parameter 'bpf_kfunc_check_set_sock_addr' but no such parameter 12079 | BTF_KFUNCS_START(bpf_kfunc_check_set_sock_addr) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/btf_ids.h:235:73: note: in definition of macro 'BTF_KFUNCS_START' 235 | #define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS }; | ^~~~ net/core/filter.c:12075:18: error: declaration for parameter 'bpf_kfunc_check_set_xdp' but no such parameter 12075 | BTF_KFUNCS_START(bpf_kfunc_check_set_xdp) | ^~~~~~~~~~~~~~~~~~~~~~~ include/linux/btf_ids.h:235:73: note: in definition of macro 'BTF_KFUNCS_START' 235 | #define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS }; | ^~~~ net/core/filter.c:12225: error: expected '{' at end of input net/core/filter.c:12225: warning: control reaches end of non-void function [-Wreturn-type] cc1: some warnings being treated as errors vim +/__initcall__kmod_filter__1641_12164_bpf_kfunc_init7 +12164 net/core/filter.c e472f88891abbc Kuniyuki Iwashima 2024-01-15 12143 b5964b968ac64c Joanne Koong 2023-03-01 12144 static int __init bpf_kfunc_init(void) b5964b968ac64c Joanne Koong 2023-03-01 12145 { b5964b968ac64c Joanne Koong 2023-03-01 12146 int ret; b5964b968ac64c Joanne Koong 2023-03-01 12147 b5964b968ac64c Joanne Koong 2023-03-01 12148 ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, &bpf_kfunc_set_skb); b5964b968ac64c Joanne Koong 2023-03-01 12149 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_ACT, &bpf_kfunc_set_skb); b5964b968ac64c Joanne Koong 2023-03-01 12150 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SK_SKB, &bpf_kfunc_set_skb); b5964b968ac64c Joanne Koong 2023-03-01 12151 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SOCKET_FILTER, &bpf_kfunc_set_skb); b5964b968ac64c Joanne Koong 2023-03-01 12152 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_CGROUP_SKB, &bpf_kfunc_set_skb); b5964b968ac64c Joanne Koong 2023-03-01 12153 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_LWT_OUT, &bpf_kfunc_set_skb); b5964b968ac64c Joanne Koong 2023-03-01 12154 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_LWT_IN, &bpf_kfunc_set_skb); b5964b968ac64c Joanne Koong 2023-03-01 12155 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_LWT_XMIT, &bpf_kfunc_set_skb); 05421aecd4ed65 Joanne Koong 2023-03-01 12156 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_LWT_SEG6LOCAL, &bpf_kfunc_set_skb); fd9c663b9ad67d Florian Westphal 2023-04-21 12157 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_NETFILTER, &bpf_kfunc_set_skb); ffc83860d8c097 Philo Lu 2024-09-11 12158 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &bpf_kfunc_set_skb); 53e380d2144190 Daan De Meyer 2023-10-11 12159 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP, &bpf_kfunc_set_xdp); e472f88891abbc Kuniyuki Iwashima 2024-01-15 12160 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_CGROUP_SOCK_ADDR, 53e380d2144190 Daan De Meyer 2023-10-11 12161 &bpf_kfunc_set_sock_addr); e472f88891abbc Kuniyuki Iwashima 2024-01-15 12162 return ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, &bpf_kfunc_set_tcp_reqsk); b5964b968ac64c Joanne Koong 2023-03-01 12163 } b5964b968ac64c Joanne Koong 2023-03-01 @12164 late_initcall(bpf_kfunc_init); 4ddbcb886268af Aditi Ghag 2023-05-19 12165 391145ba2accc4 Dave Marchevsky 2023-10-31 12166 __bpf_kfunc_start_defs(); 4ddbcb886268af Aditi Ghag 2023-05-19 12167 4ddbcb886268af Aditi Ghag 2023-05-19 12168 /* bpf_sock_destroy: Destroy the given socket with ECONNABORTED error code. 4ddbcb886268af Aditi Ghag 2023-05-19 12169 * 4ddbcb886268af Aditi Ghag 2023-05-19 12170 * The function expects a non-NULL pointer to a socket, and invokes the 4ddbcb886268af Aditi Ghag 2023-05-19 12171 * protocol specific socket destroy handlers. 4ddbcb886268af Aditi Ghag 2023-05-19 12172 * 4ddbcb886268af Aditi Ghag 2023-05-19 12173 * The helper can only be called from BPF contexts that have acquired the socket 4ddbcb886268af Aditi Ghag 2023-05-19 12174 * locks. 4ddbcb886268af Aditi Ghag 2023-05-19 12175 * 4ddbcb886268af Aditi Ghag 2023-05-19 12176 * Parameters: 4ddbcb886268af Aditi Ghag 2023-05-19 12177 * @sock: Pointer to socket to be destroyed 4ddbcb886268af Aditi Ghag 2023-05-19 12178 * 4ddbcb886268af Aditi Ghag 2023-05-19 12179 * Return: 4ddbcb886268af Aditi Ghag 2023-05-19 12180 * On error, may return EPROTONOSUPPORT, EINVAL. 4ddbcb886268af Aditi Ghag 2023-05-19 12181 * EPROTONOSUPPORT if protocol specific destroy handler is not supported. 4ddbcb886268af Aditi Ghag 2023-05-19 12182 * 0 otherwise 4ddbcb886268af Aditi Ghag 2023-05-19 12183 */ 4ddbcb886268af Aditi Ghag 2023-05-19 12184 __bpf_kfunc int bpf_sock_destroy(struct sock_common *sock) 4ddbcb886268af Aditi Ghag 2023-05-19 12185 { 4ddbcb886268af Aditi Ghag 2023-05-19 12186 struct sock *sk = (struct sock *)sock; 4ddbcb886268af Aditi Ghag 2023-05-19 12187 4ddbcb886268af Aditi Ghag 2023-05-19 12188 /* The locking semantics that allow for synchronous execution of the 4ddbcb886268af Aditi Ghag 2023-05-19 12189 * destroy handlers are only supported for TCP and UDP. 4ddbcb886268af Aditi Ghag 2023-05-19 12190 * Supporting protocols will need to acquire sock lock in the BPF context 4ddbcb886268af Aditi Ghag 2023-05-19 12191 * prior to invoking this kfunc. 4ddbcb886268af Aditi Ghag 2023-05-19 12192 */ 4ddbcb886268af Aditi Ghag 2023-05-19 12193 if (!sk->sk_prot->diag_destroy || (sk->sk_protocol != IPPROTO_TCP && 4ddbcb886268af Aditi Ghag 2023-05-19 12194 sk->sk_protocol != IPPROTO_UDP)) 4ddbcb886268af Aditi Ghag 2023-05-19 12195 return -EOPNOTSUPP; 4ddbcb886268af Aditi Ghag 2023-05-19 12196 4ddbcb886268af Aditi Ghag 2023-05-19 12197 return sk->sk_prot->diag_destroy(sk, ECONNABORTED); 4ddbcb886268af Aditi Ghag 2023-05-19 12198 } 4ddbcb886268af Aditi Ghag 2023-05-19 12199 391145ba2accc4 Dave Marchevsky 2023-10-31 12200 __bpf_kfunc_end_defs(); 4ddbcb886268af Aditi Ghag 2023-05-19 12201 6f3189f38a3e99 Daniel Xu 2024-01-28 12202 BTF_KFUNCS_START(bpf_sk_iter_kfunc_ids) 4ddbcb886268af Aditi Ghag 2023-05-19 12203 BTF_ID_FLAGS(func, bpf_sock_destroy, KF_TRUSTED_ARGS) 6f3189f38a3e99 Daniel Xu 2024-01-28 12204 BTF_KFUNCS_END(bpf_sk_iter_kfunc_ids) 4ddbcb886268af Aditi Ghag 2023-05-19 12205 4ddbcb886268af Aditi Ghag 2023-05-19 12206 static int tracing_iter_filter(const struct bpf_prog *prog, u32 kfunc_id) 4ddbcb886268af Aditi Ghag 2023-05-19 12207 { 4ddbcb886268af Aditi Ghag 2023-05-19 12208 if (btf_id_set8_contains(&bpf_sk_iter_kfunc_ids, kfunc_id) && 4ddbcb886268af Aditi Ghag 2023-05-19 12209 prog->expected_attach_type != BPF_TRACE_ITER) 4ddbcb886268af Aditi Ghag 2023-05-19 12210 return -EACCES; 4ddbcb886268af Aditi Ghag 2023-05-19 12211 return 0; 4ddbcb886268af Aditi Ghag 2023-05-19 12212 } 4ddbcb886268af Aditi Ghag 2023-05-19 12213 4ddbcb886268af Aditi Ghag 2023-05-19 12214 static const struct btf_kfunc_id_set bpf_sk_iter_kfunc_set = { 4ddbcb886268af Aditi Ghag 2023-05-19 12215 .owner = THIS_MODULE, 4ddbcb886268af Aditi Ghag 2023-05-19 12216 .set = &bpf_sk_iter_kfunc_ids, 4ddbcb886268af Aditi Ghag 2023-05-19 12217 .filter = tracing_iter_filter, 4ddbcb886268af Aditi Ghag 2023-05-19 12218 }; 4ddbcb886268af Aditi Ghag 2023-05-19 12219 4ddbcb886268af Aditi Ghag 2023-05-19 12220 static int init_subsystem(void) 4ddbcb886268af Aditi Ghag 2023-05-19 12221 { 4ddbcb886268af Aditi Ghag 2023-05-19 12222 return register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &bpf_sk_iter_kfunc_set); 4ddbcb886268af Aditi Ghag 2023-05-19 12223 } 4ddbcb886268af Aditi Ghag 2023-05-19 @12224 late_initcall(init_subsystem);
On Wed, Jan 8, 2025 at 2:52 PM Song Liu <song@kernel.org> wrote: > > btf_kfunc_id_set.remap can pick proper version of a kfunc for the calling > context. Use this logic to select bpf_dynptr_from_skb or > bpf_dynptr_from_skb_rdonly. This will make the verifier simpler. > > Unfortunately, btf_kfunc_id_set.remap cannot cover the DYNPTR_TYPE_SKB > logic in check_kfunc_args(). This can be addressed later. > > Signed-off-by: Song Liu <song@kernel.org> > --- > kernel/bpf/verifier.c | 25 ++++++---------------- > net/core/filter.c | 49 +++++++++++++++++++++++++++++++++++++++---- > 2 files changed, 51 insertions(+), 23 deletions(-) > > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c > index c321fd25fca3..95b0847191fe 100644 > --- a/kernel/bpf/verifier.c > +++ b/kernel/bpf/verifier.c > @@ -11677,6 +11677,7 @@ enum special_kfunc_type { > KF_bpf_rbtree_add_impl, > KF_bpf_rbtree_first, > KF_bpf_dynptr_from_skb, > + KF_bpf_dynptr_from_skb_rdonly, > KF_bpf_dynptr_from_xdp, > KF_bpf_dynptr_slice, > KF_bpf_dynptr_slice_rdwr, > @@ -11712,6 +11713,7 @@ BTF_ID(func, bpf_rbtree_add_impl) > BTF_ID(func, bpf_rbtree_first) > #ifdef CONFIG_NET > BTF_ID(func, bpf_dynptr_from_skb) > +BTF_ID(func, bpf_dynptr_from_skb_rdonly) > BTF_ID(func, bpf_dynptr_from_xdp) > #endif > BTF_ID(func, bpf_dynptr_slice) > @@ -11743,10 +11745,12 @@ BTF_ID(func, bpf_rbtree_add_impl) > BTF_ID(func, bpf_rbtree_first) > #ifdef CONFIG_NET > BTF_ID(func, bpf_dynptr_from_skb) > +BTF_ID(func, bpf_dynptr_from_skb_rdonly) > BTF_ID(func, bpf_dynptr_from_xdp) > #else > BTF_ID_UNUSED > BTF_ID_UNUSED > +BTF_ID_UNUSED > #endif > BTF_ID(func, bpf_dynptr_slice) > BTF_ID(func, bpf_dynptr_slice_rdwr) > @@ -12668,7 +12672,8 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_ > if (is_kfunc_arg_uninit(btf, &args[i])) > dynptr_arg_type |= MEM_UNINIT; > > - if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_skb]) { > + if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_skb] || > + meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_skb_rdonly]) { > dynptr_arg_type |= DYNPTR_TYPE_SKB; > } else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_xdp]) { > dynptr_arg_type |= DYNPTR_TYPE_XDP; > @@ -20821,9 +20826,7 @@ static void specialize_kfunc(struct bpf_verifier_env *env, > u32 func_id, u16 offset, unsigned long *addr) > { > struct bpf_prog *prog = env->prog; > - bool seen_direct_write; > void *xdp_kfunc; > - bool is_rdonly; > > if (bpf_dev_bound_kfunc_id(func_id)) { > xdp_kfunc = bpf_dev_bound_resolve_kfunc(prog, func_id); > @@ -20833,22 +20836,6 @@ static void specialize_kfunc(struct bpf_verifier_env *env, > } > /* fallback to default kfunc when not supported by netdev */ > } > - > - if (offset) > - return; > - > - if (func_id == special_kfunc_list[KF_bpf_dynptr_from_skb]) { > - seen_direct_write = env->seen_direct_write; > - is_rdonly = !may_access_direct_pkt_data(env, NULL, BPF_WRITE); > - > - if (is_rdonly) > - *addr = (unsigned long)bpf_dynptr_from_skb_rdonly; > - > - /* restore env->seen_direct_write to its original value, since > - * may_access_direct_pkt_data mutates it > - */ > - env->seen_direct_write = seen_direct_write; is it safe to remove this special seen_direct_write part of logic? > - } > } > > static void __fixup_collection_insert_kfunc(struct bpf_insn_aux_data *insn_aux, > diff --git a/net/core/filter.c b/net/core/filter.c > index 21131ec25f24..f12bcc1b21d1 100644 > --- a/net/core/filter.c > +++ b/net/core/filter.c > @@ -12047,10 +12047,8 @@ __bpf_kfunc int bpf_sk_assign_tcp_reqsk(struct __sk_buff *s, struct sock *sk, > #endif > } > > -__bpf_kfunc_end_defs(); > - > -int bpf_dynptr_from_skb_rdonly(struct __sk_buff *skb, u64 flags, > - struct bpf_dynptr *ptr__uninit) > +__bpf_kfunc int bpf_dynptr_from_skb_rdonly(struct __sk_buff *skb, u64 flags, > + struct bpf_dynptr *ptr__uninit) > { > struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)ptr__uninit; > int err; > @@ -12064,10 +12062,16 @@ int bpf_dynptr_from_skb_rdonly(struct __sk_buff *skb, u64 flags, > return 0; > } > > +__bpf_kfunc_end_defs(); > + > BTF_KFUNCS_START(bpf_kfunc_check_set_skb) > BTF_ID_FLAGS(func, bpf_dynptr_from_skb, KF_TRUSTED_ARGS) > BTF_KFUNCS_END(bpf_kfunc_check_set_skb) > > +BTF_HIDDEN_KFUNCS_START(bpf_kfunc_check_hidden_set_skb) > +BTF_ID_FLAGS(func, bpf_dynptr_from_skb_rdonly, KF_TRUSTED_ARGS) > +BTF_KFUNCS_END(bpf_kfunc_check_hidden_set_skb) > + > BTF_KFUNCS_START(bpf_kfunc_check_set_xdp) > BTF_ID_FLAGS(func, bpf_dynptr_from_xdp) > BTF_KFUNCS_END(bpf_kfunc_check_set_xdp) > @@ -12080,9 +12084,46 @@ BTF_KFUNCS_START(bpf_kfunc_check_set_tcp_reqsk) > BTF_ID_FLAGS(func, bpf_sk_assign_tcp_reqsk, KF_TRUSTED_ARGS) > BTF_KFUNCS_END(bpf_kfunc_check_set_tcp_reqsk) > > +BTF_ID_LIST(bpf_dynptr_from_skb_list) > +BTF_ID(func, bpf_dynptr_from_skb) > +BTF_ID(func, bpf_dynptr_from_skb_rdonly) > + > +static u32 bpf_kfunc_set_skb_remap(const struct bpf_prog *prog, u32 kfunc_id) > +{ > + if (kfunc_id != bpf_dynptr_from_skb_list[0]) > + return 0; > + > + switch (resolve_prog_type(prog)) { > + /* Program types only with direct read access go here! */ > + case BPF_PROG_TYPE_LWT_IN: > + case BPF_PROG_TYPE_LWT_OUT: > + case BPF_PROG_TYPE_LWT_SEG6LOCAL: > + case BPF_PROG_TYPE_SK_REUSEPORT: > + case BPF_PROG_TYPE_FLOW_DISSECTOR: > + case BPF_PROG_TYPE_CGROUP_SKB: > + return bpf_dynptr_from_skb_list[1]; > + > + /* Program types with direct read + write access go here! */ > + case BPF_PROG_TYPE_SCHED_CLS: > + case BPF_PROG_TYPE_SCHED_ACT: > + case BPF_PROG_TYPE_XDP: > + case BPF_PROG_TYPE_LWT_XMIT: > + case BPF_PROG_TYPE_SK_SKB: > + case BPF_PROG_TYPE_SK_MSG: > + case BPF_PROG_TYPE_CGROUP_SOCKOPT: > + return kfunc_id; > + > + default: > + break; > + } > + return bpf_dynptr_from_skb_list[1]; > +} I'd personally prefer the approach we have with BPF helpers, where each program type has a function that handles all helpers (identified by its ID), and then we can use C code sharing to minimize duplication of code. With this approach it seems like we'll have more duplication and we'll need to repeat these program type-based large switches for various small sets of kfuncs, no? > + > static const struct btf_kfunc_id_set bpf_kfunc_set_skb = { > .owner = THIS_MODULE, > .set = &bpf_kfunc_check_set_skb, > + .hidden_set = &bpf_kfunc_check_hidden_set_skb, > + .remap = &bpf_kfunc_set_skb_remap, > }; > > static const struct btf_kfunc_id_set bpf_kfunc_set_xdp = { > -- > 2.43.5 >
> On Jan 14, 2025, at 2:37 PM, Andrii Nakryiko <andrii.nakryiko@gmail.com> wrote: > [...] >> >> if (bpf_dev_bound_kfunc_id(func_id)) { >> xdp_kfunc = bpf_dev_bound_resolve_kfunc(prog, func_id); >> @@ -20833,22 +20836,6 @@ static void specialize_kfunc(struct bpf_verifier_env *env, >> } >> /* fallback to default kfunc when not supported by netdev */ >> } >> - >> - if (offset) >> - return; >> - >> - if (func_id == special_kfunc_list[KF_bpf_dynptr_from_skb]) { >> - seen_direct_write = env->seen_direct_write; >> - is_rdonly = !may_access_direct_pkt_data(env, NULL, BPF_WRITE); >> - >> - if (is_rdonly) >> - *addr = (unsigned long)bpf_dynptr_from_skb_rdonly; >> - >> - /* restore env->seen_direct_write to its original value, since >> - * may_access_direct_pkt_data mutates it >> - */ >> - env->seen_direct_write = seen_direct_write; > > is it safe to remove this special seen_direct_write part of logic? We need to save and restore seen_direct_write because may_access_direct_pkt_data() mutates it. If we do not call may_access_direct_pkt_data() here, as after this patch, we don't need to save and restore seen_direct_write. > >> - } >> } >> >> static void __fixup_collection_insert_kfunc(struct bpf_insn_aux_data *insn_aux, >> diff --git a/net/core/filter.c b/net/core/filter.c >> index 21131ec25f24..f12bcc1b21d1 100644 >> --- a/net/core/filter.c >> +++ b/net/core/filter.c >> @@ -12047,10 +12047,8 @@ __bpf_kfunc int bpf_sk_assign_tcp_reqsk(struct __sk_buff *s, struct sock *sk, >> #endif >> } >> >> -__bpf_kfunc_end_defs(); >> - >> -int bpf_dynptr_from_skb_rdonly(struct __sk_buff *skb, u64 flags, >> - struct bpf_dynptr *ptr__uninit) >> +__bpf_kfunc int bpf_dynptr_from_skb_rdonly(struct __sk_buff *skb, u64 flags, >> + struct bpf_dynptr *ptr__uninit) >> { >> struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)ptr__uninit; >> int err; >> @@ -12064,10 +12062,16 @@ int bpf_dynptr_from_skb_rdonly(struct __sk_buff *skb, u64 flags, >> return 0; >> } [...] >> + >> +static u32 bpf_kfunc_set_skb_remap(const struct bpf_prog *prog, u32 kfunc_id) >> +{ >> + if (kfunc_id != bpf_dynptr_from_skb_list[0]) >> + return 0; >> + >> + switch (resolve_prog_type(prog)) { >> + /* Program types only with direct read access go here! */ >> + case BPF_PROG_TYPE_LWT_IN: >> + case BPF_PROG_TYPE_LWT_OUT: >> + case BPF_PROG_TYPE_LWT_SEG6LOCAL: >> + case BPF_PROG_TYPE_SK_REUSEPORT: >> + case BPF_PROG_TYPE_FLOW_DISSECTOR: >> + case BPF_PROG_TYPE_CGROUP_SKB: >> + return bpf_dynptr_from_skb_list[1]; >> + >> + /* Program types with direct read + write access go here! */ >> + case BPF_PROG_TYPE_SCHED_CLS: >> + case BPF_PROG_TYPE_SCHED_ACT: >> + case BPF_PROG_TYPE_XDP: >> + case BPF_PROG_TYPE_LWT_XMIT: >> + case BPF_PROG_TYPE_SK_SKB: >> + case BPF_PROG_TYPE_SK_MSG: >> + case BPF_PROG_TYPE_CGROUP_SOCKOPT: >> + return kfunc_id; >> + >> + default: >> + break; >> + } >> + return bpf_dynptr_from_skb_list[1]; >> +} > > I'd personally prefer the approach we have with BPF helpers, where > each program type has a function that handles all helpers (identified > by its ID), and then we can use C code sharing to minimize duplication > of code. Different hooks of the same program type, especially struct_ops, may not have same access to different kfuncs. Therefore, I am not sure whether the approach with helpers can scale in the long term. At the moment, we use special_kfunc_[type|set|list] to handle special cases. But I am afraid this approach cannot work well with more struct_ops and kfuncs. > > With this approach it seems like we'll have more duplication and we'll > need to repeat these program type-based large switches for various > small sets of kfuncs, no? The motivation is to make the verification of kfuncs more modular, so that each set of kfuncs handle their verification as much as possible. I think the code duplication here (bpf_kfunc_set_skb_remap) is not a common problem. And we can actually reduce duplication with some simple helpers. Does this make sense? Thanks, Song
On Tue, Jan 14, 2025 at 3:03 PM Song Liu <songliubraving@meta.com> wrote: > > > > > On Jan 14, 2025, at 2:37 PM, Andrii Nakryiko <andrii.nakryiko@gmail.com> wrote: > > > > [...] > > >> > >> if (bpf_dev_bound_kfunc_id(func_id)) { > >> xdp_kfunc = bpf_dev_bound_resolve_kfunc(prog, func_id); > >> @@ -20833,22 +20836,6 @@ static void specialize_kfunc(struct bpf_verifier_env *env, > >> } > >> /* fallback to default kfunc when not supported by netdev */ > >> } > >> - > >> - if (offset) > >> - return; > >> - > >> - if (func_id == special_kfunc_list[KF_bpf_dynptr_from_skb]) { > >> - seen_direct_write = env->seen_direct_write; > >> - is_rdonly = !may_access_direct_pkt_data(env, NULL, BPF_WRITE); > >> - > >> - if (is_rdonly) > >> - *addr = (unsigned long)bpf_dynptr_from_skb_rdonly; > >> - > >> - /* restore env->seen_direct_write to its original value, since > >> - * may_access_direct_pkt_data mutates it > >> - */ > >> - env->seen_direct_write = seen_direct_write; > > > > is it safe to remove this special seen_direct_write part of logic? > > We need to save and restore seen_direct_write because > may_access_direct_pkt_data() mutates it. If we do not call > may_access_direct_pkt_data() here, as after this patch, we don't need to > save and restore seen_direct_write. > ah, existing logic is quite convoluted (and that resolve_prog_type() bit is another gotcha that's easy to miss), ok, so we used some side-effecting function for simulating side effect-free check... > > > >> - } > >> } > >> > >> static void __fixup_collection_insert_kfunc(struct bpf_insn_aux_data *insn_aux, > >> diff --git a/net/core/filter.c b/net/core/filter.c > >> index 21131ec25f24..f12bcc1b21d1 100644 > >> --- a/net/core/filter.c > >> +++ b/net/core/filter.c > >> @@ -12047,10 +12047,8 @@ __bpf_kfunc int bpf_sk_assign_tcp_reqsk(struct __sk_buff *s, struct sock *sk, > >> #endif > >> } > >> > >> -__bpf_kfunc_end_defs(); > >> - > >> -int bpf_dynptr_from_skb_rdonly(struct __sk_buff *skb, u64 flags, > >> - struct bpf_dynptr *ptr__uninit) > >> +__bpf_kfunc int bpf_dynptr_from_skb_rdonly(struct __sk_buff *skb, u64 flags, > >> + struct bpf_dynptr *ptr__uninit) > >> { > >> struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)ptr__uninit; > >> int err; > >> @@ -12064,10 +12062,16 @@ int bpf_dynptr_from_skb_rdonly(struct __sk_buff *skb, u64 flags, > >> return 0; > >> } > > [...] > > >> + > >> +static u32 bpf_kfunc_set_skb_remap(const struct bpf_prog *prog, u32 kfunc_id) > >> +{ > >> + if (kfunc_id != bpf_dynptr_from_skb_list[0]) > >> + return 0; > >> + > >> + switch (resolve_prog_type(prog)) { > >> + /* Program types only with direct read access go here! */ > >> + case BPF_PROG_TYPE_LWT_IN: > >> + case BPF_PROG_TYPE_LWT_OUT: > >> + case BPF_PROG_TYPE_LWT_SEG6LOCAL: > >> + case BPF_PROG_TYPE_SK_REUSEPORT: > >> + case BPF_PROG_TYPE_FLOW_DISSECTOR: > >> + case BPF_PROG_TYPE_CGROUP_SKB: > >> + return bpf_dynptr_from_skb_list[1]; > >> + > >> + /* Program types with direct read + write access go here! */ > >> + case BPF_PROG_TYPE_SCHED_CLS: > >> + case BPF_PROG_TYPE_SCHED_ACT: > >> + case BPF_PROG_TYPE_XDP: > >> + case BPF_PROG_TYPE_LWT_XMIT: > >> + case BPF_PROG_TYPE_SK_SKB: > >> + case BPF_PROG_TYPE_SK_MSG: > >> + case BPF_PROG_TYPE_CGROUP_SOCKOPT: > >> + return kfunc_id; > >> + > >> + default: > >> + break; > >> + } > >> + return bpf_dynptr_from_skb_list[1]; > >> +} > > > > I'd personally prefer the approach we have with BPF helpers, where > > each program type has a function that handles all helpers (identified > > by its ID), and then we can use C code sharing to minimize duplication > > of code. > > Different hooks of the same program type, especially struct_ops, may > not have same access to different kfuncs. Therefore, I am not sure > whether the approach with helpers can scale in the long term. At the > moment, we use special_kfunc_[type|set|list] to handle special cases. > But I am afraid this approach cannot work well with more struct_ops > and kfuncs. > I think we had discussion in the similar vein at last LSF/MM/BPF. struct_ops is sort of a "meta program type", I don't consider it to be sufficient by itself. For struct_ops you need to know which exact struct_ops callback is being considered (that's what would identify "BPF program type" in the pre-struct_ops world). But anyways, somehow BPF helpers approach worked across lots of program types, not sure I see why it wouldn't work for kfuncs (especially taking into account extending struct_ops with more detailed "which struct_ops callback" bit). > > > > With this approach it seems like we'll have more duplication and we'll > > need to repeat these program type-based large switches for various > > small sets of kfuncs, no? > > The motivation is to make the verification of kfuncs more modular, so > that each set of kfuncs handle their verification as much as possible. > > I think the code duplication here (bpf_kfunc_set_skb_remap) is not a > common problem. And we can actually reduce duplication with some > simple helpers. > > Does this make sense? see above, I'm a bit skeptical, buf proof is in the pudding ;) > > Thanks, > Song > >
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index c321fd25fca3..95b0847191fe 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -11677,6 +11677,7 @@ enum special_kfunc_type { KF_bpf_rbtree_add_impl, KF_bpf_rbtree_first, KF_bpf_dynptr_from_skb, + KF_bpf_dynptr_from_skb_rdonly, KF_bpf_dynptr_from_xdp, KF_bpf_dynptr_slice, KF_bpf_dynptr_slice_rdwr, @@ -11712,6 +11713,7 @@ BTF_ID(func, bpf_rbtree_add_impl) BTF_ID(func, bpf_rbtree_first) #ifdef CONFIG_NET BTF_ID(func, bpf_dynptr_from_skb) +BTF_ID(func, bpf_dynptr_from_skb_rdonly) BTF_ID(func, bpf_dynptr_from_xdp) #endif BTF_ID(func, bpf_dynptr_slice) @@ -11743,10 +11745,12 @@ BTF_ID(func, bpf_rbtree_add_impl) BTF_ID(func, bpf_rbtree_first) #ifdef CONFIG_NET BTF_ID(func, bpf_dynptr_from_skb) +BTF_ID(func, bpf_dynptr_from_skb_rdonly) BTF_ID(func, bpf_dynptr_from_xdp) #else BTF_ID_UNUSED BTF_ID_UNUSED +BTF_ID_UNUSED #endif BTF_ID(func, bpf_dynptr_slice) BTF_ID(func, bpf_dynptr_slice_rdwr) @@ -12668,7 +12672,8 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_ if (is_kfunc_arg_uninit(btf, &args[i])) dynptr_arg_type |= MEM_UNINIT; - if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_skb]) { + if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_skb] || + meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_skb_rdonly]) { dynptr_arg_type |= DYNPTR_TYPE_SKB; } else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_xdp]) { dynptr_arg_type |= DYNPTR_TYPE_XDP; @@ -20821,9 +20826,7 @@ static void specialize_kfunc(struct bpf_verifier_env *env, u32 func_id, u16 offset, unsigned long *addr) { struct bpf_prog *prog = env->prog; - bool seen_direct_write; void *xdp_kfunc; - bool is_rdonly; if (bpf_dev_bound_kfunc_id(func_id)) { xdp_kfunc = bpf_dev_bound_resolve_kfunc(prog, func_id); @@ -20833,22 +20836,6 @@ static void specialize_kfunc(struct bpf_verifier_env *env, } /* fallback to default kfunc when not supported by netdev */ } - - if (offset) - return; - - if (func_id == special_kfunc_list[KF_bpf_dynptr_from_skb]) { - seen_direct_write = env->seen_direct_write; - is_rdonly = !may_access_direct_pkt_data(env, NULL, BPF_WRITE); - - if (is_rdonly) - *addr = (unsigned long)bpf_dynptr_from_skb_rdonly; - - /* restore env->seen_direct_write to its original value, since - * may_access_direct_pkt_data mutates it - */ - env->seen_direct_write = seen_direct_write; - } } static void __fixup_collection_insert_kfunc(struct bpf_insn_aux_data *insn_aux, diff --git a/net/core/filter.c b/net/core/filter.c index 21131ec25f24..f12bcc1b21d1 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -12047,10 +12047,8 @@ __bpf_kfunc int bpf_sk_assign_tcp_reqsk(struct __sk_buff *s, struct sock *sk, #endif } -__bpf_kfunc_end_defs(); - -int bpf_dynptr_from_skb_rdonly(struct __sk_buff *skb, u64 flags, - struct bpf_dynptr *ptr__uninit) +__bpf_kfunc int bpf_dynptr_from_skb_rdonly(struct __sk_buff *skb, u64 flags, + struct bpf_dynptr *ptr__uninit) { struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)ptr__uninit; int err; @@ -12064,10 +12062,16 @@ int bpf_dynptr_from_skb_rdonly(struct __sk_buff *skb, u64 flags, return 0; } +__bpf_kfunc_end_defs(); + BTF_KFUNCS_START(bpf_kfunc_check_set_skb) BTF_ID_FLAGS(func, bpf_dynptr_from_skb, KF_TRUSTED_ARGS) BTF_KFUNCS_END(bpf_kfunc_check_set_skb) +BTF_HIDDEN_KFUNCS_START(bpf_kfunc_check_hidden_set_skb) +BTF_ID_FLAGS(func, bpf_dynptr_from_skb_rdonly, KF_TRUSTED_ARGS) +BTF_KFUNCS_END(bpf_kfunc_check_hidden_set_skb) + BTF_KFUNCS_START(bpf_kfunc_check_set_xdp) BTF_ID_FLAGS(func, bpf_dynptr_from_xdp) BTF_KFUNCS_END(bpf_kfunc_check_set_xdp) @@ -12080,9 +12084,46 @@ BTF_KFUNCS_START(bpf_kfunc_check_set_tcp_reqsk) BTF_ID_FLAGS(func, bpf_sk_assign_tcp_reqsk, KF_TRUSTED_ARGS) BTF_KFUNCS_END(bpf_kfunc_check_set_tcp_reqsk) +BTF_ID_LIST(bpf_dynptr_from_skb_list) +BTF_ID(func, bpf_dynptr_from_skb) +BTF_ID(func, bpf_dynptr_from_skb_rdonly) + +static u32 bpf_kfunc_set_skb_remap(const struct bpf_prog *prog, u32 kfunc_id) +{ + if (kfunc_id != bpf_dynptr_from_skb_list[0]) + return 0; + + switch (resolve_prog_type(prog)) { + /* Program types only with direct read access go here! */ + case BPF_PROG_TYPE_LWT_IN: + case BPF_PROG_TYPE_LWT_OUT: + case BPF_PROG_TYPE_LWT_SEG6LOCAL: + case BPF_PROG_TYPE_SK_REUSEPORT: + case BPF_PROG_TYPE_FLOW_DISSECTOR: + case BPF_PROG_TYPE_CGROUP_SKB: + return bpf_dynptr_from_skb_list[1]; + + /* Program types with direct read + write access go here! */ + case BPF_PROG_TYPE_SCHED_CLS: + case BPF_PROG_TYPE_SCHED_ACT: + case BPF_PROG_TYPE_XDP: + case BPF_PROG_TYPE_LWT_XMIT: + case BPF_PROG_TYPE_SK_SKB: + case BPF_PROG_TYPE_SK_MSG: + case BPF_PROG_TYPE_CGROUP_SOCKOPT: + return kfunc_id; + + default: + break; + } + return bpf_dynptr_from_skb_list[1]; +} + static const struct btf_kfunc_id_set bpf_kfunc_set_skb = { .owner = THIS_MODULE, .set = &bpf_kfunc_check_set_skb, + .hidden_set = &bpf_kfunc_check_hidden_set_skb, + .remap = &bpf_kfunc_set_skb_remap, }; static const struct btf_kfunc_id_set bpf_kfunc_set_xdp = {
btf_kfunc_id_set.remap can pick proper version of a kfunc for the calling context. Use this logic to select bpf_dynptr_from_skb or bpf_dynptr_from_skb_rdonly. This will make the verifier simpler. Unfortunately, btf_kfunc_id_set.remap cannot cover the DYNPTR_TYPE_SKB logic in check_kfunc_args(). This can be addressed later. Signed-off-by: Song Liu <song@kernel.org> --- kernel/bpf/verifier.c | 25 ++++++---------------- net/core/filter.c | 49 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 51 insertions(+), 23 deletions(-)