diff mbox series

[bpf-next,3/6] bpf: support attaching freplace programs to multiple attach points

Message ID 159467114297.370286.13434549915540848776.stgit@toke.dk
State Changes Requested
Delegated to: BPF Maintainers
Headers show
Series bpf: Support multi-attach for freplace programs | expand

Commit Message

Toke Høiland-Jørgensen July 13, 2020, 8:12 p.m. UTC
From: Toke Høiland-Jørgensen <toke@redhat.com>

This enables support for attaching freplace programs to multiple attach
points. It does this by amending UAPI for bpf_raw_tracepoint_open with a
target prog fd and btf ID pair that can be used to supply the new
attachment point. The target must be compatible with the target that was
supplied at program load time.

Since the checks for the attach target compatibility will output debug
information about why the attachment was rejected to the verifier log, also
add support for supplying a log buffer to bpf_raw_tracepoint_open.

The implementation reuses the checks that were factored out of
check_attach_btf_id() in the previous patch. It also moves the BPF
trampoline out of prog->aux and into struct bpf_tracking_link where it is
managed as part of the bpf_link structure. When a new target is specified,
a reference to the target program is also kept in the bpf_link structure
which removes the need to keep references to all attach targets in the
bpf_prog structure itself.

The code could theoretically support multiple-attach of other types of
tracing programs as well, but since I don't have a use case for any of
those, the bpf_tracing_prog_attach() function will reject new targets for
anything other than PROG_TYPE_EXT programs.

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
 include/linux/bpf.h      |   14 ++++---
 include/uapi/linux/bpf.h |    9 +++-
 kernel/bpf/core.c        |    1 
 kernel/bpf/syscall.c     |   96 +++++++++++++++++++++++++++++++++++++++++++---
 kernel/bpf/trampoline.c  |   14 +++----
 kernel/bpf/verifier.c    |   16 +++++---
 6 files changed, 121 insertions(+), 29 deletions(-)

Comments

kernel test robot July 13, 2020, 11:16 p.m. UTC | #1
Hi "Toke,

I love your patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]
[also build test WARNING on vhost/linux-next ipvs/master v5.8-rc5 next-20200713]
[cannot apply to bpf-next/master bpf/master net/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use  as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Toke-H-iland-J-rgensen/bpf-Support-multi-attach-for-freplace-programs/20200714-041410
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 528ae84a34ffd40da5d3fbff740d28d6dc2c8f8a
config: nios2-allyesconfig (attached as .config)
compiler: nios2-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=nios2 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   kernel/bpf/syscall.c: In function 'bpf_raw_tracepoint_open':
>> kernel/bpf/syscall.c:2831:1: warning: the frame size of 1172 bytes is larger than 1024 bytes [-Wframe-larger-than=]
    2831 | }
         | ^

vim +2831 kernel/bpf/syscall.c

