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]
Date:   Sun, 26 Feb 2023 18:14:16 +0800
From:   kernel test robot <lkp@...el.com>
To:     Joanne Koong <joannelkoong@...il.com>, bpf@...r.kernel.org
Cc:     llvm@...ts.linux.dev, oe-kbuild-all@...ts.linux.dev,
        martin.lau@...nel.org, andrii@...nel.org, ast@...nel.org,
        memxor@...il.com, daniel@...earbox.net, netdev@...r.kernel.org,
        toke@...nel.org, Joanne Koong <joannelkoong@...il.com>
Subject: Re: [PATCH v12 bpf-next 09/10] bpf: Add bpf_dynptr_slice and
 bpf_dynptr_slice_rdwr

Hi Joanne,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on bpf-next/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Joanne-Koong/bpf-Support-sk_buff-and-xdp_buff-as-valid-kfunc-arg-types/20230226-165406
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
patch link:    https://lore.kernel.org/r/20230226085120.3907863-10-joannelkoong%40gmail.com
patch subject: [PATCH v12 bpf-next 09/10] bpf: Add bpf_dynptr_slice and bpf_dynptr_slice_rdwr
config: i386-randconfig-a002 (https://download.01.org/0day-ci/archive/20230226/202302261844.BdMQvIkw-lkp@intel.com/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1)
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/intel-lab-lkp/linux/commit/bc5a61c43c72539ef11e6435a168bf240a186ac1
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Joanne-Koong/bpf-Support-sk_buff-and-xdp_buff-as-valid-kfunc-arg-types/20230226-165406
        git checkout bc5a61c43c72539ef11e6435a168bf240a186ac1
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash kernel/bpf/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@...el.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202302261844.BdMQvIkw-lkp@intel.com/

All warnings (new ones prefixed by >>):

   kernel/bpf/verifier.c:6253:5: warning: no previous prototype for function 'process_dynptr_func' [-Wmissing-prototypes]
   int process_dynptr_func(struct bpf_verifier_env *env, int regno, int insn_idx,
       ^
   kernel/bpf/verifier.c:6253:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   int process_dynptr_func(struct bpf_verifier_env *env, int regno, int insn_idx,
   ^
   static 
   kernel/bpf/verifier.c:9907:4: error: expected expression
                           struct bpf_reg_state *size_reg = &regs[regno + 1];
                           ^
   kernel/bpf/verifier.c:9910:40: error: use of undeclared identifier 'size_reg'; did you mean 'size_arg'?
                           ret = check_kfunc_mem_size_reg(env, size_reg, regno + 1);
                                                               ^~~~~~~~
                                                               size_arg
   kernel/bpf/verifier.c:9908:28: note: 'size_arg' declared here
                           const struct btf_param *size_arg = &args[i + 1];
                                                   ^
   kernel/bpf/verifier.c:9916:57: error: use of undeclared identifier 'size_reg'; did you mean 'size_arg'?
                           if (is_kfunc_arg_const_mem_size(meta->btf, size_arg, size_reg)) {
                                                                                ^~~~~~~~
                                                                                size_arg
   kernel/bpf/verifier.c:9908:28: note: 'size_arg' declared here
                           const struct btf_param *size_arg = &args[i + 1];
                                                   ^
   kernel/bpf/verifier.c:9921:24: error: use of undeclared identifier 'size_reg'
                                   if (!tnum_is_const(size_reg->var_off)) {
                                                      ^
   kernel/bpf/verifier.c:9926:32: error: use of undeclared identifier 'size_reg'
                                   meta->arg_constant.value = size_reg->var_off.value;
                                                              ^
>> kernel/bpf/verifier.c:9908:28: warning: mixing declarations and code is incompatible with standards before C99 [-Wdeclaration-after-statement]
                           const struct btf_param *size_arg = &args[i + 1];
                                                   ^
   kernel/bpf/verifier.c:10167:24: warning: array index 16 is past the end of the array (which contains 16 elements) [-Warray-bounds]
                                      meta.func_id == special_kfunc_list[KF_bpf_dynptr_slice_rdwr]) {
                                                      ^                  ~~~~~~~~~~~~~~~~~~~~~~~~
   kernel/bpf/verifier.c:9017:1: note: array 'special_kfunc_list' declared here
   BTF_ID_LIST(special_kfunc_list)
   ^
   include/linux/btf_ids.h:207:27: note: expanded from macro 'BTF_ID_LIST'
   #define BTF_ID_LIST(name) static u32 __maybe_unused name[16];
                             ^
   3 warnings and 5 errors generated.


vim +9908 kernel/bpf/verifier.c

  9584	
  9585	static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_arg_meta *meta,
  9586				    int insn_idx)
  9587	{
  9588		const char *func_name = meta->func_name, *ref_tname;
  9589		const struct btf *btf = meta->btf;
  9590		const struct btf_param *args;
  9591		u32 i, nargs;
  9592		int ret;
  9593	
  9594		args = (const struct btf_param *)(meta->func_proto + 1);
  9595		nargs = btf_type_vlen(meta->func_proto);
  9596		if (nargs > MAX_BPF_FUNC_REG_ARGS) {
  9597			verbose(env, "Function %s has %d > %d args\n", func_name, nargs,
  9598				MAX_BPF_FUNC_REG_ARGS);
  9599			return -EINVAL;
  9600		}
  9601	
  9602		/* Check that BTF function arguments match actual types that the
  9603		 * verifier sees.
  9604		 */
  9605		for (i = 0; i < nargs; i++) {
  9606			struct bpf_reg_state *regs = cur_regs(env), *reg = &regs[i + 1];
  9607			const struct btf_type *t, *ref_t, *resolve_ret;
  9608			enum bpf_arg_type arg_type = ARG_DONTCARE;
  9609			u32 regno = i + 1, ref_id, type_size;
  9610			bool is_ret_buf_sz = false;
  9611			int kf_arg_type;
  9612	
  9613			t = btf_type_skip_modifiers(btf, args[i].type, NULL);
  9614	
  9615			if (is_kfunc_arg_ignore(btf, &args[i]))
  9616				continue;
  9617	
  9618			if (btf_type_is_scalar(t)) {
  9619				if (reg->type != SCALAR_VALUE) {
  9620					verbose(env, "R%d is not a scalar\n", regno);
  9621					return -EINVAL;
  9622				}
  9623	
  9624				if (is_kfunc_arg_constant(meta->btf, &args[i])) {
  9625					if (meta->arg_constant.found) {
  9626						verbose(env, "verifier internal error: only one constant argument permitted\n");
  9627						return -EFAULT;
  9628					}
  9629					if (!tnum_is_const(reg->var_off)) {
  9630						verbose(env, "R%d must be a known constant\n", regno);
  9631						return -EINVAL;
  9632					}
  9633					ret = mark_chain_precision(env, regno);
  9634					if (ret < 0)
  9635						return ret;
  9636					meta->arg_constant.found = true;
  9637					meta->arg_constant.value = reg->var_off.value;
  9638				} else if (is_kfunc_arg_scalar_with_name(btf, &args[i], "rdonly_buf_size")) {
  9639					meta->r0_rdonly = true;
  9640					is_ret_buf_sz = true;
  9641				} else if (is_kfunc_arg_scalar_with_name(btf, &args[i], "rdwr_buf_size")) {
  9642					is_ret_buf_sz = true;
  9643				}
  9644	
  9645				if (is_ret_buf_sz) {
  9646					if (meta->r0_size) {
  9647						verbose(env, "2 or more rdonly/rdwr_buf_size parameters for kfunc");
  9648						return -EINVAL;
  9649					}
  9650	
  9651					if (!tnum_is_const(reg->var_off)) {
  9652						verbose(env, "R%d is not a const\n", regno);
  9653						return -EINVAL;
  9654					}
  9655	
  9656					meta->r0_size = reg->var_off.value;
  9657					ret = mark_chain_precision(env, regno);
  9658					if (ret)
  9659						return ret;
  9660				}
  9661				continue;
  9662			}
  9663	
  9664			if (!btf_type_is_ptr(t)) {
  9665				verbose(env, "Unrecognized arg#%d type %s\n", i, btf_type_str(t));
  9666				return -EINVAL;
  9667			}
  9668	
  9669			if (is_kfunc_trusted_args(meta) &&
  9670			    (register_is_null(reg) || type_may_be_null(reg->type))) {
  9671				verbose(env, "Possibly NULL pointer passed to trusted arg%d\n", i);
  9672				return -EACCES;
  9673			}
  9674	
  9675			if (reg->ref_obj_id) {
  9676				if (is_kfunc_release(meta) && meta->ref_obj_id) {
  9677					verbose(env, "verifier internal error: more than one arg with ref_obj_id R%d %u %u\n",
  9678						regno, reg->ref_obj_id,
  9679						meta->ref_obj_id);
  9680					return -EFAULT;
  9681				}
  9682				meta->ref_obj_id = reg->ref_obj_id;
  9683				if (is_kfunc_release(meta))
  9684					meta->release_regno = regno;
  9685			}
  9686	
  9687			ref_t = btf_type_skip_modifiers(btf, t->type, &ref_id);
  9688			ref_tname = btf_name_by_offset(btf, ref_t->name_off);
  9689	
  9690			kf_arg_type = get_kfunc_ptr_arg_type(env, meta, t, ref_t, ref_tname, args, i, nargs);
  9691			if (kf_arg_type < 0)
  9692				return kf_arg_type;
  9693	
  9694			switch (kf_arg_type) {
  9695			case KF_ARG_PTR_TO_ALLOC_BTF_ID:
  9696			case KF_ARG_PTR_TO_BTF_ID:
  9697				if (!is_kfunc_trusted_args(meta) && !is_kfunc_rcu(meta))
  9698					break;
  9699	
  9700				if (!is_trusted_reg(reg)) {
  9701					if (!is_kfunc_rcu(meta)) {
  9702						verbose(env, "R%d must be referenced or trusted\n", regno);
  9703						return -EINVAL;
  9704					}
  9705					if (!is_rcu_reg(reg)) {
  9706						verbose(env, "R%d must be a rcu pointer\n", regno);
  9707						return -EINVAL;
  9708					}
  9709				}
  9710	
  9711				fallthrough;
  9712			case KF_ARG_PTR_TO_CTX:
  9713				/* Trusted arguments have the same offset checks as release arguments */
  9714				arg_type |= OBJ_RELEASE;
  9715				break;
  9716			case KF_ARG_PTR_TO_KPTR:
  9717			case KF_ARG_PTR_TO_DYNPTR:
  9718			case KF_ARG_PTR_TO_LIST_HEAD:
  9719			case KF_ARG_PTR_TO_LIST_NODE:
  9720			case KF_ARG_PTR_TO_RB_ROOT:
  9721			case KF_ARG_PTR_TO_RB_NODE:
  9722			case KF_ARG_PTR_TO_MEM:
  9723			case KF_ARG_PTR_TO_MEM_SIZE:
  9724			case KF_ARG_PTR_TO_CALLBACK:
  9725				/* Trusted by default */
  9726				break;
  9727			default:
  9728				WARN_ON_ONCE(1);
  9729				return -EFAULT;
  9730			}
  9731	
  9732			if (is_kfunc_release(meta) && reg->ref_obj_id)
  9733				arg_type |= OBJ_RELEASE;
  9734			ret = check_func_arg_reg_off(env, reg, regno, arg_type);
  9735			if (ret < 0)
  9736				return ret;
  9737	
  9738			switch (kf_arg_type) {
  9739			case KF_ARG_PTR_TO_CTX:
  9740				if (reg->type != PTR_TO_CTX) {
  9741					verbose(env, "arg#%d expected pointer to ctx, but got %s\n", i, btf_type_str(t));
  9742					return -EINVAL;
  9743				}
  9744	
  9745				if (meta->func_id == special_kfunc_list[KF_bpf_cast_to_kern_ctx]) {
  9746					ret = get_kern_ctx_btf_id(&env->log, resolve_prog_type(env->prog));
  9747					if (ret < 0)
  9748						return -EINVAL;
  9749					meta->ret_btf_id  = ret;
  9750				}
  9751				break;
  9752			case KF_ARG_PTR_TO_ALLOC_BTF_ID:
  9753				if (reg->type != (PTR_TO_BTF_ID | MEM_ALLOC)) {
  9754					verbose(env, "arg#%d expected pointer to allocated object\n", i);
  9755					return -EINVAL;
  9756				}
  9757				if (!reg->ref_obj_id) {
  9758					verbose(env, "allocated object must be referenced\n");
  9759					return -EINVAL;
  9760				}
  9761				if (meta->btf == btf_vmlinux &&
  9762				    meta->func_id == special_kfunc_list[KF_bpf_obj_drop_impl]) {
  9763					meta->arg_obj_drop.btf = reg->btf;
  9764					meta->arg_obj_drop.btf_id = reg->btf_id;
  9765				}
  9766				break;
  9767			case KF_ARG_PTR_TO_KPTR:
  9768				if (reg->type != PTR_TO_MAP_VALUE) {
  9769					verbose(env, "arg#0 expected pointer to map value\n");
  9770					return -EINVAL;
  9771				}
  9772				ret = process_kf_arg_ptr_to_kptr(env, reg, ref_t, ref_tname, meta, i);
  9773				if (ret < 0)
  9774					return ret;
  9775				break;
  9776			case KF_ARG_PTR_TO_DYNPTR:
  9777			{
  9778				enum bpf_arg_type dynptr_arg_type = ARG_PTR_TO_DYNPTR;
  9779	
  9780				if (reg->type != PTR_TO_STACK &&
  9781				    reg->type != CONST_PTR_TO_DYNPTR) {
  9782					verbose(env, "arg#%d expected pointer to stack or dynptr_ptr\n", i);
  9783					return -EINVAL;
  9784				}
  9785	
  9786				if (reg->type == CONST_PTR_TO_DYNPTR)
  9787					dynptr_arg_type |= MEM_RDONLY;
  9788	
  9789				if (is_kfunc_arg_uninit(btf, &args[i]))
  9790					dynptr_arg_type |= MEM_UNINIT;
  9791	
  9792				if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_skb])
  9793					dynptr_arg_type |= DYNPTR_TYPE_SKB;
  9794				else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_xdp])
  9795					dynptr_arg_type |= DYNPTR_TYPE_XDP;
  9796	
  9797				ret = process_dynptr_func(env, regno, insn_idx, dynptr_arg_type);
  9798				if (ret < 0)
  9799					return ret;
  9800	
  9801				if (!(dynptr_arg_type & MEM_UNINIT)) {
  9802					int id = dynptr_id(env, reg);
  9803	
  9804					if (id < 0) {
  9805						verbose(env, "verifier internal error: failed to obtain dynptr id\n");
  9806						return id;
  9807					}
  9808					meta->initialized_dynptr.id = id;
  9809					meta->initialized_dynptr.type = dynptr_get_type(env, reg);
  9810				}
  9811	
  9812				break;
  9813			}
  9814			case KF_ARG_PTR_TO_LIST_HEAD:
  9815				if (reg->type != PTR_TO_MAP_VALUE &&
  9816				    reg->type != (PTR_TO_BTF_ID | MEM_ALLOC)) {
  9817					verbose(env, "arg#%d expected pointer to map value or allocated object\n", i);
  9818					return -EINVAL;
  9819				}
  9820				if (reg->type == (PTR_TO_BTF_ID | MEM_ALLOC) && !reg->ref_obj_id) {
  9821					verbose(env, "allocated object must be referenced\n");
  9822					return -EINVAL;
  9823				}
  9824				ret = process_kf_arg_ptr_to_list_head(env, reg, regno, meta);
  9825				if (ret < 0)
  9826					return ret;
  9827				break;
  9828			case KF_ARG_PTR_TO_RB_ROOT:
  9829				if (reg->type != PTR_TO_MAP_VALUE &&
  9830				    reg->type != (PTR_TO_BTF_ID | MEM_ALLOC)) {
  9831					verbose(env, "arg#%d expected pointer to map value or allocated object\n", i);
  9832					return -EINVAL;
  9833				}
  9834				if (reg->type == (PTR_TO_BTF_ID | MEM_ALLOC) && !reg->ref_obj_id) {
  9835					verbose(env, "allocated object must be referenced\n");
  9836					return -EINVAL;
  9837				}
  9838				ret = process_kf_arg_ptr_to_rbtree_root(env, reg, regno, meta);
  9839				if (ret < 0)
  9840					return ret;
  9841				break;
  9842			case KF_ARG_PTR_TO_LIST_NODE:
  9843				if (reg->type != (PTR_TO_BTF_ID | MEM_ALLOC)) {
  9844					verbose(env, "arg#%d expected pointer to allocated object\n", i);
  9845					return -EINVAL;
  9846				}
  9847				if (!reg->ref_obj_id) {
  9848					verbose(env, "allocated object must be referenced\n");
  9849					return -EINVAL;
  9850				}
  9851				ret = process_kf_arg_ptr_to_list_node(env, reg, regno, meta);
  9852				if (ret < 0)
  9853					return ret;
  9854				break;
  9855			case KF_ARG_PTR_TO_RB_NODE:
  9856				if (meta->func_id == special_kfunc_list[KF_bpf_rbtree_remove]) {
  9857					if (!type_is_non_owning_ref(reg->type) || reg->ref_obj_id) {
  9858						verbose(env, "rbtree_remove node input must be non-owning ref\n");
  9859						return -EINVAL;
  9860					}
  9861					if (in_rbtree_lock_required_cb(env)) {
  9862						verbose(env, "rbtree_remove not allowed in rbtree cb\n");
  9863						return -EINVAL;
  9864					}
  9865				} else {
  9866					if (reg->type != (PTR_TO_BTF_ID | MEM_ALLOC)) {
  9867						verbose(env, "arg#%d expected pointer to allocated object\n", i);
  9868						return -EINVAL;
  9869					}
  9870					if (!reg->ref_obj_id) {
  9871						verbose(env, "allocated object must be referenced\n");
  9872						return -EINVAL;
  9873					}
  9874				}
  9875	
  9876				ret = process_kf_arg_ptr_to_rbtree_node(env, reg, regno, meta);
  9877				if (ret < 0)
  9878					return ret;
  9879				break;
  9880			case KF_ARG_PTR_TO_BTF_ID:
  9881				/* Only base_type is checked, further checks are done here */
  9882				if ((base_type(reg->type) != PTR_TO_BTF_ID ||
  9883				     (bpf_type_has_unsafe_modifiers(reg->type) && !is_rcu_reg(reg))) &&
  9884				    !reg2btf_ids[base_type(reg->type)]) {
  9885					verbose(env, "arg#%d is %s ", i, reg_type_str(env, reg->type));
  9886					verbose(env, "expected %s or socket\n",
  9887						reg_type_str(env, base_type(reg->type) |
  9888								  (type_flag(reg->type) & BPF_REG_TRUSTED_MODIFIERS)));
  9889					return -EINVAL;
  9890				}
  9891				ret = process_kf_arg_ptr_to_btf_id(env, reg, ref_t, ref_tname, ref_id, meta, i);
  9892				if (ret < 0)
  9893					return ret;
  9894				break;
  9895			case KF_ARG_PTR_TO_MEM:
  9896				resolve_ret = btf_resolve_size(btf, ref_t, &type_size);
  9897				if (IS_ERR(resolve_ret)) {
  9898					verbose(env, "arg#%d reference type('%s %s') size cannot be determined: %ld\n",
  9899						i, btf_type_str(ref_t), ref_tname, PTR_ERR(resolve_ret));
  9900					return -EINVAL;
  9901				}
  9902				ret = check_mem_reg(env, reg, regno, type_size);
  9903				if (ret < 0)
  9904					return ret;
  9905				break;
  9906			case KF_ARG_PTR_TO_MEM_SIZE:
  9907				struct bpf_reg_state *size_reg = &regs[regno + 1];
> 9908				const struct btf_param *size_arg = &args[i + 1];
  9909	
  9910				ret = check_kfunc_mem_size_reg(env, size_reg, regno + 1);
  9911				if (ret < 0) {
  9912					verbose(env, "arg#%d arg#%d memory, len pair leads to invalid memory access\n", i, i + 1);
  9913					return ret;
  9914				}
  9915	
  9916				if (is_kfunc_arg_const_mem_size(meta->btf, size_arg, size_reg)) {
  9917					if (meta->arg_constant.found) {
  9918						verbose(env, "verifier internal error: only one constant argument permitted\n");
  9919						return -EFAULT;
  9920					}
  9921					if (!tnum_is_const(size_reg->var_off)) {
  9922						verbose(env, "R%d must be a known constant\n", regno + 1);
  9923						return -EINVAL;
  9924					}
  9925					meta->arg_constant.found = true;
  9926					meta->arg_constant.value = size_reg->var_off.value;
  9927				}
  9928	
  9929				/* Skip next '__sz' or '__szk' argument */
  9930				i++;
  9931				break;
  9932			case KF_ARG_PTR_TO_CALLBACK:
  9933				meta->subprogno = reg->subprogno;
  9934				break;
  9935			}
  9936		}
  9937	
  9938		if (is_kfunc_release(meta) && !meta->release_regno) {
  9939			verbose(env, "release kernel function %s expects refcounted PTR_TO_BTF_ID\n",
  9940				func_name);
  9941			return -EINVAL;
  9942		}
  9943	
  9944		return 0;
  9945	}
  9946	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