History

bpf, x86: Attach a cookie to fentry/fexit/fmod_ret/lsm.

Pass a cookie along with BPF_LINK_CREATE requests. Add a bpf_cookie field to struct bpf_tracing_link to attach a cookie. The cookie of a bpf_tracing_link is available by calling bpf_get_attach_cookie when running the BPF program of the attached link. The value of a cookie will be set at bpf_tramp_run_ctx by the trampoline of the link.

Kui-Feng Lee committed 4 years ago

Commit 2fcc8241 parent e384c7b8 files · +69 −8Browse files

Unified · Split

8 files
  1. arch/x86/net/bpf_jit_comp.c +3 −2
  2. include/linux/bpf.h +1 −0
  3. include/uapi/linux/bpf.h +9 −0
  4. kernel/bpf/bpf_lsm.c +17 −0
  5. kernel/bpf/syscall.c +8 −4
  6. kernel/bpf/trampoline.c +5 −2
  7. kernel/trace/bpf_trace.c +17 −0
  8. tools/include/uapi/linux/bpf.h +9 −0
arch/x86/net/bpf_jit_comp.c+3−2
@@ -1769,9 +1769,10 @@ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog, · 1768 unmodified lines
1769 u8 *jmp_insn;1769 u8 *jmp_insn;
1770 int ctx_cookie_off = offsetof(struct bpf_tramp_run_ctx, bpf_cookie);1770 int ctx_cookie_off = offsetof(struct bpf_tramp_run_ctx, bpf_cookie);
1771 struct bpf_prog *p = l->link.prog;1771 struct bpf_prog *p = l->link.prog;
1772 u64 cookie = l->cookie;
1772 1773
1773 /* mov rdi, 0 */1774 /* mov rdi, cookie */
1774 emit_mov_imm64(&prog, BPF_REG_1, 0, 0);1775 emit_mov_imm64(&prog, BPF_REG_1, (long) cookie >> 32, (u32) (long) cookie);
1775 1776
1776 /* Prepare struct bpf_tramp_run_ctx.1777 /* Prepare struct bpf_tramp_run_ctx.
1777 *1778 *
include/linux/bpf.h+1−0
@@ -1102,6 +1102,7 @@ struct bpf_link_ops { · 1101 unmodified lines
1102struct bpf_tramp_link {1102struct bpf_tramp_link {
1103 struct bpf_link link;1103 struct bpf_link link;
1104 struct hlist_node tramp_hlist;1104 struct hlist_node tramp_hlist;
1105 u64 cookie;
1105};1106};
1106 1107
1107struct bpf_tracing_link {1108struct bpf_tracing_link {
include/uapi/linux/bpf.h+9−0
@@ -1490,6 +1490,15 @@ union bpf_attr { · 1489 unmodified lines
1490 __aligned_u64 addrs;1490 __aligned_u64 addrs;
1491 __aligned_u64 cookies;1491 __aligned_u64 cookies;
1492 } kprobe_multi;1492 } kprobe_multi;
1493 struct {
1494 /* this is overlaid with the target_btf_id above. */
1495 __u32 target_btf_id;
1496 /* black box user-provided value passed through
1497 * to BPF program at the execution time and
1498 * accessible through bpf_get_attach_cookie() BPF helper
1499 */
1500 __u64 cookie;
1501 } tracing;
1493 };1502 };
1494 } link_create;1503 } link_create;
1495 1504
kernel/bpf/bpf_lsm.c+17−0
@@ -117,6 +117,21 @@ static const struct bpf_func_proto bpf_ima_file_hash_proto = { · 116 unmodified lines
117 .allowed = bpf_ima_inode_hash_allowed,117 .allowed = bpf_ima_inode_hash_allowed,
118};118};
119 119
120BPF_CALL_1(bpf_get_attach_cookie, void *, ctx)
121{
122 struct bpf_trace_run_ctx *run_ctx;
123
124 run_ctx = container_of(current->bpf_ctx, struct bpf_trace_run_ctx, run_ctx);
125 return run_ctx->bpf_cookie;
126}
127
128static const struct bpf_func_proto bpf_get_attach_cookie_proto = {
129 .func = bpf_get_attach_cookie,
130 .gpl_only = false,
131 .ret_type = RET_INTEGER,
132 .arg1_type = ARG_PTR_TO_CTX,
133};
134
120static const struct bpf_func_proto *135static const struct bpf_func_proto *
121bpf_lsm_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)136bpf_lsm_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
122{137{
@@ -141,6 +156,8 @@ bpf_lsm_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) · 18 unmodified lines
141 return prog->aux->sleepable ? &bpf_ima_inode_hash_proto : NULL;156 return prog->aux->sleepable ? &bpf_ima_inode_hash_proto : NULL;
142 case BPF_FUNC_ima_file_hash:157 case BPF_FUNC_ima_file_hash:
143 return prog->aux->sleepable ? &bpf_ima_file_hash_proto : NULL;158 return prog->aux->sleepable ? &bpf_ima_file_hash_proto : NULL;
159 case BPF_FUNC_get_attach_cookie:
160 return bpf_prog_has_trampoline(prog) ? &bpf_get_attach_cookie_proto : NULL;
144 default:161 default:
145 return tracing_prog_func_proto(func_id, prog);162 return tracing_prog_func_proto(func_id, prog);
146 }163 }
kernel/bpf/syscall.c+8−4
@@ -2921,7 +2921,8 @@ static const struct bpf_link_ops bpf_tracing_link_lops = { · 2920 unmodified lines
2921 2921
2922static int bpf_tracing_prog_attach(struct bpf_prog *prog,2922static int bpf_tracing_prog_attach(struct bpf_prog *prog,
2923 int tgt_prog_fd,2923 int tgt_prog_fd,
2924 u32 btf_id)2924 u32 btf_id,
2925 u64 bpf_cookie)
2925{2926{
2926 struct bpf_link_primer link_primer;2927 struct bpf_link_primer link_primer;
2927 struct bpf_prog *tgt_prog = NULL;2928 struct bpf_prog *tgt_prog = NULL;
@@ -2986,6 +2987,7 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog, · 58 unmodified lines
2986 bpf_link_init(&link->link.link, BPF_LINK_TYPE_TRACING,2987 bpf_link_init(&link->link.link, BPF_LINK_TYPE_TRACING,
2987 &bpf_tracing_link_lops, prog);2988 &bpf_tracing_link_lops, prog);
2988 link->attach_type = prog->expected_attach_type;2989 link->attach_type = prog->expected_attach_type;
2990 link->link.cookie = bpf_cookie;
2989 2991
2990 mutex_lock(&prog->aux->dst_mutex);2992 mutex_lock(&prog->aux->dst_mutex);
2991 2993
@@ -3271,7 +3273,7 @@ static int bpf_raw_tp_link_attach(struct bpf_prog *prog, · 279 unmodified lines
3271 tp_name = prog->aux->attach_func_name;3273 tp_name = prog->aux->attach_func_name;
3272 break;3274 break;
3273 }3275 }
3274 return bpf_tracing_prog_attach(prog, 0, 0);3276 return bpf_tracing_prog_attach(prog, 0, 0, 0);
3275 case BPF_PROG_TYPE_RAW_TRACEPOINT:3277 case BPF_PROG_TYPE_RAW_TRACEPOINT:
3276 case BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE:3278 case BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE:
3277 if (strncpy_from_user(buf, user_tp_name, sizeof(buf) - 1) < 0)3279 if (strncpy_from_user(buf, user_tp_name, sizeof(buf) - 1) < 0)
@@ -4524,7 +4526,8 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr) · 1246 unmodified lines
4524 case BPF_PROG_TYPE_EXT:4526 case BPF_PROG_TYPE_EXT:
4525 ret = bpf_tracing_prog_attach(prog,4527 ret = bpf_tracing_prog_attach(prog,
4526 attr->link_create.target_fd,4528 attr->link_create.target_fd,
4527 attr->link_create.target_btf_id);4529 attr->link_create.target_btf_id,
4530 attr->link_create.tracing.cookie);
4528 break;4531 break;
4529 case BPF_PROG_TYPE_LSM:4532 case BPF_PROG_TYPE_LSM:
4530 case BPF_PROG_TYPE_TRACING:4533 case BPF_PROG_TYPE_TRACING:
@@ -4539,7 +4542,8 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr) · 8 unmodified lines
4539 else4542 else
4540 ret = bpf_tracing_prog_attach(prog,4543 ret = bpf_tracing_prog_attach(prog,
4541 attr->link_create.target_fd,4544 attr->link_create.target_fd,
4542 attr->link_create.target_btf_id);4545 attr->link_create.target_btf_id,
4546 attr->link_create.tracing.cookie);
4543 break;4547 break;
4544 case BPF_PROG_TYPE_FLOW_DISSECTOR:4548 case BPF_PROG_TYPE_FLOW_DISSECTOR:
4545 case BPF_PROG_TYPE_SK_LOOKUP:4549 case BPF_PROG_TYPE_SK_LOOKUP:
kernel/bpf/trampoline.c+5−2
@@ -30,9 +30,12 @@ static DEFINE_MUTEX(trampoline_mutex); · 29 unmodified lines
30bool bpf_prog_has_trampoline(const struct bpf_prog *prog)30bool bpf_prog_has_trampoline(const struct bpf_prog *prog)
31{31{
32 enum bpf_attach_type eatype = prog->expected_attach_type;32 enum bpf_attach_type eatype = prog->expected_attach_type;
33 enum bpf_prog_type ptype = prog->type;
33 34
34 return eatype == BPF_TRACE_FENTRY || eatype == BPF_TRACE_FEXIT ||35 return (ptype == BPF_PROG_TYPE_TRACING &&
35 eatype == BPF_MODIFY_RETURN;36 (eatype == BPF_TRACE_FENTRY || eatype == BPF_TRACE_FEXIT ||
37 eatype == BPF_MODIFY_RETURN)) ||
38 (ptype == BPF_PROG_TYPE_LSM && eatype == BPF_LSM_MAC);
36}39}
37 40
38void *bpf_jit_alloc_exec_page(void)41void *bpf_jit_alloc_exec_page(void)
kernel/trace/bpf_trace.c+17−0
@@ -1091,6 +1091,21 @@ static const struct bpf_func_proto bpf_get_attach_cookie_proto_pe = { · 1090 unmodified lines
1091 .arg1_type = ARG_PTR_TO_CTX,1091 .arg1_type = ARG_PTR_TO_CTX,
1092};1092};
1093 1093
1094BPF_CALL_1(bpf_get_attach_cookie_tracing, void *, ctx)
1095{
1096 struct bpf_trace_run_ctx *run_ctx;
1097
1098 run_ctx = container_of(current->bpf_ctx, struct bpf_trace_run_ctx, run_ctx);
1099 return run_ctx->bpf_cookie;
1100}
1101
1102static const struct bpf_func_proto bpf_get_attach_cookie_proto_tracing = {
1103 .func = bpf_get_attach_cookie_tracing,
1104 .gpl_only = false,
1105 .ret_type = RET_INTEGER,
1106 .arg1_type = ARG_PTR_TO_CTX,
1107};
1108
1094BPF_CALL_3(bpf_get_branch_snapshot, void *, buf, u32, size, u64, flags)1109BPF_CALL_3(bpf_get_branch_snapshot, void *, buf, u32, size, u64, flags)
1095{1110{
1096#ifndef CONFIG_X861111#ifndef CONFIG_X86
@@ -1719,6 +1734,8 @@ tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) · 622 unmodified lines
1719 return bpf_prog_has_trampoline(prog) ? &bpf_get_func_ret_proto : NULL;1734 return bpf_prog_has_trampoline(prog) ? &bpf_get_func_ret_proto : NULL;
1720 case BPF_FUNC_get_func_arg_cnt:1735 case BPF_FUNC_get_func_arg_cnt:
1721 return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_cnt_proto : NULL;1736 return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_cnt_proto : NULL;
1737 case BPF_FUNC_get_attach_cookie:
1738 return bpf_prog_has_trampoline(prog) ? &bpf_get_attach_cookie_proto_tracing : NULL;
1722 default:1739 default:
1723 fn = raw_tp_prog_func_proto(func_id, prog);1740 fn = raw_tp_prog_func_proto(func_id, prog);
1724 if (!fn && prog->expected_attach_type == BPF_TRACE_ITER)1741 if (!fn && prog->expected_attach_type == BPF_TRACE_ITER)
tools/include/uapi/linux/bpf.h+9−0
@@ -1490,6 +1490,15 @@ union bpf_attr { · 1489 unmodified lines
1490 __aligned_u64 addrs;1490 __aligned_u64 addrs;
1491 __aligned_u64 cookies;1491 __aligned_u64 cookies;
1492 } kprobe_multi;1492 } kprobe_multi;
1493 struct {
1494 /* this is overlaid with the target_btf_id above. */
1495 __u32 target_btf_id;
1496 /* black box user-provided value passed through
1497 * to BPF program at the execution time and
1498 * accessible through bpf_get_attach_cookie() BPF helper
1499 */
1500 __u64 cookie;
1501 } tracing;
1493 };1502 };
1494 } link_create;1503 } link_create;
1495 1504