Hi Yonghong,
[FYI, it's a private test report for your RFC patch.]
[auto build test ERROR on bpf-next/master]
url:
https://github.com/0day-ci/linux/commits/Yonghong-Song/compiler-attribute...
base:
https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
config: arc-randconfig-r043-20211117 (attached as .config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
wget
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O
~/bin/make.cross
chmod +x ~/bin/make.cross
#
https://github.com/0day-ci/linux/commit/07b1ca82a3a2c8779b7451e66b9cd37eb...
git remote add linux-review
https://github.com/0day-ci/linux
git fetch --no-tags linux-review
Yonghong-Song/compiler-attribute-define-__user-as-__attribute__-btf_type_tag-user/20211118-044124
git checkout 07b1ca82a3a2c8779b7451e66b9cd37eb2886c48
# save the attached .config to linux build tree
mkdir build_dir
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir
ARCH=arc SHELL=/bin/bash kernel/bpf/
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp(a)intel.com>
All errors (new ones prefixed by >>):
kernel/bpf/verifier.c: In function 'check_mem_access':
> kernel/bpf/verifier.c:4386:96: error: 'is_user'
undeclared (first use in this function); did you mean 'in_userns'?
4386
| err = check_ctx_access(env, insn_idx, off, size, t, ®_type,
&btf, &btf_id, &is_user);
|
^~~~~~~
|
in_userns
kernel/bpf/verifier.c:4386:96: note: each undeclared identifier is reported only once
for each function it appears in
In file included from include/linux/perf_event.h:25,
from kernel/bpf/verifier.c:20:
At top level:
arch/arc/include/asm/perf_event.h:126:27: warning: 'arc_pmu_cache_map' defined
but not used [-Wunused-const-variable=]
126 | static const unsigned int arc_pmu_cache_map[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] =
{
| ^~~~~~~~~~~~~~~~~
arch/arc/include/asm/perf_event.h:91:27: warning: 'arc_pmu_ev_hw_map' defined
but not used [-Wunused-const-variable=]
91 | static const char * const arc_pmu_ev_hw_map[] = {
| ^~~~~~~~~~~~~~~~~
vim +4386 kernel/bpf/verifier.c
4290
4291 /* check whether memory at (regno + off) is accessible for t = (read | write)
4292 * if t==write, value_regno is a register which value is stored into memory
4293 * if t==read, value_regno is a register which will receive the value from memory
4294 * if t==write && value_regno==-1, some unknown value is stored into
memory
4295 * if t==read && value_regno==-1, don't care what we read from memory
4296 */
4297 static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regno,
4298 int off, int bpf_size, enum bpf_access_type t,
4299 int value_regno, bool strict_alignment_once)
4300 {
4301 struct bpf_reg_state *regs = cur_regs(env);
4302 struct bpf_reg_state *reg = regs + regno;
4303 struct bpf_func_state *state;
4304 int size, err = 0;
4305
4306 size = bpf_size_to_bytes(bpf_size);
4307 if (size < 0)
4308 return size;
4309
4310 /* alignment checks will add in reg->off themselves */
4311 err = check_ptr_alignment(env, reg, off, size, strict_alignment_once);
4312 if (err)
4313 return err;
4314
4315 /* for access checks, reg->off is just part of off */
4316 off += reg->off;
4317
4318 if (reg->type == PTR_TO_MAP_KEY) {
4319 if (t == BPF_WRITE) {
4320 verbose(env, "write to change key R%d not allowed\n", regno);
4321 return -EACCES;
4322 }
4323
4324 err = check_mem_region_access(env, regno, off, size,
4325 reg->map_ptr->key_size, false);
4326 if (err)
4327 return err;
4328 if (value_regno >= 0)
4329 mark_reg_unknown(env, regs, value_regno);
4330 } else if (reg->type == PTR_TO_MAP_VALUE) {
4331 if (t == BPF_WRITE && value_regno >= 0 &&
4332 is_pointer_value(env, value_regno)) {
4333 verbose(env, "R%d leaks addr into map\n", value_regno);
4334 return -EACCES;
4335 }
4336 err = check_map_access_type(env, regno, off, size, t);
4337 if (err)
4338 return err;
4339 err = check_map_access(env, regno, off, size, false);
4340 if (!err && t == BPF_READ && value_regno >= 0) {
4341 struct bpf_map *map = reg->map_ptr;
4342
4343 /* if map is read-only, track its contents as scalars */
4344 if (tnum_is_const(reg->var_off) &&
4345 bpf_map_is_rdonly(map) &&
4346 map->ops->map_direct_value_addr) {
4347 int map_off = off + reg->var_off.value;
4348 u64 val = 0;
4349
4350 err = bpf_map_direct_read(map, map_off, size,
4351 &val);
4352 if (err)
4353 return err;
4354
4355 regs[value_regno].type = SCALAR_VALUE;
4356 __mark_reg_known(®s[value_regno], val);
4357 } else {
4358 mark_reg_unknown(env, regs, value_regno);
4359 }
4360 }
4361 } else if (reg->type == PTR_TO_MEM) {
4362 if (t == BPF_WRITE && value_regno >= 0 &&
4363 is_pointer_value(env, value_regno)) {
4364 verbose(env, "R%d leaks addr into mem\n", value_regno);
4365 return -EACCES;
4366 }
4367 err = check_mem_region_access(env, regno, off, size,
4368 reg->mem_size, false);
4369 if (!err && t == BPF_READ && value_regno >= 0)
4370 mark_reg_unknown(env, regs, value_regno);
4371 } else if (reg->type == PTR_TO_CTX) {
4372 enum bpf_reg_type reg_type = SCALAR_VALUE;
4373 struct btf *btf = NULL;
4374 u32 btf_id = 0;
4375
4376 if (t == BPF_WRITE && value_regno >= 0 &&
4377 is_pointer_value(env, value_regno)) {
4378 verbose(env, "R%d leaks addr into ctx\n", value_regno);
4379 return -EACCES;
4380 }
4381
4382 err = check_ctx_reg(env, reg, regno);
4383 if (err < 0)
4384 return err;
4385
4386 err = check_ctx_access(env, insn_idx, off, size, t,
®_type, &btf, &btf_id, &is_user);
4387 if (err)
4388 verbose_linfo(env, insn_idx, "; ");
4389 if (!err && t == BPF_READ && value_regno >= 0) {
4390 /* ctx access returns either a scalar, or a
4391 * PTR_TO_PACKET[_META,_END]. In the latter
4392 * case, we know the offset is zero.
4393 */
4394 if (reg_type == SCALAR_VALUE) {
4395 mark_reg_unknown(env, regs, value_regno);
4396 } else {
4397 mark_reg_known_zero(env, regs,
4398 value_regno);
4399 if (reg_type_may_be_null(reg_type))
4400 regs[value_regno].id = ++env->id_gen;
4401 /* A load of ctx field could have different
4402 * actual load size with the one encoded in the
4403 * insn. When the dst is PTR, it is for sure not
4404 * a sub-register.
4405 */
4406 regs[value_regno].subreg_def = DEF_NOT_SUBREG;
4407 if (reg_type == PTR_TO_BTF_ID ||
4408 reg_type == PTR_TO_BTF_ID_OR_NULL) {
4409 regs[value_regno].btf = btf;
4410 regs[value_regno].btf_id = btf_id;
4411 regs[value_regno].is_user = is_user;
4412 }
4413 }
4414 regs[value_regno].type = reg_type;
4415 }
4416
4417 } else if (reg->type == PTR_TO_STACK) {
4418 /* Basic bounds checks. */
4419 err = check_stack_access_within_bounds(env, regno, off, size, ACCESS_DIRECT, t);
4420 if (err)
4421 return err;
4422
4423 state = func(env, reg);
4424 err = update_stack_depth(env, state, off);
4425 if (err)
4426 return err;
4427
4428 if (t == BPF_READ)
4429 err = check_stack_read(env, regno, off, size,
4430 value_regno);
4431 else
4432 err = check_stack_write(env, regno, off, size,
4433 value_regno, insn_idx);
4434 } else if (reg_is_pkt_pointer(reg)) {
4435 if (t == BPF_WRITE && !may_access_direct_pkt_data(env, NULL, t)) {
4436 verbose(env, "cannot write into packet\n");
4437 return -EACCES;
4438 }
4439 if (t == BPF_WRITE && value_regno >= 0 &&
4440 is_pointer_value(env, value_regno)) {
4441 verbose(env, "R%d leaks addr into packet\n",
4442 value_regno);
4443 return -EACCES;
4444 }
4445 err = check_packet_access(env, regno, off, size, false);
4446 if (!err && t == BPF_READ && value_regno >= 0)
4447 mark_reg_unknown(env, regs, value_regno);
4448 } else if (reg->type == PTR_TO_FLOW_KEYS) {
4449 if (t == BPF_WRITE && value_regno >= 0 &&
4450 is_pointer_value(env, value_regno)) {
4451 verbose(env, "R%d leaks addr into flow keys\n",
4452 value_regno);
4453 return -EACCES;
4454 }
4455
4456 err = check_flow_keys_access(env, off, size);
4457 if (!err && t == BPF_READ && value_regno >= 0)
4458 mark_reg_unknown(env, regs, value_regno);
4459 } else if (type_is_sk_pointer(reg->type)) {
4460 if (t == BPF_WRITE) {
4461 verbose(env, "R%d cannot write into %s\n",
4462 regno, reg_type_str[reg->type]);
4463 return -EACCES;
4464 }
4465 err = check_sock_access(env, insn_idx, regno, off, size, t);
4466 if (!err && value_regno >= 0)
4467 mark_reg_unknown(env, regs, value_regno);
4468 } else if (reg->type == PTR_TO_TP_BUFFER) {
4469 err = check_tp_buffer_access(env, reg, regno, off, size);
4470 if (!err && t == BPF_READ && value_regno >= 0)
4471 mark_reg_unknown(env, regs, value_regno);
4472 } else if (reg->type == PTR_TO_BTF_ID) {
4473 err = check_ptr_to_btf_access(env, regs, regno, off, size, t,
4474 value_regno);
4475 } else if (reg->type == CONST_PTR_TO_MAP) {
4476 err = check_ptr_to_map_access(env, regs, regno, off, size, t,
4477 value_regno);
4478 } else if (reg->type == PTR_TO_RDONLY_BUF) {
4479 if (t == BPF_WRITE) {
4480 verbose(env, "R%d cannot write into %s\n",
4481 regno, reg_type_str[reg->type]);
4482 return -EACCES;
4483 }
4484 err = check_buffer_access(env, reg, regno, off, size, false,
4485 "rdonly",
4486 &env->prog->aux->max_rdonly_access);
4487 if (!err && value_regno >= 0)
4488 mark_reg_unknown(env, regs, value_regno);
4489 } else if (reg->type == PTR_TO_RDWR_BUF) {
4490 err = check_buffer_access(env, reg, regno, off, size, false,
4491 "rdwr",
4492 &env->prog->aux->max_rdwr_access);
4493 if (!err && t == BPF_READ && value_regno >= 0)
4494 mark_reg_unknown(env, regs, value_regno);
4495 } else {
4496 verbose(env, "R%d invalid mem access '%s'\n", regno,
4497 reg_type_str[reg->type]);
4498 return -EACCES;
4499 }
4500
4501 if (!err && size < BPF_REG_SIZE && value_regno >= 0
&& t == BPF_READ &&
4502 regs[value_regno].type == SCALAR_VALUE) {
4503 /* b/h/w load zero-extends, mark upper bits as known 0 */
4504 coerce_reg_to_size(®s[value_regno], size);
4505 }
4506 return err;
4507 }
4508
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org