c4f6699dfcb8558 Alexei Starovoitov     2018-03-28  2726  
c4f6699dfcb8558 Alexei Starovoitov     2018-03-28  2727  static int bpf_raw_tracepoint_open(const union bpf_attr *attr)
c4f6699dfcb8558 Alexei Starovoitov     2018-03-28  2728  {
a3b80e1078943dc Andrii Nakryiko        2020-04-28  2729  	struct bpf_link_primer link_primer;
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2730  	struct bpf_verifier_log log = {};
babf3164095b067 Andrii Nakryiko        2020-03-09  2731  	struct bpf_raw_tp_link *link;
c4f6699dfcb8558 Alexei Starovoitov     2018-03-28  2732  	struct bpf_raw_event_map *btp;
c4f6699dfcb8558 Alexei Starovoitov     2018-03-28  2733  	struct bpf_prog *prog;
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2734  	const char *tp_name;
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2735  	char buf[128];
a3b80e1078943dc Andrii Nakryiko        2020-04-28  2736  	int err;
c4f6699dfcb8558 Alexei Starovoitov     2018-03-28  2737  
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2738  	if (CHECK_ATTR(BPF_RAW_TRACEPOINT_OPEN))
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2739  		return -EINVAL;
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2740  
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2741  	prog = bpf_prog_get(attr->raw_tracepoint.prog_fd);
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2742  	if (IS_ERR(prog))
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2743  		return PTR_ERR(prog);
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2744  
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2745  	if (attr->raw_tracepoint.log_level ||
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2746  	    attr->raw_tracepoint.log_buf ||
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2747  	    attr->raw_tracepoint.log_size) {
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2748  		/* user requested verbose verifier output
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2749  		 * and supplied buffer to store the verification trace
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2750  		 */
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2751  		log.level = attr->raw_tracepoint.log_level;
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2752  		log.ubuf = (char __user *) (unsigned long) attr->raw_tracepoint.log_buf;
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2753  		log.len_total = attr->raw_tracepoint.log_size;
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2754  
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2755  		/* log attributes have to be sane */
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2756  		if (log.len_total < 128 || log.len_total > UINT_MAX >> 2 ||
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2757  		    !log.level || !log.ubuf || log.level & ~BPF_LOG_MASK)
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2758  			return -EINVAL;
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2759  	}
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2760  
9e4e01dfd3254c7 KP Singh               2020-03-29  2761  	switch (prog->type) {
9e4e01dfd3254c7 KP Singh               2020-03-29  2762  	case BPF_PROG_TYPE_TRACING:
9e4e01dfd3254c7 KP Singh               2020-03-29  2763  	case BPF_PROG_TYPE_EXT:
9e4e01dfd3254c7 KP Singh               2020-03-29  2764  	case BPF_PROG_TYPE_LSM:
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2765  		if (attr->raw_tracepoint.name) {
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2766  			/* The attach point for this category of programs should
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2767  			 * be specified via btf_id during program load, or using
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2768  			 * tgt_btf_id.
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2769  			 */
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2770  			err = -EINVAL;
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2771  			goto out_put_prog;
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2772  		}
9e4e01dfd3254c7 KP Singh               2020-03-29  2773  		if (prog->type == BPF_PROG_TYPE_TRACING &&
9e4e01dfd3254c7 KP Singh               2020-03-29  2774  		    prog->expected_attach_type == BPF_TRACE_RAW_TP) {
382072916044015 Martin KaFai Lau       2019-10-24  2775  			tp_name = prog->aux->attach_func_name;
9e4e01dfd3254c7 KP Singh               2020-03-29  2776  			break;
9e4e01dfd3254c7 KP Singh               2020-03-29  2777  		}
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2778  		return bpf_tracing_prog_attach(prog,
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2779  					       attr->raw_tracepoint.tgt_prog_fd,
95dcc8ca42c35eb Toke Høiland-Jørgensen 2020-07-13  2780  					       attr->raw_tracepoint.tgt_btf_id, &log);
9e4e01dfd3254c7 KP Singh               2020-03-29  2781  	case BPF_PROG_TYPE_RAW_TRACEPOINT:
9e4e01dfd3254c7 KP Singh               2020-03-29  2782  	case BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE:
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2783  		if (strncpy_from_user(buf,
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2784  				      u64_to_user_ptr(attr->raw_tracepoint.name),
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2785  				      sizeof(buf) - 1) < 0) {
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2786  			err = -EFAULT;
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2787  			goto out_put_prog;
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2788  		}
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2789  		buf[sizeof(buf) - 1] = 0;
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2790  		tp_name = buf;
9e4e01dfd3254c7 KP Singh               2020-03-29  2791  		break;
9e4e01dfd3254c7 KP Singh               2020-03-29  2792  	default:
9e4e01dfd3254c7 KP Singh               2020-03-29  2793  		err = -EINVAL;
9e4e01dfd3254c7 KP Singh               2020-03-29  2794  		goto out_put_prog;
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2795  	}
c4f6699dfcb8558 Alexei Starovoitov     2018-03-28  2796  
a38d1107f937ca9 Matt Mullins           2018-12-12  2797  	btp = bpf_get_raw_tracepoint(tp_name);
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2798  	if (!btp) {
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2799  		err = -ENOENT;
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2800  		goto out_put_prog;
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2801  	}
c4f6699dfcb8558 Alexei Starovoitov     2018-03-28  2802  
babf3164095b067 Andrii Nakryiko        2020-03-09  2803  	link = kzalloc(sizeof(*link), GFP_USER);
babf3164095b067 Andrii Nakryiko        2020-03-09  2804  	if (!link) {
a38d1107f937ca9 Matt Mullins           2018-12-12  2805  		err = -ENOMEM;
a38d1107f937ca9 Matt Mullins           2018-12-12  2806  		goto out_put_btp;
a38d1107f937ca9 Matt Mullins           2018-12-12  2807  	}
f2e10bff16a0fdd Andrii Nakryiko        2020-04-28  2808  	bpf_link_init(&link->link, BPF_LINK_TYPE_RAW_TRACEPOINT,
f2e10bff16a0fdd Andrii Nakryiko        2020-04-28  2809  		      &bpf_raw_tp_link_lops, prog);
babf3164095b067 Andrii Nakryiko        2020-03-09  2810  	link->btp = btp;
c4f6699dfcb8558 Alexei Starovoitov     2018-03-28  2811  
a3b80e1078943dc Andrii Nakryiko        2020-04-28  2812  	err = bpf_link_prime(&link->link, &link_primer);
a3b80e1078943dc Andrii Nakryiko        2020-04-28  2813  	if (err) {
babf3164095b067 Andrii Nakryiko        2020-03-09  2814  		kfree(link);
babf3164095b067 Andrii Nakryiko        2020-03-09  2815  		goto out_put_btp;
babf3164095b067 Andrii Nakryiko        2020-03-09  2816  	}
c4f6699dfcb8558 Alexei Starovoitov     2018-03-28  2817  
babf3164095b067 Andrii Nakryiko        2020-03-09  2818  	err = bpf_probe_register(link->btp, prog);
babf3164095b067 Andrii Nakryiko        2020-03-09  2819  	if (err) {
a3b80e1078943dc Andrii Nakryiko        2020-04-28  2820  		bpf_link_cleanup(&link_primer);
babf3164095b067 Andrii Nakryiko        2020-03-09  2821  		goto out_put_btp;
c4f6699dfcb8558 Alexei Starovoitov     2018-03-28  2822  	}
babf3164095b067 Andrii Nakryiko        2020-03-09  2823  
a3b80e1078943dc Andrii Nakryiko        2020-04-28  2824  	return bpf_link_settle(&link_primer);
c4f6699dfcb8558 Alexei Starovoitov     2018-03-28  2825  
a38d1107f937ca9 Matt Mullins           2018-12-12  2826  out_put_btp:
a38d1107f937ca9 Matt Mullins           2018-12-12  2827  	bpf_put_raw_tracepoint(btp);
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2828  out_put_prog:
ac4414b5ca47d16 Alexei Starovoitov     2019-10-15  2829  	bpf_prog_put(prog);
c4f6699dfcb8558 Alexei Starovoitov     2018-03-28  2830  	return err;
c4f6699dfcb8558 Alexei Starovoitov     2018-03-28 @2831  }
c4f6699dfcb8558 Alexei Starovoitov     2018-03-28  2832  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 67310595f720..3d43778a1d05 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -568,8 +568,8 @@  static __always_inline unsigned int bpf_dispatcher_nop_func(
 }
 #ifdef CONFIG_BPF_JIT
 struct bpf_trampoline *bpf_trampoline_lookup(u64 key);
