@@ -2584,24 +2584,25 @@ static struct btf *find_kfunc_desc_btf(struct bpf_verifier_env *env, s16 offset)
25842584
25852585#define KF_IMPL_SUFFIX "_impl"
25862586
2587- static const struct btf_type *find_kfunc_impl_proto(struct bpf_verifier_env *env ,
2587+ static const struct btf_type *find_kfunc_impl_proto(struct bpf_verifier_log *log ,
25882588 struct btf *btf,
25892589 const char *func_name)
25902590{
2591- char *buf = env->tmp_str_buf;
25922591 const struct btf_type *func;
2592+ char buf[KSYM_NAME_LEN];
25932593 s32 impl_id;
25942594 int len;
25952595
2596- len = snprintf(buf, TMP_STR_BUF_LEN, "%s%s", func_name, KF_IMPL_SUFFIX);
2597- if (len < 0 || len >= TMP_STR_BUF_LEN) {
2598- verbose(env, "function name %s%s is too long\n", func_name, KF_IMPL_SUFFIX);
2596+ len = snprintf(buf, sizeof(buf), "%s%s", func_name, KF_IMPL_SUFFIX);
2597+ if (len < 0 || len >= sizeof(buf)) {
2598+ bpf_log(log, "function name %s%s is too long\n",
2599+ func_name, KF_IMPL_SUFFIX);
25992600 return NULL;
26002601 }
26012602
26022603 impl_id = btf_find_by_name_kind(btf, buf, BTF_KIND_FUNC);
26032604 if (impl_id <= 0) {
2604- verbose(env , "cannot find function %s in BTF\n", buf);
2605+ bpf_log(log , "cannot find function %s in BTF\n", buf);
26052606 return NULL;
26062607 }
26072608
@@ -2653,7 +2654,7 @@ static int fetch_kfunc_meta(struct bpf_verifier_env *env,
26532654 * can be found through the counterpart _impl kfunc.
26542655 */
26552656 if (kfunc_flags && (*kfunc_flags & KF_IMPLICIT_ARGS))
2656- func_proto = find_kfunc_impl_proto(env, btf, func_name);
2657+ func_proto = find_kfunc_impl_proto(& env->log , btf, func_name);
26572658 else
26582659 func_proto = btf_type_by_id(btf, func->type);
26592660
@@ -5326,14 +5327,11 @@ static int check_max_stack_depth(struct bpf_verifier_env *env)
53265327static int __check_buffer_access(struct bpf_verifier_env *env,
53275328 const char *buf_info,
53285329 const struct bpf_reg_state *reg,
5329- argno_t argno, int off, int size)
5330+ argno_t argno, int off, int size,
5331+ u32 *access_end)
53305332{
5331- if (off < 0) {
5332- verbose(env,
5333- "%s invalid %s buffer access: off=%d, size=%d\n",
5334- reg_arg_name(env, argno), buf_info, off, size);
5335- return -EACCES;
5336- }
5333+ s64 start;
5334+
53375335 if (!tnum_is_const(reg->var_off)) {
53385336 char tn_buf[48];
53395337
@@ -5344,21 +5342,30 @@ static int __check_buffer_access(struct bpf_verifier_env *env,
53445342 return -EACCES;
53455343 }
53465344
5345+ start = (s64)reg->var_off.value + off;
5346+ if (start < 0) {
5347+ verbose(env,
5348+ "%s invalid negative %s buffer offset: off=%d, var_off=%lld\n",
5349+ reg_arg_name(env, argno), buf_info, off, (s64)reg->var_off.value);
5350+ return -EACCES;
5351+ }
5352+
5353+ *access_end = start + size;
53475354 return 0;
53485355}
53495356
53505357static int check_tp_buffer_access(struct bpf_verifier_env *env,
53515358 const struct bpf_reg_state *reg,
53525359 argno_t argno, int off, int size)
53535360{
5361+ u32 access_end;
53545362 int err;
53555363
5356- err = __check_buffer_access(env, "tracepoint", reg, argno, off, size);
5364+ err = __check_buffer_access(env, "tracepoint", reg, argno, off, size, &access_end );
53575365 if (err)
53585366 return err;
53595367
5360- env->prog->aux->max_tp_access = max(reg->var_off.value + off + size,
5361- env->prog->aux->max_tp_access);
5368+ env->prog->aux->max_tp_access = max(access_end, env->prog->aux->max_tp_access);
53625369
53635370 return 0;
53645371}
@@ -5370,13 +5377,14 @@ static int check_buffer_access(struct bpf_verifier_env *env,
53705377 u32 *max_access)
53715378{
53725379 const char *buf_info = type_is_rdonly_mem(reg->type) ? "rdonly" : "rdwr";
5380+ u32 access_end;
53735381 int err;
53745382
5375- err = __check_buffer_access(env, buf_info, reg, argno, off, size);
5383+ err = __check_buffer_access(env, buf_info, reg, argno, off, size, &access_end );
53765384 if (err)
53775385 return err;
53785386
5379- *max_access = max(reg->var_off.value + off + size , *max_access);
5387+ *max_access = max(access_end , *max_access);
53805388
53815389 return 0;
53825390}
@@ -18873,6 +18881,47 @@ static int btf_id_allow_sleepable(u32 btf_id, unsigned long addr, const struct b
1887318881 return -EINVAL;
1887418882}
1887518883
18884+ /*
18885+ * Resolve the prototype describing a trace target's real ABI. A
18886+ * KF_IMPLICIT_ARGS kfunc has its injected args stripped from the public
18887+ * prototype, so use the _impl prototype; other targets use their own.
18888+ */
18889+ static const struct btf_type *
18890+ btf_attach_func_proto(struct bpf_verifier_log *log, struct btf *btf, u32 func_id)
18891+ {
18892+ const struct btf_type *func;
18893+ struct module *mod = NULL;
18894+ const char *name;
18895+ int implicit;
18896+
18897+ func = btf_type_by_id(btf, func_id);
18898+ if (!func || !btf_type_is_func(func))
18899+ return NULL;
18900+ name = btf_name_by_offset(btf, func->name_off);
18901+
18902+ /*
18903+ * btf_kfunc_check_flag() reads kfunc_set_tab, which for a module is
18904+ * stable only once it is live; hold a module ref across the read to
18905+ * exclude a concurrent module load.
18906+ */
18907+ if (btf_is_module(btf)) {
18908+ mod = btf_try_get_module(btf);
18909+ if (!mod)
18910+ return NULL;
18911+ }
18912+ implicit = btf_kfunc_check_flag(btf, func_id, KF_IMPLICIT_ARGS);
18913+ module_put(mod);
18914+
18915+ if (implicit == -EINVAL) {
18916+ bpf_log(log, "kfunc %s has inconsistent KF_IMPLICIT_ARGS\n", name);
18917+ return NULL;
18918+ }
18919+ if (implicit > 0)
18920+ return find_kfunc_impl_proto(log, btf, name);
18921+
18922+ return btf_type_by_id(btf, func->type);
18923+ }
18924+
1887618925int bpf_check_attach_target(struct bpf_verifier_log *log,
1887718926 const struct bpf_prog *prog,
1887818927 const struct bpf_prog *tgt_prog,
@@ -19121,8 +19170,8 @@ int bpf_check_attach_target(struct bpf_verifier_log *log,
1912119170 if (prog_extension &&
1912219171 btf_check_type_match(log, prog, btf, t))
1912319172 return -EINVAL;
19124- t = btf_type_by_id( btf, t->type );
19125- if (!btf_type_is_func_proto(t))
19173+ t = btf_attach_func_proto(log, btf, btf_id );
19174+ if (!t || ! btf_type_is_func_proto(t))
1912619175 return -EINVAL;
1912719176
1912819177 if ((prog->aux->saved_dst_prog_type || prog->aux->saved_dst_attach_type) &&
@@ -19405,10 +19454,8 @@ int bpf_check_attach_btf_id_multi(struct btf *btf, struct bpf_prog *prog, u32 bt
1940519454 tname = btf_name_by_offset(btf, t->name_off);
1940619455 if (!tname)
1940719456 return -EINVAL;
19408- if (!btf_type_is_func(t))
19409- return -EINVAL;
19410- t = btf_type_by_id(btf, t->type);
19411- if (!btf_type_is_func_proto(t))
19457+ t = btf_attach_func_proto(NULL, btf, btf_id);
19458+ if (!t || !btf_type_is_func_proto(t))
1941219459 return -EINVAL;
1941319460 err = btf_distill_func_proto(NULL, btf, t, tname, &tgt_info->fmodel);
1941419461 if (err < 0)
0 commit comments