]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bpf: btf: check name validity for various types
authorYonghong Song <yhs@fb.com>
Tue, 27 Nov 2018 21:23:28 +0000 (13:23 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 29 Nov 2018 00:03:04 +0000 (16:03 -0800)
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>
kernel/bpf/btf.c

index 93c233ab2db66c402464e266308d976fc50ab00d..4da543d6bea29c315b896848269e873f78ac09dd 100644 (file)
@@ -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);