lkml.org 
[lkml]   [2019]   [Dec]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 134/243] bpf: btf: check name validity for various types
    Date
    From: Yonghong Song <yhs@fb.com>

    [ Upstream commit eb04bbb608e683f8fd3ef7f716e2fa32dd90861f ]

    This patch added name checking for the following types:
    . BTF_KIND_PTR, BTF_KIND_ARRAY, BTF_KIND_VOLATILE,
    BTF_KIND_CONST, BTF_KIND_RESTRICT:
    the name must be null
    . BTF_KIND_STRUCT, BTF_KIND_UNION: the struct/member name
    is either null or a valid identifier
    . BTF_KIND_ENUM: the enum type name is either null or a valid
    identifier; the enumerator name must be a valid identifier.
    . BTF_KIND_FWD: the name must be a valid identifier
    . BTF_KIND_TYPEDEF: the name must be a valid identifier

    For those places a valid name is required, the name must be
    a valid C identifier. This can be relaxed later if we found
    use cases for a different (non-C) frontend.

    Fixes: 69b693f0aefa ("bpf: btf: Introduce BPF Type Format (BTF)")
    Acked-by: Martin KaFai Lau <kafai@fb.com>
    Signed-off-by: Yonghong Song <yhs@fb.com>
    Signed-off-by: Alexei Starovoitov <ast@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    kernel/bpf/btf.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++
    1 file changed, 57 insertions(+)

    diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
    index f0f9109f59bac..3e2413345e718 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);
    --
    2.20.1


    \
     
     \ /
      Last update: 2019-12-11 16:52    [W:5.146 / U:1.368 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site