diff options
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r-- | kernel/bpf/syscall.c | 33 |
1 files changed, 8 insertions, 25 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 998377808102..85cbeec06e50 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c | |||
@@ -1214,6 +1214,7 @@ static void __bpf_prog_put(struct bpf_prog *prog, bool do_idr_lock) | |||
1214 | bpf_prog_free_id(prog, do_idr_lock); | 1214 | bpf_prog_free_id(prog, do_idr_lock); |
1215 | bpf_prog_kallsyms_del_all(prog); | 1215 | bpf_prog_kallsyms_del_all(prog); |
1216 | btf_put(prog->aux->btf); | 1216 | btf_put(prog->aux->btf); |
1217 | kvfree(prog->aux->func_info); | ||
1217 | 1218 | ||
1218 | call_rcu(&prog->aux->rcu, __bpf_prog_put_rcu); | 1219 | call_rcu(&prog->aux->rcu, __bpf_prog_put_rcu); |
1219 | } | 1220 | } |
@@ -2219,46 +2220,28 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog, | |||
2219 | } | 2220 | } |
2220 | 2221 | ||
2221 | if (prog->aux->btf) { | 2222 | if (prog->aux->btf) { |
2223 | u32 krec_size = sizeof(struct bpf_func_info); | ||
2222 | u32 ucnt, urec_size; | 2224 | u32 ucnt, urec_size; |
2223 | 2225 | ||
2224 | info.btf_id = btf_id(prog->aux->btf); | 2226 | info.btf_id = btf_id(prog->aux->btf); |
2225 | 2227 | ||
2226 | ucnt = info.func_info_cnt; | 2228 | 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; |
2228 | urec_size = info.func_info_rec_size; | 2230 | 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; |
2230 | if (ucnt) { | 2232 | if (ucnt) { |
2231 | /* expect passed-in urec_size is what the kernel expects */ | 2233 | /* expect passed-in urec_size is what the kernel expects */ |
2232 | if (urec_size != info.func_info_rec_size) | 2234 | if (urec_size != info.func_info_rec_size) |
2233 | return -EINVAL; | 2235 | return -EINVAL; |
2234 | 2236 | ||
2235 | if (bpf_dump_raw_ok()) { | 2237 | if (bpf_dump_raw_ok()) { |
2236 | struct bpf_func_info kern_finfo; | ||
2237 | char __user *user_finfo; | 2238 | char __user *user_finfo; |
2238 | u32 i, insn_offset; | ||
2239 | 2239 | ||
2240 | user_finfo = u64_to_user_ptr(info.func_info); | 2240 | user_finfo = u64_to_user_ptr(info.func_info); |
2241 | if (prog->aux->func_cnt) { | 2241 | ucnt = min_t(u32, info.func_info_cnt, ucnt); |
2242 | ucnt = min_t(u32, info.func_info_cnt, ucnt); | 2242 | if (copy_to_user(user_finfo, prog->aux->func_info, |
2243 | insn_offset = 0; | 2243 | krec_size * ucnt)) |
2244 | for (i = 0; i < ucnt; i++) { | 2244 | return -EFAULT; |
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 | } | ||
2262 | } else { | 2245 | } else { |
2263 | info.func_info_cnt = 0; | 2246 | info.func_info_cnt = 0; |
2264 | } | 2247 | } |