-int bpf_trampoline_link_prog(struct bpf_prog *prog);
-int bpf_trampoline_unlink_prog(struct bpf_prog *prog);
+int bpf_trampoline_link_prog(struct bpf_prog *prog, struct bpf_trampoline *tr);
+int bpf_trampoline_unlink_prog(struct bpf_prog *prog, struct bpf_trampoline *tr);
 int bpf_trampoline_get(u64 key, void *addr,
 		       struct btf_func_model *fmodel,
 		       struct bpf_trampoline **trampoline);
@@ -621,11 +621,13 @@  static inline struct bpf_trampoline *bpf_trampoline_lookup(u64 key)
 {
 	return NULL;
 }
-static inline int bpf_trampoline_link_prog(struct bpf_prog *prog)
+static inline int bpf_trampoline_link_prog(struct bpf_prog *prog,
+					   struct bpf_trampoline *tr)
 {
 	return -ENOTSUPP;
 }
-static inline int bpf_trampoline_unlink_prog(struct bpf_prog *prog)
+static inline int bpf_trampoline_unlink_prog(struct bpf_prog *prog,
+					     struct bpf_trampoline *tr)
 {
 	return -ENOTSUPP;
 }
@@ -697,10 +699,12 @@  struct bpf_prog_aux {
 	bool attach_btf_trace; /* true if attaching to BTF-enabled raw tp */
 	bool func_proto_unreliable;
 	enum bpf_tramp_prog_type trampoline_prog_type;
-	struct bpf_trampoline *trampoline;
 	struct hlist_node tramp_hlist;
 	/* BTF_KIND_FUNC_PROTO for valid attach_btf_id */
 	const struct btf_type *attach_func_proto;
+	/* target BPF prog types for trace programs */
+	enum bpf_prog_type tgt_prog_type;
+	enum bpf_attach_type tgt_attach_type;
 	/* function name for valid attach_btf_id */
 	const char *attach_func_name;
 	struct bpf_prog **func;
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index da9bf35a26f8..662a15e4a1a1 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -573,8 +573,13 @@  union bpf_attr {
 	} query;
 
 	struct { /* anonymous struct used by BPF_RAW_TRACEPOINT_OPEN command */
-		__u64 name;
-		__u32 prog_fd;
+		__u64		name;
+		__u32		prog_fd;
+		__u32		log_level;	/* verbosity level of log */
+		__u32		log_size;	/* size of user buffer */
+		__aligned_u64	log_buf;	/* user supplied buffer */
+		__u32		tgt_prog_fd;
+		__u32		tgt_btf_id;
 	} raw_tracepoint;
 
 	struct { /* anonymous struct for BPF_BTF_LOAD */
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 9df4cc9a2907..ed4d7259316a 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -2087,7 +2087,6 @@  static void bpf_prog_free_deferred(struct work_struct *work)
 	if (aux->prog->has_callchain_buf)
 		put_callchain_buffers();
 #endif
-	bpf_trampoline_put(aux->trampoline);
 	for (i = 0; i < aux->func_cnt; i++)
 		bpf_jit_free(aux->func[i]);
 	if (aux->func_cnt) {
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 8da159936bab..eec6dc0f0a54 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -4,6 +4,7 @@ 
 #include <linux/bpf.h>
 #include <linux/bpf_trace.h>
 #include <linux/bpf_lirc.h>
+#include <linux/bpf_verifier.h>
 #include <linux/btf.h>
 #include <linux/syscalls.h>
 #include <linux/slab.h>
@@ -2483,11 +2484,21 @@  struct bpf_link *bpf_link_get_from_fd(u32 ufd)
 struct bpf_tracing_link {
 	struct bpf_link link;
 	enum bpf_attach_type attach_type;
+	struct bpf_trampoline *trampoline;
+	struct bpf_prog *tgt_prog;
 };
 
 static void bpf_tracing_link_release(struct bpf_link *link)
 {
-	WARN_ON_ONCE(bpf_trampoline_unlink_prog(link->prog));
+	struct bpf_tracing_link *tr_link =
+		container_of(link, struct bpf_tracing_link, link);
+
+	WARN_ON_ONCE(bpf_trampoline_unlink_prog(link->prog,
+						tr_link->trampoline));
+
+	bpf_trampoline_put(tr_link->trampoline);
+	if (tr_link->tgt_prog)
+		bpf_prog_put(tr_link->tgt_prog);
 }
 
 static void bpf_tracing_link_dealloc(struct bpf_link *link)
@@ -2527,10 +2538,18 @@  static const struct bpf_link_ops bpf_tracing_link_lops = {
 	.fill_link_info = bpf_tracing_link_fill_link_info,
 };
 
-static int bpf_tracing_prog_attach(struct bpf_prog *prog)
+static int bpf_tracing_prog_attach(struct bpf_prog *prog,
+				   int tgt_prog_fd,
+				   u32 btf_id,
+				   struct bpf_verifier_log *log)
 {
 	struct bpf_link_primer link_primer;
+	struct bpf_trampoline *tr = NULL;
+	struct bpf_prog *tgt_prog = NULL;
 	struct bpf_tracing_link *link;
+	struct btf_func_model fmodel;
+	long addr;
+	u64 key;
 	int err;
 
 	switch (prog->type) {
@@ -2559,6 +2578,43 @@  static int bpf_tracing_prog_attach(struct bpf_prog *prog)
 		goto out_put_prog;
 	}
 
+	if (tgt_prog_fd) {
+		/* For now we only allow new targets for BPF_PROG_TYPE_EXT */
+		if (prog->type != BPF_PROG_TYPE_EXT ||
+		    !btf_id) {
+			err = -EINVAL;
+			goto out_put_prog;
+		}
+		tgt_prog = bpf_prog_get(tgt_prog_fd);
+		if (IS_ERR(tgt_prog)) {
+			err = PTR_ERR(tgt_prog);
+			tgt_prog = NULL;
+			goto out_put_prog;
+		}
+
+	} else if (btf_id) {
+		err = -EINVAL;
+		goto out_put_prog;
+	} else {
+		btf_id = prog->aux->attach_btf_id;
+		tgt_prog = prog->aux->linked_prog;
+		if (tgt_prog)
+			bpf_prog_inc(tgt_prog); /* we call bpf_prog_put() on link release */
+	}
+	err = bpf_check_attach_target(log, prog, tgt_prog, btf_id,
+				      &fmodel, &addr, NULL, NULL);
+	if (err)
+		goto out_put_prog;
+
+	if (tgt_prog)
+		key = ((u64)tgt_prog->aux->id) << 32 | btf_id;
+	else
+		key = btf_id;
+
+	err = bpf_trampoline_get(key, (void *)addr, &fmodel, &tr);
+	if (err)
+		goto out_put_prog;
+
 	link = kzalloc(sizeof(*link), GFP_USER);
 	if (!link) {
 		err = -ENOMEM;
@@ -2574,15 +2630,21 @@  static int bpf_tracing_prog_attach(struct bpf_prog *prog)
 		goto out_put_prog;
 	}
 
-	err = bpf_trampoline_link_prog(prog);
+	err = bpf_trampoline_link_prog(prog, tr);
 	if (err) {
 		bpf_link_cleanup(&link_primer);
 		goto out_put_prog;
 	}
+	link->trampoline = tr;
+	link->tgt_prog = tgt_prog;
 
 	return bpf_link_settle(&link_primer);
 out_put_prog:
 	bpf_prog_put(prog);
+	if (tgt_prog)
+		bpf_prog_put(tgt_prog);
+	if (tr)
+		bpf_trampoline_put(tr);
 	return err;
 }
 
@@ -2660,11 +2722,12 @@  static const struct bpf_link_ops bpf_raw_tp_link_lops = {
 	.fill_link_info = bpf_raw_tp_link_fill_link_info,
 };
 
-#define BPF_RAW_TRACEPOINT_OPEN_LAST_FIELD raw_tracepoint.prog_fd
+#define BPF_RAW_TRACEPOINT_OPEN_LAST_FIELD raw_tracepoint.tgt_btf_id
 
 static int bpf_raw_tracepoint_open(const union bpf_attr *attr)
 {
 	struct bpf_link_primer link_primer;
+	struct bpf_verifier_log log = {};
 	struct bpf_raw_tp_link *link;
 	struct bpf_raw_event_map *btp;
 	struct bpf_prog *prog;
@@ -2679,13 +2742,30 @@  static int bpf_raw_tracepoint_open(const union bpf_attr *attr)
 	if (IS_ERR(prog))
 		return PTR_ERR(prog);
 
+	if (attr->raw_tracepoint.log_level ||
+	    attr->raw_tracepoint.log_buf ||
+	    attr->raw_tracepoint.log_size) {
+		/* user requested verbose verifier output
+		 * and supplied buffer to store the verification trace
+		 */
+		log.level = attr->raw_tracepoint.log_level;
+		log.ubuf = (char __user *) (unsigned long) attr->raw_tracepoint.log_buf;
+		log.len_total = attr->raw_tracepoint.log_size;
+
+		/* log attributes have to be sane */
+		if (log.len_total < 128 || log.len_total > UINT_MAX >> 2 ||
+		    !log.level || !log.ubuf || log.level & ~BPF_LOG_MASK)
+			return -EINVAL;
+	}
+
 	switch (prog->type) {
 	case BPF_PROG_TYPE_TRACING:
 	case BPF_PROG_TYPE_EXT:
 	case BPF_PROG_TYPE_LSM:
 		if (attr->raw_tracepoint.name) {
-			/* The attach point for this category of programs
-			 * should be specified via btf_id during program load.
+			/* The attach point for this category of programs should
+			 * be specified via btf_id during program load, or using
+			 * tgt_btf_id.
 			 */
 			err = -EINVAL;
 			goto out_put_prog;
@@ -2695,7 +2775,9 @@  static int bpf_raw_tracepoint_open(const union bpf_attr *attr)
 			tp_name = prog->aux->attach_func_name;
 			break;
 		}
-		return bpf_tracing_prog_attach(prog);
+		return bpf_tracing_prog_attach(prog,
+					       attr->raw_tracepoint.tgt_prog_fd,
+					       attr->raw_tracepoint.tgt_btf_id, &log);
 	case BPF_PROG_TYPE_RAW_TRACEPOINT:
 	case BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE:
 		if (strncpy_from_user(buf,
diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
index fadfa330f728..40797405f1a0 100644
--- a/kernel/bpf/trampoline.c
+++ b/kernel/bpf/trampoline.c
@@ -256,14 +256,13 @@  static enum bpf_tramp_prog_type bpf_attach_type_to_tramp(struct bpf_prog *prog)
 	}
 }
 
-int bpf_trampoline_link_prog(struct bpf_prog *prog)
+int bpf_trampoline_link_prog(struct bpf_prog *prog,
+			     struct bpf_trampoline *tr)
 {
 	enum bpf_tramp_prog_type kind;
-	struct bpf_trampoline *tr;
 	int err = 0;
 	int cnt;
 
-	tr = prog->aux->trampoline;
 	kind = bpf_attach_type_to_tramp(prog);
 	mutex_lock(&tr->mutex);
 	if (tr->extension_prog) {
@@ -296,7 +295,7 @@  int bpf_trampoline_link_prog(struct bpf_prog *prog)
 	}
 	hlist_add_head(&prog->aux->tramp_hlist, &tr->progs_hlist[kind]);
 	tr->progs_cnt[kind]++;
-	err = bpf_trampoline_update(prog->aux->trampoline);
+	err = bpf_trampoline_update(tr);
 	if (err) {
 		hlist_del(&prog->aux->tramp_hlist);
 		tr->progs_cnt[kind]--;
@@ -307,13 +306,12 @@  int bpf_trampoline_link_prog(struct bpf_prog *prog)
 }
 
 /* bpf_trampoline_unlink_prog() should never fail. */
-int bpf_trampoline_unlink_prog(struct bpf_prog *prog)
+int bpf_trampoline_unlink_prog(struct bpf_prog *prog,
+			       struct bpf_trampoline *tr)
 {
 	enum bpf_tramp_prog_type kind;
-	struct bpf_trampoline *tr;
 	int err;
 
-	tr = prog->aux->trampoline;
 	kind = bpf_attach_type_to_tramp(prog);
 	mutex_lock(&tr->mutex);
 	if (kind == BPF_TRAMP_REPLACE) {
@@ -325,7 +323,7 @@  int bpf_trampoline_unlink_prog(struct bpf_prog *prog)
 	}
 	hlist_del(&prog->aux->tramp_hlist);
 	tr->progs_cnt[kind]--;
-	err = bpf_trampoline_update(prog->aux->trampoline);
+	err = bpf_trampoline_update(tr);
 out:
 	mutex_unlock(&tr->mutex);
 	return err;
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index ff3c5c53982c..867bc14f5610 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -10889,6 +10889,12 @@  int bpf_check_attach_target(struct bpf_verifier_log *log,
 		if (!btf_type_is_func_proto(t))
 			return -EINVAL;
 
+		if ((prog->aux->tgt_prog_type &&
+		     prog->aux->tgt_prog_type != tgt_prog->type) ||
+		    (prog->aux->tgt_attach_type &&
+		     prog->aux->tgt_attach_type != tgt_prog->expected_attach_type))
+			return -EINVAL;
+
 		if (tgt_prog && conservative)
 			t = NULL;
 
@@ -10931,7 +10937,6 @@  static int check_attach_btf_id(struct bpf_verifier_env *env)
 	const char *tname;
 	long addr;
 	int ret;
-	u64 key;
 
 	if (prog->type == BPF_PROG_TYPE_STRUCT_OPS)
 		return check_struct_ops_btf_id(env);
@@ -10947,13 +10952,13 @@  static int check_attach_btf_id(struct bpf_verifier_env *env)
 		return ret;
 
 	if (tgt_prog) {
+		prog->aux->tgt_prog_type = tgt_prog->type;
+		prog->aux->tgt_attach_type = tgt_prog->expected_attach_type;
+
 		if (prog->type == BPF_PROG_TYPE_EXT) {
 			env->ops = bpf_verifier_ops[tgt_prog->type];
 			prog->expected_attach_type = tgt_prog->expected_attach_type;
 		}
-		key = ((u64)tgt_prog->aux->id) << 32 | btf_id;
-	} else {
-		key = btf_id;
 	}
 
 	prog->aux->attach_func_proto = t;
@@ -10984,8 +10989,7 @@  static int check_attach_btf_id(struct bpf_verifier_env *env)
 			if (ret < 0)
 				return ret;
 		}
-		return bpf_trampoline_get(key, (void *)addr, &fmodel,
-					  &prog->aux->trampoline);
+		return 0;
 	}
 }