aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/syscall.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r--kernel/bpf/syscall.c83
1 files changed, 77 insertions, 6 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index aa05aa38f4a8..19c88cff7880 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -1215,6 +1215,7 @@ static void __bpf_prog_put(struct bpf_prog *prog, bool 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 kvfree(prog->aux->func_info);
1218 bpf_prog_free_linfo(prog);
1218 1219
1219 call_rcu(&prog->aux->rcu, __bpf_prog_put_rcu); 1220 call_rcu(&prog->aux->rcu, __bpf_prog_put_rcu);
1220 } 1221 }
@@ -1439,7 +1440,7 @@ bpf_prog_load_check_attach_type(enum bpf_prog_type prog_type,
1439} 1440}
1440 1441
1441/* last field in 'union bpf_attr' used by this command */ 1442/* last field in 'union bpf_attr' used by this command */
1442#define BPF_PROG_LOAD_LAST_FIELD func_info_cnt 1443#define BPF_PROG_LOAD_LAST_FIELD line_info_cnt
1443 1444
1444static int bpf_prog_load(union bpf_attr *attr, union bpf_attr __user *uattr) 1445static int bpf_prog_load(union bpf_attr *attr, union bpf_attr __user *uattr)
1445{ 1446{
@@ -1560,6 +1561,7 @@ static int bpf_prog_load(union bpf_attr *attr, union bpf_attr __user *uattr)
1560 return err; 1561 return err;
1561 1562
1562free_used_maps: 1563free_used_maps:
1564 bpf_prog_free_linfo(prog);
1563 kvfree(prog->aux->func_info); 1565 kvfree(prog->aux->func_info);
1564 btf_put(prog->aux->btf); 1566 btf_put(prog->aux->btf);
1565 bpf_prog_kallsyms_del_subprogs(prog); 1567 bpf_prog_kallsyms_del_subprogs(prog);
@@ -2041,6 +2043,37 @@ static struct bpf_insn *bpf_insn_prepare_dump(const struct bpf_prog *prog)
2041 return insns; 2043 return insns;
2042} 2044}
2043 2045
2046static int set_info_rec_size(struct bpf_prog_info *info)
2047{
2048 /*
2049 * Ensure info.*_rec_size is the same as kernel expected size
2050 *
2051 * or
2052 *
2053 * Only allow zero *_rec_size if both _rec_size and _cnt are
2054 * zero. In this case, the kernel will set the expected
2055 * _rec_size back to the info.
2056 */
2057
2058 if ((info->func_info_cnt || info->func_info_rec_size) &&
2059 info->func_info_rec_size != sizeof(struct bpf_func_info))
2060 return -EINVAL;
2061
2062 if ((info->line_info_cnt || info->line_info_rec_size) &&
2063 info->line_info_rec_size != sizeof(struct bpf_line_info))
2064 return -EINVAL;
2065
2066 if ((info->jited_line_info_cnt || info->jited_line_info_rec_size) &&
2067 info->jited_line_info_rec_size != sizeof(__u64))
2068 return -EINVAL;
2069
2070 info->func_info_rec_size = sizeof(struct bpf_func_info);
2071 info->line_info_rec_size = sizeof(struct bpf_line_info);
2072 info->jited_line_info_rec_size = sizeof(__u64);
2073
2074 return 0;
2075}
2076
2044static int bpf_prog_get_info_by_fd(struct bpf_prog *prog, 2077static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
2045 const union bpf_attr *attr, 2078 const union bpf_attr *attr,
2046 union bpf_attr __user *uattr) 2079 union bpf_attr __user *uattr)
@@ -2083,11 +2116,9 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
2083 return -EFAULT; 2116 return -EFAULT;
2084 } 2117 }
2085 2118
2086 if ((info.func_info_cnt || info.func_info_rec_size) && 2119 err = set_info_rec_size(&info);
2087 info.func_info_rec_size != sizeof(struct bpf_func_info)) 2120 if (err)
2088 return -EINVAL; 2121 return err;
2089
2090 info.func_info_rec_size = sizeof(struct bpf_func_info);
2091 2122
2092 if (!capable(CAP_SYS_ADMIN)) { 2123 if (!capable(CAP_SYS_ADMIN)) {
2093 info.jited_prog_len = 0; 2124 info.jited_prog_len = 0;
@@ -2095,6 +2126,8 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
2095 info.nr_jited_ksyms = 0; 2126 info.nr_jited_ksyms = 0;
2096 info.nr_jited_func_lens = 0; 2127 info.nr_jited_func_lens = 0;
2097 info.func_info_cnt = 0; 2128 info.func_info_cnt = 0;
2129 info.line_info_cnt = 0;
2130 info.jited_line_info_cnt = 0;
2098 goto done; 2131 goto done;
2099 } 2132 }
2100 2133
@@ -2251,6 +2284,44 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
2251 } 2284 }
2252 } 2285 }
2253 2286
2287 ulen = info.line_info_cnt;
2288 info.line_info_cnt = prog->aux->nr_linfo;
2289 if (info.line_info_cnt && ulen) {
2290 if (bpf_dump_raw_ok()) {
2291 __u8 __user *user_linfo;
2292
2293 user_linfo = u64_to_user_ptr(info.line_info);
2294 ulen = min_t(u32, info.line_info_cnt, ulen);
2295 if (copy_to_user(user_linfo, prog->aux->linfo,
2296 info.line_info_rec_size * ulen))
2297 return -EFAULT;
2298 } else {
2299 info.line_info = 0;
2300 }
2301 }
2302
2303 ulen = info.jited_line_info_cnt;
2304 if (prog->aux->jited_linfo)
2305 info.jited_line_info_cnt = prog->aux->nr_linfo;
2306 else
2307 info.jited_line_info_cnt = 0;
2308 if (info.jited_line_info_cnt && ulen) {
2309 if (bpf_dump_raw_ok()) {
2310 __u64 __user *user_linfo;
2311 u32 i;
2312
2313 user_linfo = u64_to_user_ptr(info.jited_line_info);
2314 ulen = min_t(u32, info.jited_line_info_cnt, ulen);
2315 for (i = 0; i < ulen; i++) {
2316 if (put_user((__u64)(long)prog->aux->jited_linfo[i],
2317 &user_linfo[i]))
2318 return -EFAULT;
2319 }
2320 } else {
2321 info.jited_line_info = 0;
2322 }
2323 }
2324
2254done: 2325done:
2255 if (copy_to_user(uinfo, &info, info_len) || 2326 if (copy_to_user(uinfo, &info, info_len) ||
2256 put_user(info_len, &uattr->info.info_len)) 2327 put_user(info_len, &uattr->info.info_len))