Skip to content

Commit 93029d7

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next
Daniel Borkmann says: ==================== bpf-next 2018-11-30 The following pull-request contains BPF updates for your *net-next* tree. (Getting out bit earlier this time to pull in a dependency from bpf.) The main changes are: 1) Add libbpf ABI versioning and document API naming conventions as well as ABI versioning process, from Andrey. 2) Add a new sk_msg_pop_data() helper for sk_msg based BPF programs that is used in conjunction with sk_msg_push_data() for adding / removing meta data to the msg data, from John. 3) Optimize convert_bpf_ld_abs() for 0 offset and fix various lib and testsuite build failures on 32 bit, from David. 4) Make BPF prog dump for !JIT identical to how we dump subprogs when JIT is in use, from Yonghong. 5) Rename btf_get_from_id() to make it more conform with libbpf API naming conventions, from Martin. 6) Add a missing BPF kselftest config item, from Naresh. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 3d58c9c + b426995 commit 93029d7

File tree

25 files changed

+760
-115
lines changed

25 files changed

+760
-115
lines changed

include/linux/bpf.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,8 @@ struct bpf_prog_aux {
299299
u32 max_pkt_offset;
300300
u32 stack_depth;
301301
u32 id;
302-
u32 func_cnt;
302+
u32 func_cnt; /* used by non-func prog as the number of func progs */
303+
u32 func_idx; /* 0 for non-func prog, the index in func array for func prog */
303304
bool offload_requested;
304305
struct bpf_prog **func;
305306
void *jit_data; /* JIT specific data. arch dependent */
@@ -317,7 +318,8 @@ struct bpf_prog_aux {
317318
#endif
318319
struct bpf_prog_offload *offload;
319320
struct btf *btf;
320-
u32 type_id; /* type id for this prog/func */
321+
struct bpf_func_info *func_info;
322+
u32 func_info_cnt;
321323
union {
322324
struct work_struct work;
323325
struct rcu_head rcu;

include/linux/bpf_verifier.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,6 @@ static inline bool bpf_verifier_log_needed(const struct bpf_verifier_log *log)
204204
struct bpf_subprog_info {
205205
u32 start; /* insn idx of function entry point */
206206
u16 stack_depth; /* max. stack depth used by this function */
207-
u32 type_id; /* btf type_id for this subprog */
208207
};
209208

210209
/* single container for all structs

include/uapi/linux/bpf.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2268,6 +2268,19 @@ union bpf_attr {
22682268
*
22692269
* Return
22702270
* 0 on success, or a negative error in case of failure.
2271+
*
2272+
* int bpf_msg_pop_data(struct sk_msg_buff *msg, u32 start, u32 pop, u64 flags)
2273+
* Description
2274+
* Will remove *pop* bytes from a *msg* starting at byte *start*.
2275+
* This may result in **ENOMEM** errors under certain situations if
2276+
* an allocation and copy are required due to a full ring buffer.
2277+
* However, the helper will try to avoid doing the allocation
2278+
* if possible. Other errors can occur if input parameters are
2279+
* invalid either due to *start* byte not being valid part of msg
2280+
* payload and/or *pop* value being to large.
2281+
*
2282+
* Return
2283+
* 0 on success, or a negative erro in case of failure.
22712284
*/
22722285
#define __BPF_FUNC_MAPPER(FN) \
22732286
FN(unspec), \
@@ -2360,7 +2373,8 @@ union bpf_attr {
23602373
FN(map_push_elem), \
23612374
FN(map_pop_elem), \
23622375
FN(map_peek_elem), \
2363-
FN(msg_push_data),
2376+
FN(msg_push_data), \
2377+
FN(msg_pop_data),
23642378

23652379
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
23662380
* function eBPF program intends to call

kernel/bpf/core.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,8 @@ static void bpf_get_prog_name(const struct bpf_prog *prog, char *sym)
411411

412412
/* prog->aux->name will be ignored if full btf name is available */
413413
if (prog->aux->btf) {
414-
type = btf_type_by_id(prog->aux->btf, prog->aux->type_id);
414+
type = btf_type_by_id(prog->aux->btf,
415+
prog->aux->func_info[prog->aux->func_idx].type_id);
415416
func_name = btf_name_by_offset(prog->aux->btf, type->name_off);
416417
snprintf(sym, (size_t)(end - sym), "_%s", func_name);
417418
return;

kernel/bpf/syscall.c

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,6 +1214,7 @@ static void __bpf_prog_put(struct bpf_prog *prog, bool do_idr_lock)
12141214
bpf_prog_free_id(prog, do_idr_lock);
12151215
bpf_prog_kallsyms_del_all(prog);
12161216
btf_put(prog->aux->btf);
1217+
kvfree(prog->aux->func_info);
12171218

12181219
call_rcu(&prog->aux->rcu, __bpf_prog_put_rcu);
12191220
}
@@ -2219,46 +2220,28 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
22192220
}
22202221

22212222
if (prog->aux->btf) {
2223+
u32 krec_size = sizeof(struct bpf_func_info);
22222224
u32 ucnt, urec_size;
22232225

22242226
info.btf_id = btf_id(prog->aux->btf);
22252227

22262228
ucnt = info.func_info_cnt;
2227-
info.func_info_cnt = prog->aux->func_cnt ? : 1;
2229+
info.func_info_cnt = prog->aux->func_info_cnt;
22282230
urec_size = info.func_info_rec_size;
2229-
info.func_info_rec_size = sizeof(struct bpf_func_info);
2231+
info.func_info_rec_size = krec_size;
22302232
if (ucnt) {
22312233
/* expect passed-in urec_size is what the kernel expects */
22322234
if (urec_size != info.func_info_rec_size)
22332235
return -EINVAL;
22342236

22352237
if (bpf_dump_raw_ok()) {
2236-
struct bpf_func_info kern_finfo;
22372238
char __user *user_finfo;
2238-
u32 i, insn_offset;
22392239

22402240
user_finfo = u64_to_user_ptr(info.func_info);
2241-
if (prog->aux->func_cnt) {
2242-
ucnt = min_t(u32, info.func_info_cnt, ucnt);
2243-
insn_offset = 0;
2244-
for (i = 0; i < ucnt; i++) {
2245-
kern_finfo.insn_offset = insn_offset;
2246-
kern_finfo.type_id = prog->aux->func[i]->aux->type_id;
2247-
if (copy_to_user(user_finfo, &kern_finfo,
2248-
sizeof(kern_finfo)))
2249-
return -EFAULT;
2250-
2251-
/* func[i]->len holds the prog len */
2252-
insn_offset += prog->aux->func[i]->len;
2253-
user_finfo += urec_size;
2254-
}
2255-
} else {
2256-
kern_finfo.insn_offset = 0;
2257-
kern_finfo.type_id = prog->aux->type_id;
2258-
if (copy_to_user(user_finfo, &kern_finfo,
2259-
sizeof(kern_finfo)))
2260-
return -EFAULT;
2261-
}
2241+
ucnt = min_t(u32, info.func_info_cnt, ucnt);
2242+
if (copy_to_user(user_finfo, prog->aux->func_info,
2243+
krec_size * ucnt))
2244+
return -EFAULT;
22622245
} else {
22632246
info.func_info_cnt = 0;
22642247
}

kernel/bpf/verifier.c

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4650,7 +4650,7 @@ static int check_btf_func(struct bpf_prog *prog, struct bpf_verifier_env *env,
46504650
{
46514651
u32 i, nfuncs, urec_size, min_size, prev_offset;
46524652
u32 krec_size = sizeof(struct bpf_func_info);
4653-
struct bpf_func_info krecord = {};
4653+
struct bpf_func_info *krecord = NULL;
46544654
const struct btf_type *type;
46554655
void __user *urecord;
46564656
struct btf *btf;
@@ -4682,6 +4682,12 @@ static int check_btf_func(struct bpf_prog *prog, struct bpf_verifier_env *env,
46824682
urecord = u64_to_user_ptr(attr->func_info);
46834683
min_size = min_t(u32, krec_size, urec_size);
46844684

4685+
krecord = kvcalloc(nfuncs, krec_size, GFP_KERNEL | __GFP_NOWARN);
4686+
if (!krecord) {
4687+
ret = -ENOMEM;
4688+
goto free_btf;
4689+
}
4690+
46854691
for (i = 0; i < nfuncs; i++) {
46864692
ret = bpf_check_uarg_tail_zero(urecord, krec_size, urec_size);
46874693
if (ret) {
@@ -4696,59 +4702,69 @@ static int check_btf_func(struct bpf_prog *prog, struct bpf_verifier_env *env,
46964702
goto free_btf;
46974703
}
46984704

4699-
if (copy_from_user(&krecord, urecord, min_size)) {
4705+
if (copy_from_user(&krecord[i], urecord, min_size)) {
47004706
ret = -EFAULT;
47014707
goto free_btf;
47024708
}
47034709

47044710
/* check insn_offset */
47054711
if (i == 0) {
4706-
if (krecord.insn_offset) {
4712+
if (krecord[i].insn_offset) {
47074713
verbose(env,
47084714
"nonzero insn_offset %u for the first func info record",
4709-
krecord.insn_offset);
4715+
krecord[i].insn_offset);
47104716
ret = -EINVAL;
47114717
goto free_btf;
47124718
}
4713-
} else if (krecord.insn_offset <= prev_offset) {
4719+
} else if (krecord[i].insn_offset <= prev_offset) {
47144720
verbose(env,
47154721
"same or smaller insn offset (%u) than previous func info record (%u)",
4716-
krecord.insn_offset, prev_offset);
4722+
krecord[i].insn_offset, prev_offset);
47174723
ret = -EINVAL;
47184724
goto free_btf;
47194725
}
47204726

4721-
if (env->subprog_info[i].start != krecord.insn_offset) {
4727+
if (env->subprog_info[i].start != krecord[i].insn_offset) {
47224728
verbose(env, "func_info BTF section doesn't match subprog layout in BPF program\n");
47234729
ret = -EINVAL;
47244730
goto free_btf;
47254731
}
47264732

47274733
/* check type_id */
4728-
type = btf_type_by_id(btf, krecord.type_id);
4734+
type = btf_type_by_id(btf, krecord[i].type_id);
47294735
if (!type || BTF_INFO_KIND(type->info) != BTF_KIND_FUNC) {
47304736
verbose(env, "invalid type id %d in func info",
4731-
krecord.type_id);
4737+
krecord[i].type_id);
47324738
ret = -EINVAL;
47334739
goto free_btf;
47344740
}
47354741

4736-
if (i == 0)
4737-
prog->aux->type_id = krecord.type_id;
4738-
env->subprog_info[i].type_id = krecord.type_id;
4739-
4740-
prev_offset = krecord.insn_offset;
4742+
prev_offset = krecord[i].insn_offset;
47414743
urecord += urec_size;
47424744
}
47434745

47444746
prog->aux->btf = btf;
4747+
prog->aux->func_info = krecord;
4748+
prog->aux->func_info_cnt = nfuncs;
47454749
return 0;
47464750

47474751
free_btf:
47484752
btf_put(btf);
4753+
kvfree(krecord);
47494754
return ret;
47504755
}
47514756

4757+
static void adjust_btf_func(struct bpf_verifier_env *env)
4758+
{
4759+
int i;
4760+
4761+
if (!env->prog->aux->func_info)
4762+
return;
4763+
4764+
for (i = 0; i < env->subprog_cnt; i++)
4765+
env->prog->aux->func_info[i].insn_offset = env->subprog_info[i].start;
4766+
}
4767+
47524768
/* check %cur's range satisfies %old's */
47534769
static bool range_within(struct bpf_reg_state *old,
47544770
struct bpf_reg_state *cur)
@@ -6043,15 +6059,17 @@ static int jit_subprogs(struct bpf_verifier_env *env)
60436059
if (bpf_prog_calc_tag(func[i]))
60446060
goto out_free;
60456061
func[i]->is_func = 1;
6062+
func[i]->aux->func_idx = i;
6063+
/* the btf and func_info will be freed only at prog->aux */
6064+
func[i]->aux->btf = prog->aux->btf;
6065+
func[i]->aux->func_info = prog->aux->func_info;
6066+
60466067
/* Use bpf_prog_F_tag to indicate functions in stack traces.
60476068
* Long term would need debug info to populate names
60486069
*/
60496070
func[i]->aux->name[0] = 'F';
60506071
func[i]->aux->stack_depth = env->subprog_info[i].stack_depth;
60516072
func[i]->jit_requested = 1;
6052-
/* the btf will be freed only at prog->aux */
6053-
func[i]->aux->btf = prog->aux->btf;
6054-
func[i]->aux->type_id = env->subprog_info[i].type_id;
60556073
func[i] = bpf_int_jit_compile(func[i]);
60566074
if (!func[i]->jited) {
60576075
err = -ENOTSUPP;
@@ -6572,6 +6590,9 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr,
65726590
convert_pseudo_ld_imm64(env);
65736591
}
65746592

6593+
if (ret == 0)
6594+
adjust_btf_func(env);
6595+
65756596
err_release_maps:
65766597
if (!env->prog->aux->used_maps)
65776598
/* if we didn't copy map pointers into bpf_prog_info, release

0 commit comments

Comments
 (0)