lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <201912242019.rQeJ2muE%lkp@intel.com>
Date:   Tue, 24 Dec 2019 20:28:24 +0800
From:   kbuild test robot <lkp@...el.com>
To:     Martin KaFai Lau <kafai@...com>
Cc:     kbuild-all@...ts.01.org, bpf@...r.kernel.org,
        Alexei Starovoitov <ast@...nel.org>,
        Daniel Borkmann <daniel@...earbox.net>,
        David Miller <davem@...emloft.net>, kernel-team@...com,
        netdev@...r.kernel.org
Subject: Re: [PATCH bpf-next v2 06/11] bpf: Introduce BPF_MAP_TYPE_STRUCT_OPS

Hi Martin,

I love your patch! Yet something to improve:

[auto build test ERROR on bpf-next/master]
[cannot apply to bpf/master net/master v5.5-rc3 next-20191219]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Martin-KaFai-Lau/Introduce-BPF-STRUCT_OPS/20191224-085617
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
config: arm64-defconfig (attached as .config)
compiler: aarch64-linux-gcc (GCC) 7.5.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=7.5.0 make.cross ARCH=arm64 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@...el.com>

All error/warnings (new ones prefixed by >>):

   kernel/bpf/bpf_struct_ops.c: In function 'bpf_struct_ops_init':
   kernel/bpf/bpf_struct_ops.c:176:8: error: implicit declaration of function 'btf_distill_func_proto'; did you mean 'btf_type_is_func_proto'? [-Werror=implicit-function-declaration]
           btf_distill_func_proto(&log, _btf_vmlinux,
           ^~~~~~~~~~~~~~~~~~~~~~
           btf_type_is_func_proto
   kernel/bpf/bpf_struct_ops.c: In function 'bpf_struct_ops_map_update_elem':
>> kernel/bpf/bpf_struct_ops.c:408:2: error: implicit declaration of function 'bpf_map_inc'; did you mean 'bpf_map_put'? [-Werror=implicit-function-declaration]
     bpf_map_inc(map);
     ^~~~~~~~~~~
     bpf_map_put
   kernel/bpf/bpf_struct_ops.c: In function 'bpf_struct_ops_map_free':
>> kernel/bpf/bpf_struct_ops.c:468:2: error: implicit declaration of function 'bpf_map_area_free'; did you mean 'bpf_prog_free'? [-Werror=implicit-function-declaration]
     bpf_map_area_free(st_map->progs);
     ^~~~~~~~~~~~~~~~~
     bpf_prog_free
   kernel/bpf/bpf_struct_ops.c: In function 'bpf_struct_ops_map_alloc':
   kernel/bpf/bpf_struct_ops.c:515:8: error: implicit declaration of function 'bpf_map_charge_init'; did you mean 'bpf_prog_change_xdp'? [-Werror=implicit-function-declaration]
     err = bpf_map_charge_init(&mem, map_total_size);
           ^~~~~~~~~~~~~~~~~~~
           bpf_prog_change_xdp
>> kernel/bpf/bpf_struct_ops.c:519:11: error: implicit declaration of function 'bpf_map_area_alloc'; did you mean 'bpf_prog_alloc'? [-Werror=implicit-function-declaration]
     st_map = bpf_map_area_alloc(st_map_size, NUMA_NO_NODE);
              ^~~~~~~~~~~~~~~~~~
              bpf_prog_alloc
>> kernel/bpf/bpf_struct_ops.c:519:9: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
     st_map = bpf_map_area_alloc(st_map_size, NUMA_NO_NODE);
            ^
>> kernel/bpf/bpf_struct_ops.c:521:3: error: implicit declaration of function 'bpf_map_charge_finish'; did you mean 'bpf_map_flags_to_cap'? [-Werror=implicit-function-declaration]
      bpf_map_charge_finish(&mem);
      ^~~~~~~~~~~~~~~~~~~~~
      bpf_map_flags_to_cap
   kernel/bpf/bpf_struct_ops.c:527:17: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
     st_map->uvalue = bpf_map_area_alloc(vt->size, NUMA_NO_NODE);
                    ^
   kernel/bpf/bpf_struct_ops.c:528:16: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
     st_map->progs =
                   ^
   kernel/bpf/bpf_struct_ops.c:545:2: error: implicit declaration of function 'bpf_map_init_from_attr'; did you mean 'bpf_jit_get_func_addr'? [-Werror=implicit-function-declaration]
     bpf_map_init_from_attr(map, attr);
     ^~~~~~~~~~~~~~~~~~~~~~
     bpf_jit_get_func_addr
   kernel/bpf/bpf_struct_ops.c:546:2: error: implicit declaration of function 'bpf_map_charge_move'; did you mean 'bpf_prog_change_xdp'? [-Werror=implicit-function-declaration]
     bpf_map_charge_move(&map->memory, &mem);
     ^~~~~~~~~~~~~~~~~~~
     bpf_prog_change_xdp
   cc1: some warnings being treated as errors

vim +408 kernel/bpf/bpf_struct_ops.c

   289	
   290	static int bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
   291						  void *value, u64 flags)
   292	{
   293		struct bpf_struct_ops_map *st_map = (struct bpf_struct_ops_map *)map;
   294		const struct bpf_struct_ops *st_ops = st_map->st_ops;
   295		struct bpf_struct_ops_value *uvalue, *kvalue;
   296		const struct btf_member *member;
   297		const struct btf_type *t = st_ops->type;
   298		void *udata, *kdata;
   299		int prog_fd, err = 0;
   300		void *image;
   301		u32 i;
   302	
   303		if (flags)
   304			return -EINVAL;
   305	
   306		if (*(u32 *)key != 0)
   307			return -E2BIG;
   308	
   309		uvalue = (struct bpf_struct_ops_value *)value;
   310		if (uvalue->state || refcount_read(&uvalue->refcnt))
   311			return -EINVAL;
   312	
   313		uvalue = (struct bpf_struct_ops_value *)st_map->uvalue;
   314		kvalue = (struct bpf_struct_ops_value *)&st_map->kvalue;
   315	
   316		spin_lock(&st_map->lock);
   317	
   318		if (kvalue->state != BPF_STRUCT_OPS_STATE_INIT) {
   319			err = -EBUSY;
   320			goto unlock;
   321		}
   322	
   323		memcpy(uvalue, value, map->value_size);
   324	
   325		udata = &uvalue->data;
   326		kdata = &kvalue->data;
   327		image = st_map->image;
   328	
   329		for_each_member(i, t, member) {
   330			const struct btf_type *mtype, *ptype;
   331			struct bpf_prog *prog;
   332			u32 moff;
   333	
   334			moff = btf_member_bit_offset(t, member) / 8;
   335			mtype = btf_type_by_id(btf_vmlinux, member->type);
   336			ptype = btf_type_resolve_ptr(btf_vmlinux, member->type, NULL);
   337			if (ptype == module_type) {
   338				*(void **)(kdata + moff) = BPF_MODULE_OWNER;
   339				continue;
   340			}
   341	
   342			err = st_ops->init_member(t, member, kdata, udata);
   343			if (err < 0)
   344				goto reset_unlock;
   345	
   346			/* The ->init_member() has handled this member */
   347			if (err > 0)
   348				continue;
   349	
   350			/* If st_ops->init_member does not handle it,
   351			 * we will only handle func ptrs and zero-ed members
   352			 * here.  Reject everything else.
   353			 */
   354	
   355			/* All non func ptr member must be 0 */
   356			if (!btf_type_resolve_func_ptr(btf_vmlinux, member->type,
   357						       NULL)) {
   358				u32 msize;
   359	
   360				mtype = btf_resolve_size(btf_vmlinux, mtype,
   361							 &msize, NULL, NULL);
   362				if (IS_ERR(mtype)) {
   363					err = PTR_ERR(mtype);
   364					goto reset_unlock;
   365				}
   366	
   367				if (memchr_inv(udata + moff, 0, msize)) {
   368					err = -EINVAL;
   369					goto reset_unlock;
   370				}
   371	
   372				continue;
   373			}
   374	
   375			prog_fd = (int)(*(unsigned long *)(udata + moff));
   376			/* Similar check as the attr->attach_prog_fd */
   377			if (!prog_fd)
   378				continue;
   379	
   380			prog = bpf_prog_get(prog_fd);
   381			if (IS_ERR(prog)) {
   382				err = PTR_ERR(prog);
   383				goto reset_unlock;
   384			}
   385			st_map->progs[i] = prog;
   386	
   387			if (prog->type != BPF_PROG_TYPE_STRUCT_OPS ||
   388			    prog->aux->attach_btf_id != st_ops->type_id ||
   389			    prog->expected_attach_type != i) {
   390				err = -EINVAL;
   391				goto reset_unlock;
   392			}
   393	
   394			err = arch_prepare_bpf_trampoline(image,
   395							  &st_ops->func_models[i], 0,
   396							  &prog, 1, NULL, 0, NULL);
   397			if (err < 0)
   398				goto reset_unlock;
   399	
   400			*(void **)(kdata + moff) = image;
   401			image += err;
   402	
   403			/* put prog_id to udata */
   404			*(unsigned long *)(udata + moff) = prog->aux->id;
   405		}
   406	
   407		refcount_set(&kvalue->refcnt, 1);
 > 408		bpf_map_inc(map);
   409	
   410		err = st_ops->reg(kdata);
   411		if (!err) {
   412			/* Pair with smp_load_acquire() during lookup */
   413			smp_store_release(&kvalue->state, BPF_STRUCT_OPS_STATE_INUSE);
   414			goto unlock;
   415		}
   416	
   417		/* Error during st_ops->reg() */
   418		bpf_map_put(map);
   419	
   420	reset_unlock:
   421		bpf_struct_ops_map_put_progs(st_map);
   422		memset(uvalue, 0, map->value_size);
   423		memset(kvalue, 0, map->value_size);
   424	
   425	unlock:
   426		spin_unlock(&st_map->lock);
   427		return err;
   428	}
   429	
   430	static int bpf_struct_ops_map_delete_elem(struct bpf_map *map, void *key)
   431	{
   432		enum bpf_struct_ops_state prev_state;
   433		struct bpf_struct_ops_map *st_map;
   434	
   435		st_map = (struct bpf_struct_ops_map *)map;
   436		prev_state = cmpxchg(&st_map->kvalue.state,
   437				     BPF_STRUCT_OPS_STATE_INUSE,
   438				     BPF_STRUCT_OPS_STATE_TOBEFREE);
   439		if (prev_state == BPF_STRUCT_OPS_STATE_INUSE) {
   440			st_map->st_ops->unreg(&st_map->kvalue.data);
   441			if (refcount_dec_and_test(&st_map->kvalue.refcnt))
   442				bpf_map_put(map);
   443		}
   444	
   445		return 0;
   446	}
   447	
   448	static void bpf_struct_ops_map_seq_show_elem(struct bpf_map *map, void *key,
   449						     struct seq_file *m)
   450	{
   451		void *value;
   452	
   453		value = bpf_struct_ops_map_lookup_elem(map, key);
   454		if (!value)
   455			return;
   456	
   457		btf_type_seq_show(btf_vmlinux, map->btf_vmlinux_value_type_id,
   458				  value, m);
   459		seq_puts(m, "\n");
   460	}
   461	
   462	static void bpf_struct_ops_map_free(struct bpf_map *map)
   463	{
   464		struct bpf_struct_ops_map *st_map = (struct bpf_struct_ops_map *)map;
   465	
   466		if (st_map->progs)
   467			bpf_struct_ops_map_put_progs(st_map);
 > 468		bpf_map_area_free(st_map->progs);
   469		bpf_jit_free_exec(st_map->image);
   470		bpf_map_area_free(st_map->uvalue);
   471		bpf_map_area_free(st_map);
   472	}
   473	
   474	static int bpf_struct_ops_map_alloc_check(union bpf_attr *attr)
   475	{
   476		if (attr->key_size != sizeof(unsigned int) || attr->max_entries != 1 ||
   477		    attr->map_flags || !attr->btf_vmlinux_value_type_id)
   478			return -EINVAL;
   479		return 0;
   480	}
   481	
   482	static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)
   483	{
   484		const struct bpf_struct_ops *st_ops;
   485		size_t map_total_size, st_map_size;
   486		struct bpf_struct_ops_map *st_map;
   487		const struct btf_type *t, *vt;
   488		struct bpf_map_memory mem;
   489		struct bpf_map *map;
   490		int err;
   491	
   492		if (!capable(CAP_SYS_ADMIN))
   493			return ERR_PTR(-EPERM);
   494	
   495		st_ops = bpf_struct_ops_find_value(attr->btf_vmlinux_value_type_id);
   496		if (!st_ops)
   497			return ERR_PTR(-ENOTSUPP);
   498	
   499		vt = st_ops->value_type;
   500		if (attr->value_size != vt->size)
   501			return ERR_PTR(-EINVAL);
   502	
   503		t = st_ops->type;
   504	
   505		st_map_size = sizeof(*st_map) +
   506			/* kvalue stores the
   507			 * struct bpf_struct_ops_tcp_congestions_ops
   508			 */
   509			(vt->size - sizeof(struct bpf_struct_ops_value));
   510		map_total_size = st_map_size +
   511			/* uvalue */
   512			sizeof(vt->size) +
   513			/* struct bpf_progs **progs */
   514			 btf_type_vlen(t) * sizeof(struct bpf_prog *);
 > 515		err = bpf_map_charge_init(&mem, map_total_size);
   516		if (err < 0)
   517			return ERR_PTR(err);
   518	
 > 519		st_map = bpf_map_area_alloc(st_map_size, NUMA_NO_NODE);
   520		if (!st_map) {
 > 521			bpf_map_charge_finish(&mem);
   522			return ERR_PTR(-ENOMEM);
   523		}
   524		st_map->st_ops = st_ops;
   525		map = &st_map->map;
   526	
   527		st_map->uvalue = bpf_map_area_alloc(vt->size, NUMA_NO_NODE);
   528		st_map->progs =
   529			bpf_map_area_alloc(btf_type_vlen(t) * sizeof(struct bpf_prog *),
   530					   NUMA_NO_NODE);
   531		/* Each trampoline costs < 64 bytes.  Ensure one page
   532		 * is enough for max number of func ptrs.
   533		 */
   534		BUILD_BUG_ON(PAGE_SIZE / 64 < BPF_STRUCT_OPS_MAX_NR_MEMBERS);
   535		st_map->image = bpf_jit_alloc_exec(PAGE_SIZE);
   536		if (!st_map->uvalue || !st_map->progs || !st_map->image) {
   537			bpf_struct_ops_map_free(map);
   538			bpf_map_charge_finish(&mem);
   539			return ERR_PTR(-ENOMEM);
   540		}
   541	
   542		spin_lock_init(&st_map->lock);
   543		set_vm_flush_reset_perms(st_map->image);
   544		set_memory_x((long)st_map->image, 1);
   545		bpf_map_init_from_attr(map, attr);
   546		bpf_map_charge_move(&map->memory, &mem);
   547	
   548		return map;
   549	}
   550	

---
0-DAY kernel test infrastructure                 Open Source Technology Center
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org Intel Corporation

Download attachment ".config.gz" of type "application/gzip" (46481 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