diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/bpf/btf.c | 57 | 
1 files changed, 57 insertions, 0 deletions
| diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 93c233ab2db6..4da543d6bea2 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -1168,6 +1168,22 @@ static int btf_ref_type_check_meta(struct btf_verifier_env *env,  		return -EINVAL;  	} +	/* typedef type must have a valid name, and other ref types, +	 * volatile, const, restrict, should have a null name. +	 */ +	if (BTF_INFO_KIND(t->info) == BTF_KIND_TYPEDEF) { +		if (!t->name_off || +		    !btf_name_valid_identifier(env->btf, t->name_off)) { +			btf_verifier_log_type(env, t, "Invalid name"); +			return -EINVAL; +		} +	} else { +		if (t->name_off) { +			btf_verifier_log_type(env, t, "Invalid name"); +			return -EINVAL; +		} +	} +  	btf_verifier_log_type(env, t, NULL);  	return 0; @@ -1325,6 +1341,13 @@ static s32 btf_fwd_check_meta(struct btf_verifier_env *env,  		return -EINVAL;  	} +	/* fwd type must have a valid name */ +	if (!t->name_off || +	    !btf_name_valid_identifier(env->btf, t->name_off)) { +		btf_verifier_log_type(env, t, "Invalid name"); +		return -EINVAL; +	} +  	btf_verifier_log_type(env, t, NULL);  	return 0; @@ -1381,6 +1404,12 @@ static s32 btf_array_check_meta(struct btf_verifier_env *env,  		return -EINVAL;  	} +	/* array type should not have a name */ +	if (t->name_off) { +		btf_verifier_log_type(env, t, "Invalid name"); +		return -EINVAL; +	} +  	if (btf_type_vlen(t)) {  		btf_verifier_log_type(env, t, "vlen != 0");  		return -EINVAL; @@ -1557,6 +1586,13 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env,  		return -EINVAL;  	} +	/* struct type either no name or a valid one */ +	if (t->name_off && +	    !btf_name_valid_identifier(env->btf, t->name_off)) { +		btf_verifier_log_type(env, t, "Invalid name"); +		return -EINVAL; +	} +  	btf_verifier_log_type(env, t, NULL);  	last_offset = 0; @@ -1568,6 +1604,12 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env,  			return -EINVAL;  		} +		/* struct member either no name or a valid one */ +		if (member->name_off && +		    !btf_name_valid_identifier(btf, member->name_off)) { +			btf_verifier_log_member(env, t, member, "Invalid name"); +			return -EINVAL; +		}  		/* A member cannot be in type void */  		if (!member->type || !BTF_TYPE_ID_VALID(member->type)) {  			btf_verifier_log_member(env, t, member, @@ -1755,6 +1797,13 @@ static s32 btf_enum_check_meta(struct btf_verifier_env *env,  		return -EINVAL;  	} +	/* enum type either no name or a valid one */ +	if (t->name_off && +	    !btf_name_valid_identifier(env->btf, t->name_off)) { +		btf_verifier_log_type(env, t, "Invalid name"); +		return -EINVAL; +	} +  	btf_verifier_log_type(env, t, NULL);  	for (i = 0; i < nr_enums; i++) { @@ -1764,6 +1813,14 @@ static s32 btf_enum_check_meta(struct btf_verifier_env *env,  			return -EINVAL;  		} +		/* enum member must have a valid name */ +		if (!enums[i].name_off || +		    !btf_name_valid_identifier(btf, enums[i].name_off)) { +			btf_verifier_log_type(env, t, "Invalid name"); +			return -EINVAL; +		} + +  		btf_verifier_log(env, "\t%s val=%d\n",  				 btf_name_by_offset(btf, enums[i].name_off),  				 enums[i].val); | 
