aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/btf.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/bpf/btf.c')
-rw-r--r--kernel/bpf/btf.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index ee4c82667d65..4da543d6bea2 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -5,6 +5,7 @@
5#include <uapi/linux/types.h> 5#include <uapi/linux/types.h>
6#include <linux/seq_file.h> 6#include <linux/seq_file.h>
7#include <linux/compiler.h> 7#include <linux/compiler.h>
8#include <linux/ctype.h>
8#include <linux/errno.h> 9#include <linux/errno.h>
9#include <linux/slab.h> 10#include <linux/slab.h>
10#include <linux/anon_inodes.h> 11#include <linux/anon_inodes.h>
@@ -426,6 +427,30 @@ static bool btf_name_offset_valid(const struct btf *btf, u32 offset)
426 offset < btf->hdr.str_len; 427 offset < btf->hdr.str_len;
427} 428}
428 429
430/* Only C-style identifier is permitted. This can be relaxed if
431 * necessary.
432 */
433static bool btf_name_valid_identifier(const struct btf *btf, u32 offset)
434{
435 /* offset must be valid */
436 const char *src = &btf->strings[offset];
437 const char *src_limit;
438
439 if (!isalpha(*src) && *src != '_')
440 return false;
441
442 /* set a limit on identifier length */
443 src_limit = src + KSYM_NAME_LEN;
444 src++;
445 while (*src && src < src_limit) {
446 if (!isalnum(*src) && *src != '_')
447 return false;
448 src++;
449 }
450
451 return !*src;
452}
453
429static const char *btf_name_by_offset(const struct btf *btf, u32 offset) 454static const char *btf_name_by_offset(const struct btf *btf, u32 offset)
430{ 455{
431 if (!offset) 456 if (!offset)
@@ -1143,6 +1168,22 @@ static int btf_ref_type_check_meta(struct btf_verifier_env *env,
1143 return -EINVAL; 1168 return -EINVAL;
1144 } 1169 }
1145 1170
1171 /* typedef type must have a valid name, and other ref types,
1172 * volatile, const, restrict, should have a null name.
1173 */
1174 if (BTF_INFO_KIND(t->info) == BTF_KIND_TYPEDEF) {
1175 if (!t->name_off ||
1176 !btf_name_valid_identifier(env->btf, t->name_off)) {
1177 btf_verifier_log_type(env, t, "Invalid name");
1178 return -EINVAL;
1179 }
1180 } else {
1181 if (t->name_off) {
1182 btf_verifier_log_type(env, t, "Invalid name");
1183 return -EINVAL;
1184 }
1185 }
1186
1146 btf_verifier_log_type(env, t, NULL); 1187 btf_verifier_log_type(env, t, NULL);
1147 1188
1148 return 0; 1189 return 0;
@@ -1300,6 +1341,13 @@ static s32 btf_fwd_check_meta(struct btf_verifier_env *env,
1300 return -EINVAL; 1341 return -EINVAL;
1301 } 1342 }
1302 1343
1344 /* fwd type must have a valid name */
1345 if (!t->name_off ||
1346 !btf_name_valid_identifier(env->btf, t->name_off)) {
1347 btf_verifier_log_type(env, t, "Invalid name");
1348 return -EINVAL;
1349 }
1350
1303 btf_verifier_log_type(env, t, NULL); 1351 btf_verifier_log_type(env, t, NULL);
1304 1352
1305 return 0; 1353 return 0;
@@ -1356,6 +1404,12 @@ static s32 btf_array_check_meta(struct btf_verifier_env *env,
1356 return -EINVAL; 1404 return -EINVAL;
1357 } 1405 }
1358 1406
1407 /* array type should not have a name */
1408 if (t->name_off) {
1409 btf_verifier_log_type(env, t, "Invalid name");
1410 return -EINVAL;
1411 }
1412
1359 if (btf_type_vlen(t)) { 1413 if (btf_type_vlen(t)) {
1360 btf_verifier_log_type(env, t, "vlen != 0"); 1414 btf_verifier_log_type(env, t, "vlen != 0");
1361 return -EINVAL; 1415 return -EINVAL;
@@ -1532,6 +1586,13 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env,
1532 return -EINVAL; 1586 return -EINVAL;
1533 } 1587 }
1534 1588
1589 /* struct type either no name or a valid one */
1590 if (t->name_off &&
1591 !btf_name_valid_identifier(env->btf, t->name_off)) {
1592 btf_verifier_log_type(env, t, "Invalid name");
1593 return -EINVAL;
1594 }
1595
1535 btf_verifier_log_type(env, t, NULL); 1596 btf_verifier_log_type(env, t, NULL);
1536 1597
1537 last_offset = 0; 1598 last_offset = 0;
@@ -1543,6 +1604,12 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env,
1543 return -EINVAL; 1604 return -EINVAL;
1544 } 1605 }
1545 1606
1607 /* struct member either no name or a valid one */
1608 if (member->name_off &&
1609 !btf_name_valid_identifier(btf, member->name_off)) {
1610 btf_verifier_log_member(env, t, member, "Invalid name");
1611 return -EINVAL;
1612 }
1546 /* A member cannot be in type void */ 1613 /* A member cannot be in type void */
1547 if (!member->type || !BTF_TYPE_ID_VALID(member->type)) { 1614 if (!member->type || !BTF_TYPE_ID_VALID(member->type)) {
1548 btf_verifier_log_member(env, t, member, 1615 btf_verifier_log_member(env, t, member,
@@ -1730,6 +1797,13 @@ static s32 btf_enum_check_meta(struct btf_verifier_env *env,
1730 return -EINVAL; 1797 return -EINVAL;
1731 } 1798 }
1732 1799
1800 /* enum type either no name or a valid one */
1801 if (t->name_off &&
1802 !btf_name_valid_identifier(env->btf, t->name_off)) {
1803 btf_verifier_log_type(env, t, "Invalid name");
1804 return -EINVAL;
1805 }
1806
1733 btf_verifier_log_type(env, t, NULL); 1807 btf_verifier_log_type(env, t, NULL);
1734 1808
1735 for (i = 0; i < nr_enums; i++) { 1809 for (i = 0; i < nr_enums; i++) {
@@ -1739,6 +1813,14 @@ static s32 btf_enum_check_meta(struct btf_verifier_env *env,
1739 return -EINVAL; 1813 return -EINVAL;
1740 } 1814 }
1741 1815
1816 /* enum member must have a valid name */
1817 if (!enums[i].name_off ||
1818 !btf_name_valid_identifier(btf, enums[i].name_off)) {
1819 btf_verifier_log_type(env, t, "Invalid name");
1820 return -EINVAL;
1821 }
1822
1823
1742 btf_verifier_log(env, "\t%s val=%d\n", 1824 btf_verifier_log(env, "\t%s val=%d\n",
1743 btf_name_by_offset(btf, enums[i].name_off), 1825 btf_name_by_offset(btf, enums[i].name_off),
1744 enums[i].val); 1826 enums[i].val);