From: kernel test robot <lkp@intel.com>
To: chenyuan_fl@163.com, eddyz87@gmail.com, yonghong.song@linux.dev
Cc: llvm@lists.linux.dev, oe-kbuild-all@lists.linux.dev,
andrii@kernel.org, ast@kernel.org, bot+bpf-ci@kernel.org,
bpf@vger.kernel.org, chenyuan@kylinos.cn, chenyuan_fl@163.com,
clm@meta.com, daniel@iogearbox.net, ihor.solodrai@linux.dev,
jolsa@kernel.org, linux-kernel@vger.kernel.org,
martin.lau@kernel.org, martin.lau@linux.dev, memxor@gmail.com,
song@kernel.org
Subject: Re: [PATCH bpf v4 2/2] selftests/bpf: Add regression test for kfunc implicit arg injection
Date: Tue, 2 Jun 2026 19:36:25 +0200 [thread overview]
Message-ID: <202606021934.SXop4khA-lkp@intel.com> (raw)
In-Reply-To: <20260602093836.2632714-3-chenyuan_fl@163.com>
Hi Yuan,
kernel test robot noticed the following build errors:
[auto build test ERROR on bpf/master]
url: https://github.com/intel-lab-lkp/linux/commits/chenyuan_fl-163-com/bpf-Fix-kfunc-implicit-arg-inject-type-detection-to-prevent-invalid-pointer-deref/20260602-175420
base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git master
patch link: https://lore.kernel.org/r/20260602093836.2632714-3-chenyuan_fl%40163.com
patch subject: [PATCH bpf v4 2/2] selftests/bpf: Add regression test for kfunc implicit arg injection
config: x86_64-kexec (https://download.01.org/0day-ci/archive/20260602/202606021934.SXop4khA-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260602/202606021934.SXop4khA-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/202606021934.SXop4khA-lkp@intel.com/
All errors (new ones prefixed by >>):
>> kernel/bpf/verifier.c:12097:5: error: call to undeclared function 'reg_arg_name'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
12097 | reg_arg_name(env, argno));
| ^
>> kernel/bpf/verifier.c:12097:23: error: use of undeclared identifier 'argno'
12097 | reg_arg_name(env, argno));
| ^
2 errors generated.
vim +/reg_arg_name +12097 kernel/bpf/verifier.c
12044
12045 static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_arg_meta *meta,
12046 int insn_idx)
12047 {
12048 const char *func_name = meta->func_name, *ref_tname;
12049 const struct btf *btf = meta->btf;
12050 const struct btf_param *args;
12051 struct btf_record *rec;
12052 u32 i, nargs;
12053 int ret;
12054
12055 args = (const struct btf_param *)(meta->func_proto + 1);
12056 nargs = btf_type_vlen(meta->func_proto);
12057 if (nargs > MAX_BPF_FUNC_REG_ARGS) {
12058 verbose(env, "Function %s has %d > %d args\n", func_name, nargs,
12059 MAX_BPF_FUNC_REG_ARGS);
12060 return -EINVAL;
12061 }
12062
12063 /* Check that BTF function arguments match actual types that the
12064 * verifier sees.
12065 */
12066 for (i = 0; i < nargs; i++) {
12067 struct bpf_reg_state *regs = cur_regs(env), *reg = ®s[i + 1];
12068 const struct btf_type *t, *ref_t, *resolve_ret;
12069 enum bpf_arg_type arg_type = ARG_DONTCARE;
12070 u32 regno = i + 1, ref_id, type_size;
12071 bool is_ret_buf_sz = false;
12072 int kf_arg_type;
12073
12074 if (is_kfunc_arg_prog_aux(btf, &args[i])) {
12075 /* Reject repeated use bpf_prog_aux */
12076 if (meta->arg_prog) {
12077 verifier_bug(env, "Only 1 prog->aux argument supported per-kfunc");
12078 return -EFAULT;
12079 }
12080 meta->arg_prog = true;
12081 cur_aux(env)->arg_prog = regno;
12082 continue;
12083 }
12084
12085 if (is_kfunc_arg_ignore(btf, &args[i]))
12086 continue;
12087
12088 if (is_kfunc_arg_implicit(meta, i)) {
12089 /* list_push / rbtree_add kfuncs have implicit args
12090 * (e.g. 'off' parameter) handled during verification
12091 * in bpf_fixup_kfunc_call(). Don't flag them.
12092 */
12093 if (is_bpf_list_push_kfunc(meta->func_id) ||
12094 is_bpf_rbtree_add_kfunc(meta->func_id))
12095 continue;
12096 verbose(env, "%s unrecognized implicit argument, possible BTF mismatch\n",
12097 reg_arg_name(env, argno));
12098 return -EFAULT;
12099 }
12100
12101 t = btf_type_skip_modifiers(btf, args[i].type, NULL);
12102
12103 if (btf_type_is_scalar(t)) {
12104 if (reg->type != SCALAR_VALUE) {
12105 verbose(env, "R%d is not a scalar\n", regno);
12106 return -EINVAL;
12107 }
12108
12109 if (is_kfunc_arg_constant(meta->btf, &args[i])) {
12110 if (meta->arg_constant.found) {
12111 verifier_bug(env, "only one constant argument permitted");
12112 return -EFAULT;
12113 }
12114 if (!tnum_is_const(reg->var_off)) {
12115 verbose(env, "R%d must be a known constant\n", regno);
12116 return -EINVAL;
12117 }
12118 ret = mark_chain_precision(env, regno);
12119 if (ret < 0)
12120 return ret;
12121 meta->arg_constant.found = true;
12122 meta->arg_constant.value = reg->var_off.value;
12123 } else if (is_kfunc_arg_scalar_with_name(btf, &args[i], "rdonly_buf_size")) {
12124 meta->r0_rdonly = true;
12125 is_ret_buf_sz = true;
12126 } else if (is_kfunc_arg_scalar_with_name(btf, &args[i], "rdwr_buf_size")) {
12127 is_ret_buf_sz = true;
12128 }
12129
12130 if (is_ret_buf_sz) {
12131 if (meta->r0_size) {
12132 verbose(env, "2 or more rdonly/rdwr_buf_size parameters for kfunc");
12133 return -EINVAL;
12134 }
12135
12136 if (!tnum_is_const(reg->var_off)) {
12137 verbose(env, "R%d is not a const\n", regno);
12138 return -EINVAL;
12139 }
12140
12141 meta->r0_size = reg->var_off.value;
12142 ret = mark_chain_precision(env, regno);
12143 if (ret)
12144 return ret;
12145 }
12146 continue;
12147 }
12148
12149 if (!btf_type_is_ptr(t)) {
12150 verbose(env, "Unrecognized arg#%d type %s\n", i, btf_type_str(t));
12151 return -EINVAL;
12152 }
12153
12154 if ((bpf_register_is_null(reg) || type_may_be_null(reg->type)) &&
12155 !is_kfunc_arg_nullable(meta->btf, &args[i])) {
12156 verbose(env, "Possibly NULL pointer passed to trusted arg%d\n", i);
12157 return -EACCES;
12158 }
12159
12160 if (reg->ref_obj_id) {
12161 if (is_kfunc_release(meta) && meta->ref_obj_id) {
12162 verifier_bug(env, "more than one arg with ref_obj_id R%d %u %u",
12163 regno, reg->ref_obj_id,
12164 meta->ref_obj_id);
12165 return -EFAULT;
12166 }
12167 meta->ref_obj_id = reg->ref_obj_id;
12168 if (is_kfunc_release(meta))
12169 meta->release_regno = regno;
12170 }
12171
12172 ref_t = btf_type_skip_modifiers(btf, t->type, &ref_id);
12173 ref_tname = btf_name_by_offset(btf, ref_t->name_off);
12174
12175 kf_arg_type = get_kfunc_ptr_arg_type(env, meta, t, ref_t, ref_tname, args, i, nargs);
12176 if (kf_arg_type < 0)
12177 return kf_arg_type;
12178
12179 switch (kf_arg_type) {
12180 case KF_ARG_PTR_TO_NULL:
12181 continue;
12182 case KF_ARG_PTR_TO_MAP:
12183 if (!reg->map_ptr) {
12184 verbose(env, "pointer in R%d isn't map pointer\n", regno);
12185 return -EINVAL;
12186 }
12187 if (meta->map.ptr && (reg->map_ptr->record->wq_off >= 0 ||
12188 reg->map_ptr->record->task_work_off >= 0)) {
12189 /* Use map_uid (which is unique id of inner map) to reject:
12190 * inner_map1 = bpf_map_lookup_elem(outer_map, key1)
12191 * inner_map2 = bpf_map_lookup_elem(outer_map, key2)
12192 * if (inner_map1 && inner_map2) {
12193 * wq = bpf_map_lookup_elem(inner_map1);
12194 * if (wq)
12195 * // mismatch would have been allowed
12196 * bpf_wq_init(wq, inner_map2);
12197 * }
12198 *
12199 * Comparing map_ptr is enough to distinguish normal and outer maps.
12200 */
12201 if (meta->map.ptr != reg->map_ptr ||
12202 meta->map.uid != reg->map_uid) {
12203 if (reg->map_ptr->record->task_work_off >= 0) {
12204 verbose(env,
12205 "bpf_task_work pointer in R2 map_uid=%d doesn't match map pointer in R3 map_uid=%d\n",
12206 meta->map.uid, reg->map_uid);
12207 return -EINVAL;
12208 }
12209 verbose(env,
12210 "workqueue pointer in R1 map_uid=%d doesn't match map pointer in R2 map_uid=%d\n",
12211 meta->map.uid, reg->map_uid);
12212 return -EINVAL;
12213 }
12214 }
12215 meta->map.ptr = reg->map_ptr;
12216 meta->map.uid = reg->map_uid;
12217 fallthrough;
12218 case KF_ARG_PTR_TO_ALLOC_BTF_ID:
12219 case KF_ARG_PTR_TO_BTF_ID:
12220 if (!is_trusted_reg(reg)) {
12221 if (!is_kfunc_rcu(meta)) {
12222 verbose(env, "R%d must be referenced or trusted\n", regno);
12223 return -EINVAL;
12224 }
12225 if (!is_rcu_reg(reg)) {
12226 verbose(env, "R%d must be a rcu pointer\n", regno);
12227 return -EINVAL;
12228 }
12229 }
12230 fallthrough;
12231 case KF_ARG_PTR_TO_DYNPTR:
12232 case KF_ARG_PTR_TO_ITER:
12233 case KF_ARG_PTR_TO_LIST_HEAD:
12234 case KF_ARG_PTR_TO_LIST_NODE:
12235 case KF_ARG_PTR_TO_RB_ROOT:
12236 case KF_ARG_PTR_TO_RB_NODE:
12237 case KF_ARG_PTR_TO_MEM:
12238 case KF_ARG_PTR_TO_MEM_SIZE:
12239 case KF_ARG_PTR_TO_CALLBACK:
12240 case KF_ARG_PTR_TO_REFCOUNTED_KPTR:
12241 case KF_ARG_PTR_TO_CONST_STR:
12242 case KF_ARG_PTR_TO_WORKQUEUE:
12243 case KF_ARG_PTR_TO_TIMER:
12244 case KF_ARG_PTR_TO_TASK_WORK:
12245 case KF_ARG_PTR_TO_IRQ_FLAG:
12246 case KF_ARG_PTR_TO_RES_SPIN_LOCK:
12247 break;
12248 case KF_ARG_PTR_TO_CTX:
12249 arg_type = ARG_PTR_TO_CTX;
12250 break;
12251 default:
12252 verifier_bug(env, "unknown kfunc arg type %d", kf_arg_type);
12253 return -EFAULT;
12254 }
12255
12256 if (is_kfunc_release(meta) && reg->ref_obj_id)
12257 arg_type |= OBJ_RELEASE;
12258 ret = check_func_arg_reg_off(env, reg, regno, arg_type);
12259 if (ret < 0)
12260 return ret;
12261
12262 switch (kf_arg_type) {
12263 case KF_ARG_PTR_TO_CTX:
12264 if (reg->type != PTR_TO_CTX) {
12265 verbose(env, "arg#%d expected pointer to ctx, but got %s\n",
12266 i, reg_type_str(env, reg->type));
12267 return -EINVAL;
12268 }
12269
12270 if (meta->func_id == special_kfunc_list[KF_bpf_cast_to_kern_ctx]) {
12271 ret = get_kern_ctx_btf_id(&env->log, resolve_prog_type(env->prog));
12272 if (ret < 0)
12273 return -EINVAL;
12274 meta->ret_btf_id = ret;
12275 }
12276 break;
12277 case KF_ARG_PTR_TO_ALLOC_BTF_ID:
12278 if (reg->type == (PTR_TO_BTF_ID | MEM_ALLOC)) {
12279 if (!is_bpf_obj_drop_kfunc(meta->func_id)) {
12280 verbose(env, "arg#%d expected for bpf_obj_drop()\n", i);
12281 return -EINVAL;
12282 }
12283 } else if (reg->type == (PTR_TO_BTF_ID | MEM_ALLOC | MEM_PERCPU)) {
12284 if (!is_bpf_percpu_obj_drop_kfunc(meta->func_id)) {
12285 verbose(env, "arg#%d expected for bpf_percpu_obj_drop()\n", i);
12286 return -EINVAL;
12287 }
12288 } else {
12289 verbose(env, "arg#%d expected pointer to allocated object\n", i);
12290 return -EINVAL;
12291 }
12292 if (!reg->ref_obj_id) {
12293 verbose(env, "allocated object must be referenced\n");
12294 return -EINVAL;
12295 }
12296 if (meta->btf == btf_vmlinux) {
12297 meta->arg_btf = reg->btf;
12298 meta->arg_btf_id = reg->btf_id;
12299 }
12300 break;
12301 case KF_ARG_PTR_TO_DYNPTR:
12302 {
12303 enum bpf_arg_type dynptr_arg_type = ARG_PTR_TO_DYNPTR;
12304 int clone_ref_obj_id = 0;
12305
12306 if (reg->type == CONST_PTR_TO_DYNPTR)
12307 dynptr_arg_type |= MEM_RDONLY;
12308
12309 if (is_kfunc_arg_uninit(btf, &args[i]))
12310 dynptr_arg_type |= MEM_UNINIT;
12311
12312 if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_skb]) {
12313 dynptr_arg_type |= DYNPTR_TYPE_SKB;
12314 } else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_xdp]) {
12315 dynptr_arg_type |= DYNPTR_TYPE_XDP;
12316 } else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_skb_meta]) {
12317 dynptr_arg_type |= DYNPTR_TYPE_SKB_META;
12318 } else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_file]) {
12319 dynptr_arg_type |= DYNPTR_TYPE_FILE;
12320 } else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_file_discard]) {
12321 dynptr_arg_type |= DYNPTR_TYPE_FILE;
12322 meta->release_regno = regno;
12323 } else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_clone] &&
12324 (dynptr_arg_type & MEM_UNINIT)) {
12325 enum bpf_dynptr_type parent_type = meta->initialized_dynptr.type;
12326
12327 if (parent_type == BPF_DYNPTR_TYPE_INVALID) {
12328 verifier_bug(env, "no dynptr type for parent of clone");
12329 return -EFAULT;
12330 }
12331
12332 dynptr_arg_type |= (unsigned int)get_dynptr_type_flag(parent_type);
12333 clone_ref_obj_id = meta->initialized_dynptr.ref_obj_id;
12334 if (dynptr_type_refcounted(parent_type) && !clone_ref_obj_id) {
12335 verifier_bug(env, "missing ref obj id for parent of clone");
12336 return -EFAULT;
12337 }
12338 }
12339
12340 ret = process_dynptr_func(env, regno, insn_idx, dynptr_arg_type, clone_ref_obj_id);
12341 if (ret < 0)
12342 return ret;
12343
12344 if (!(dynptr_arg_type & MEM_UNINIT)) {
12345 int id = dynptr_id(env, reg);
12346
12347 if (id < 0) {
12348 verifier_bug(env, "failed to obtain dynptr id");
12349 return id;
12350 }
12351 meta->initialized_dynptr.id = id;
12352 meta->initialized_dynptr.type = dynptr_get_type(env, reg);
12353 meta->initialized_dynptr.ref_obj_id = dynptr_ref_obj_id(env, reg);
12354 }
12355
12356 break;
12357 }
12358 case KF_ARG_PTR_TO_ITER:
12359 if (meta->func_id == special_kfunc_list[KF_bpf_iter_css_task_new]) {
12360 if (!check_css_task_iter_allowlist(env)) {
12361 verbose(env, "css_task_iter is only allowed in bpf_lsm, bpf_iter and sleepable progs\n");
12362 return -EINVAL;
12363 }
12364 }
12365 ret = process_iter_arg(env, regno, insn_idx, meta);
12366 if (ret < 0)
12367 return ret;
12368 break;
12369 case KF_ARG_PTR_TO_LIST_HEAD:
12370 if (reg->type != PTR_TO_MAP_VALUE &&
12371 reg->type != (PTR_TO_BTF_ID | MEM_ALLOC)) {
12372 verbose(env, "arg#%d expected pointer to map value or allocated object\n", i);
12373 return -EINVAL;
12374 }
12375 if (reg->type == (PTR_TO_BTF_ID | MEM_ALLOC) && !reg->ref_obj_id) {
12376 verbose(env, "allocated object must be referenced\n");
12377 return -EINVAL;
12378 }
12379 ret = process_kf_arg_ptr_to_list_head(env, reg, regno, meta);
12380 if (ret < 0)
12381 return ret;
12382 break;
12383 case KF_ARG_PTR_TO_RB_ROOT:
12384 if (reg->type != PTR_TO_MAP_VALUE &&
12385 reg->type != (PTR_TO_BTF_ID | MEM_ALLOC)) {
12386 verbose(env, "arg#%d expected pointer to map value or allocated object\n", i);
12387 return -EINVAL;
12388 }
12389 if (reg->type == (PTR_TO_BTF_ID | MEM_ALLOC) && !reg->ref_obj_id) {
12390 verbose(env, "allocated object must be referenced\n");
12391 return -EINVAL;
12392 }
12393 ret = process_kf_arg_ptr_to_rbtree_root(env, reg, regno, meta);
12394 if (ret < 0)
12395 return ret;
12396 break;
12397 case KF_ARG_PTR_TO_LIST_NODE:
12398 if (reg->type != (PTR_TO_BTF_ID | MEM_ALLOC)) {
12399 verbose(env, "arg#%d expected pointer to allocated object\n", i);
12400 return -EINVAL;
12401 }
12402 if (!reg->ref_obj_id) {
12403 verbose(env, "allocated object must be referenced\n");
12404 return -EINVAL;
12405 }
12406 ret = process_kf_arg_ptr_to_list_node(env, reg, regno, meta);
12407 if (ret < 0)
12408 return ret;
12409 break;
12410 case KF_ARG_PTR_TO_RB_NODE:
12411 if (is_bpf_rbtree_add_kfunc(meta->func_id)) {
12412 if (reg->type != (PTR_TO_BTF_ID | MEM_ALLOC)) {
12413 verbose(env, "arg#%d expected pointer to allocated object\n", i);
12414 return -EINVAL;
12415 }
12416 if (!reg->ref_obj_id) {
12417 verbose(env, "allocated object must be referenced\n");
12418 return -EINVAL;
12419 }
12420 } else {
12421 if (!type_is_non_owning_ref(reg->type) && !reg->ref_obj_id) {
12422 verbose(env, "%s can only take non-owning or refcounted bpf_rb_node pointer\n", func_name);
12423 return -EINVAL;
12424 }
12425 if (in_rbtree_lock_required_cb(env)) {
12426 verbose(env, "%s not allowed in rbtree cb\n", func_name);
12427 return -EINVAL;
12428 }
12429 }
12430
12431 ret = process_kf_arg_ptr_to_rbtree_node(env, reg, regno, meta);
12432 if (ret < 0)
12433 return ret;
12434 break;
12435 case KF_ARG_PTR_TO_MAP:
12436 /* If argument has '__map' suffix expect 'struct bpf_map *' */
12437 ref_id = *reg2btf_ids[CONST_PTR_TO_MAP];
12438 ref_t = btf_type_by_id(btf_vmlinux, ref_id);
12439 ref_tname = btf_name_by_offset(btf, ref_t->name_off);
12440 fallthrough;
12441 case KF_ARG_PTR_TO_BTF_ID:
12442 /* Only base_type is checked, further checks are done here */
12443 if ((base_type(reg->type) != PTR_TO_BTF_ID ||
12444 (bpf_type_has_unsafe_modifiers(reg->type) && !is_rcu_reg(reg))) &&
12445 !reg2btf_ids[base_type(reg->type)]) {
12446 verbose(env, "arg#%d is %s ", i, reg_type_str(env, reg->type));
12447 verbose(env, "expected %s or socket\n",
12448 reg_type_str(env, base_type(reg->type) |
12449 (type_flag(reg->type) & BPF_REG_TRUSTED_MODIFIERS)));
12450 return -EINVAL;
12451 }
12452 ret = process_kf_arg_ptr_to_btf_id(env, reg, ref_t, ref_tname, ref_id, meta, i);
12453 if (ret < 0)
12454 return ret;
12455 break;
12456 case KF_ARG_PTR_TO_MEM:
12457 resolve_ret = btf_resolve_size(btf, ref_t, &type_size);
12458 if (IS_ERR(resolve_ret)) {
12459 verbose(env, "arg#%d reference type('%s %s') size cannot be determined: %ld\n",
12460 i, btf_type_str(ref_t), ref_tname, PTR_ERR(resolve_ret));
12461 return -EINVAL;
12462 }
12463 ret = check_mem_reg(env, reg, regno, type_size);
12464 if (ret < 0)
12465 return ret;
12466 break;
12467 case KF_ARG_PTR_TO_MEM_SIZE:
12468 {
12469 struct bpf_reg_state *buff_reg = ®s[regno];
12470 const struct btf_param *buff_arg = &args[i];
12471 struct bpf_reg_state *size_reg = ®s[regno + 1];
12472 const struct btf_param *size_arg = &args[i + 1];
12473
12474 if (!bpf_register_is_null(buff_reg) || !is_kfunc_arg_nullable(meta->btf, buff_arg)) {
12475 ret = check_kfunc_mem_size_reg(env, size_reg, regno + 1);
12476 if (ret < 0) {
12477 verbose(env, "arg#%d arg#%d memory, len pair leads to invalid memory access\n", i, i + 1);
12478 return ret;
12479 }
12480 }
12481
12482 if (is_kfunc_arg_const_mem_size(meta->btf, size_arg, size_reg)) {
12483 if (meta->arg_constant.found) {
12484 verifier_bug(env, "only one constant argument permitted");
12485 return -EFAULT;
12486 }
12487 if (!tnum_is_const(size_reg->var_off)) {
12488 verbose(env, "R%d must be a known constant\n", regno + 1);
12489 return -EINVAL;
12490 }
12491 meta->arg_constant.found = true;
12492 meta->arg_constant.value = size_reg->var_off.value;
12493 }
12494
12495 /* Skip next '__sz' or '__szk' argument */
12496 i++;
12497 break;
12498 }
12499 case KF_ARG_PTR_TO_CALLBACK:
12500 if (reg->type != PTR_TO_FUNC) {
12501 verbose(env, "arg%d expected pointer to func\n", i);
12502 return -EINVAL;
12503 }
12504 meta->subprogno = reg->subprogno;
12505 break;
12506 case KF_ARG_PTR_TO_REFCOUNTED_KPTR:
12507 if (!type_is_ptr_alloc_obj(reg->type)) {
12508 verbose(env, "arg#%d is neither owning or non-owning ref\n", i);
12509 return -EINVAL;
12510 }
12511 if (!type_is_non_owning_ref(reg->type))
12512 meta->arg_owning_ref = true;
12513
12514 rec = reg_btf_record(reg);
12515 if (!rec) {
12516 verifier_bug(env, "Couldn't find btf_record");
12517 return -EFAULT;
12518 }
12519
12520 if (rec->refcount_off < 0) {
12521 verbose(env, "arg#%d doesn't point to a type with bpf_refcount field\n", i);
12522 return -EINVAL;
12523 }
12524
12525 meta->arg_btf = reg->btf;
12526 meta->arg_btf_id = reg->btf_id;
12527 break;
12528 case KF_ARG_PTR_TO_CONST_STR:
12529 if (reg->type != PTR_TO_MAP_VALUE) {
12530 verbose(env, "arg#%d doesn't point to a const string\n", i);
12531 return -EINVAL;
12532 }
12533 ret = check_reg_const_str(env, reg, regno);
12534 if (ret)
12535 return ret;
12536 break;
12537 case KF_ARG_PTR_TO_WORKQUEUE:
12538 if (reg->type != PTR_TO_MAP_VALUE) {
12539 verbose(env, "arg#%d doesn't point to a map value\n", i);
12540 return -EINVAL;
12541 }
12542 ret = check_map_field_pointer(env, regno, BPF_WORKQUEUE, &meta->map);
12543 if (ret < 0)
12544 return ret;
12545 break;
12546 case KF_ARG_PTR_TO_TIMER:
12547 if (reg->type != PTR_TO_MAP_VALUE) {
12548 verbose(env, "arg#%d doesn't point to a map value\n", i);
12549 return -EINVAL;
12550 }
12551 ret = process_timer_kfunc(env, regno, meta);
12552 if (ret < 0)
12553 return ret;
12554 break;
12555 case KF_ARG_PTR_TO_TASK_WORK:
12556 if (reg->type != PTR_TO_MAP_VALUE) {
12557 verbose(env, "arg#%d doesn't point to a map value\n", i);
12558 return -EINVAL;
12559 }
12560 ret = check_map_field_pointer(env, regno, BPF_TASK_WORK, &meta->map);
12561 if (ret < 0)
12562 return ret;
12563 break;
12564 case KF_ARG_PTR_TO_IRQ_FLAG:
12565 if (reg->type != PTR_TO_STACK) {
12566 verbose(env, "arg#%d doesn't point to an irq flag on stack\n", i);
12567 return -EINVAL;
12568 }
12569 ret = process_irq_flag(env, regno, meta);
12570 if (ret < 0)
12571 return ret;
12572 break;
12573 case KF_ARG_PTR_TO_RES_SPIN_LOCK:
12574 {
12575 int flags = PROCESS_RES_LOCK;
12576
12577 if (reg->type != PTR_TO_MAP_VALUE && reg->type != (PTR_TO_BTF_ID | MEM_ALLOC)) {
12578 verbose(env, "arg#%d doesn't point to map value or allocated object\n", i);
12579 return -EINVAL;
12580 }
12581
12582 if (!is_bpf_res_spin_lock_kfunc(meta->func_id))
12583 return -EFAULT;
12584 if (meta->func_id == special_kfunc_list[KF_bpf_res_spin_lock] ||
12585 meta->func_id == special_kfunc_list[KF_bpf_res_spin_lock_irqsave])
12586 flags |= PROCESS_SPIN_LOCK;
12587 if (meta->func_id == special_kfunc_list[KF_bpf_res_spin_lock_irqsave] ||
12588 meta->func_id == special_kfunc_list[KF_bpf_res_spin_unlock_irqrestore])
12589 flags |= PROCESS_LOCK_IRQ;
12590 ret = process_spin_lock(env, regno, flags);
12591 if (ret < 0)
12592 return ret;
12593 break;
12594 }
12595 }
12596 }
12597
12598 if (is_kfunc_release(meta) && !meta->release_regno) {
12599 verbose(env, "release kernel function %s expects refcounted PTR_TO_BTF_ID\n",
12600 func_name);
12601 return -EINVAL;
12602 }
12603
12604 return 0;
12605 }
12606
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
next prev parent reply other threads:[~2026-06-02 17:36 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-07 8:09 [PATCH] bpf: fix btf_types_are_same for cross-BTF type comparison chenyuan_fl
2026-04-07 8:58 ` Leon Hwang
2026-04-07 9:01 ` bot+bpf-ci
2026-04-07 11:19 ` Alan Maguire
2026-05-15 18:27 ` Ihor Solodrai
2026-06-01 6:46 ` [PATCH bpf v2 0/2] bpf: Fix kfunc implicit arg injection and add selftest chenyuan_fl
2026-06-01 6:46 ` [PATCH bpf v2 1/2] bpf: Fix kfunc implicit arg inject type detection to prevent invalid pointer deref chenyuan_fl
2026-06-01 7:42 ` bot+bpf-ci
2026-06-01 19:32 ` Eduard Zingerman
2026-06-02 8:58 ` [PATCH bpf v3 0/2] bpf: Fix kfunc implicit arg injection and add selftest chenyuan_fl
2026-06-02 8:58 ` [PATCH bpf v3 1/2] bpf: Fix kfunc implicit arg inject type detection to prevent invalid pointer deref chenyuan_fl
2026-06-02 9:23 ` sashiko-bot
2026-06-02 9:44 ` bot+bpf-ci
2026-06-02 18:52 ` Ihor Solodrai
2026-06-04 9:14 ` chenyuan
2026-06-04 10:21 ` Alan Maguire
2026-06-02 8:58 ` [PATCH bpf v3 2/2] selftests/bpf: Add regression test for kfunc implicit arg injection chenyuan_fl
2026-06-02 9:31 ` sashiko-bot
2026-06-02 9:44 ` bot+bpf-ci
2026-06-02 9:38 ` [PATCH bpf v4 0/2] bpf: Fix kfunc implicit arg injection and add selftest chenyuan_fl
2026-06-02 9:38 ` [PATCH bpf v4 1/2] bpf: Fix kfunc implicit arg inject type detection to prevent invalid pointer deref chenyuan_fl
2026-06-02 9:58 ` sashiko-bot
2026-06-02 10:42 ` bot+bpf-ci
2026-06-05 0:42 ` Eduard Zingerman
2026-06-02 9:38 ` [PATCH bpf v4 2/2] selftests/bpf: Add regression test for kfunc implicit arg injection chenyuan_fl
2026-06-02 10:06 ` sashiko-bot
2026-06-02 10:27 ` bot+bpf-ci
2026-06-02 17:36 ` kernel test robot [this message]
2026-06-02 18:37 ` kernel test robot
2026-06-05 1:29 ` Eduard Zingerman
2026-06-01 17:12 ` [PATCH bpf v2 1/2] bpf: Fix kfunc implicit arg inject type detection to prevent invalid pointer deref Yonghong Song
2026-06-01 21:36 ` Eduard Zingerman
2026-06-01 6:46 ` [PATCH bpf v2 2/2] selftests/bpf: Add regression test for kfunc implicit arg injection with stale register chenyuan_fl
2026-06-01 7:08 ` sashiko-bot
2026-06-01 17:17 ` Yonghong Song
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=202606021934.SXop4khA-lkp@intel.com \
--to=lkp@intel.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bot+bpf-ci@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=chenyuan@kylinos.cn \
--cc=chenyuan_fl@163.com \
--cc=clm@meta.com \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=ihor.solodrai@linux.dev \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=llvm@lists.linux.dev \
--cc=martin.lau@kernel.org \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=oe-kbuild-all@lists.linux.dev \
--cc=song@kernel.org \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.