All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH bpf-next] bpf: New bpf helpers to get perf type of [uk]probe
@ 2023-06-21 12:00 Yafang Shao
  2023-06-21 12:00 ` [RFC PATCH bpf-next] perf: Add perf_type_[uk]probe() Yafang Shao
  2023-06-21 12:00 ` [RFC PATCH bpf-next] bpf: Add two new bpf helpers bpf_perf_type_[uk]probe() Yafang Shao
  0 siblings, 2 replies; 6+ messages in thread
From: Yafang Shao @ 2023-06-21 12:00 UTC (permalink / raw
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa
  Cc: bpf, Yafang Shao

We are utilizing BPF LSM to monitor BPF operations within our container
environment. Our goal is to examine the program type and perform the
respective audits in our LSM program.

When it comes to the perf_event BPF program, there are no specific
definitions for the perf types of kprobe or uprobe. In other words, there
is no PERF_TYPE_[UK]PROBE. It appears that defining them as UAPI at this
stage would be impractical.

Therefore, if we wish to determine whether a new BPF program created via
perf_event_open() is a kprobe or an uprobe, we need to retrieve the type in
userspace by reading /sys/bus/event_source/devices/[uk]probe/type and
subsequently store it in global variables within the LSM program. This
approach proves to be inconvenient.

Here is a short example of LSM program.

  static int perf_type_kprobe = -1; // set it from userspace
  static int perf_type_uprobe = -1; // set it from userspace

  SEC("lsm/perf_event_open")
  int BPF_PROG(perf_event_audit, struct perf_event_attr *attr, int type)
  {
      if (attr->type == perf_type_kprobe)
          return perf_event_kprobe_audit(attr);
      if (attr->type == perf_type_uprobe)
          return perf_event_uprobe_audit(attr);
      return 0;
  }

Two new BPF helpers have been introduced to enhance the functionality.
These helpers allow us to directly obtain the perf type of a kprobe or
uprobe within a BPF program.

After that change, the LSM prog as follows,

  static int perf_type_kprobe;
  static int perf_type_uprobe;

  SEC("lsm/perf_event_open")
  int BPF_PROG(perf_event_audit, struct perf_event_attr *attr, int type)
  {
      if (!perf_type_kprobe)
          perf_type_kprobe = bpf_perf_type_kprobe();
      if (!perf_type_uprobe)
          perf_type_uprobe = bpf_perf_type_uprobe();

      if (attr->type == perf_type_kprobe)
          return perf_event_kprobe_audit(attr);
      if (attr->type == perf_type_uprobe)
          return perf_event_uprobe_audit(attr);
      return 0;
  }

Yafang Shao (2):
  perf: Add perf_type_[uk]probe()
  bpf: Add two new bpf helpers bpf_perf_type_[uk]probe()

 include/linux/bpf.h            |  2 ++
 include/linux/perf_event.h     |  3 +++
 include/uapi/linux/bpf.h       | 18 ++++++++++++++++++
 kernel/bpf/core.c              |  2 ++
 kernel/bpf/helpers.c           | 23 +++++++++++++++++++++++
 kernel/events/core.c           | 18 ++++++++++++++++++
 kernel/trace/bpf_trace.c       |  4 ++++
 tools/include/uapi/linux/bpf.h | 18 ++++++++++++++++++
 8 files changed, 88 insertions(+)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [RFC PATCH bpf-next] perf: Add perf_type_[uk]probe()
  2023-06-21 12:00 [RFC PATCH bpf-next] bpf: New bpf helpers to get perf type of [uk]probe Yafang Shao
@ 2023-06-21 12:00 ` Yafang Shao
  2023-06-21 12:00 ` [RFC PATCH bpf-next] bpf: Add two new bpf helpers bpf_perf_type_[uk]probe() Yafang Shao
  1 sibling, 0 replies; 6+ messages in thread
From: Yafang Shao @ 2023-06-21 12:00 UTC (permalink / raw
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa
  Cc: bpf, Yafang Shao

Add perf_type_uprobe() to get the perf_type of uprobe and
perf_type_kprobe() to get the perf_type of kprobe.

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 include/linux/perf_event.h |  3 +++
 kernel/events/core.c       | 18 ++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index d5628a7..79dbc70 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1881,4 +1881,7 @@ static inline void perf_lopwr_cb(bool mode)
 }
 #endif
 
+int perf_type_kprobe(void);
+int perf_type_uprobe(void);
+
 #endif /* _LINUX_PERF_EVENT_H */
diff --git a/kernel/events/core.c b/kernel/events/core.c
index db016e4..075d4fb 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -10456,6 +10456,24 @@ static inline bool perf_event_is_tracing(struct perf_event *event)
 	return false;
 }
 
+int perf_type_kprobe(void)
+{
+#ifdef CONFIG_KPROBE_EVENTS
+	return perf_kprobe.type;
+#else
+	return -EOPNOTSUPP;
+#endif
+}
+
+int perf_type_uprobe(void)
+{
+#ifdef CONFIG_UPROBE_EVENTS
+	return perf_uprobe.type;
+#else
+	return -EOPNOTSUPP;
+#endif
+}
+
 int perf_event_set_bpf_prog(struct perf_event *event, struct bpf_prog *prog,
 			    u64 bpf_cookie)
 {
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC PATCH bpf-next] bpf: Add two new bpf helpers bpf_perf_type_[uk]probe()
  2023-06-21 12:00 [RFC PATCH bpf-next] bpf: New bpf helpers to get perf type of [uk]probe Yafang Shao
  2023-06-21 12:00 ` [RFC PATCH bpf-next] perf: Add perf_type_[uk]probe() Yafang Shao
@ 2023-06-21 12:00 ` Yafang Shao
  2023-06-21 22:59   ` kernel test robot
  2023-06-22 23:37   ` Alexei Starovoitov
  1 sibling, 2 replies; 6+ messages in thread
From: Yafang Shao @ 2023-06-21 12:00 UTC (permalink / raw
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa
  Cc: bpf, Yafang Shao

We are utilizing BPF LSM to monitor BPF operations within our container
environment. Our goal is to examine the program type and perform the 
respective audits in our LSM program.

When it comes to the perf_event BPF program, there are no specific
definitions for the perf types of kprobe or uprobe. In other words, there
is no PERF_TYPE_[UK]PROBE. It appears that defining them as UAPI at this
stage would be impractical.

Therefore, if we wish to determine whether a new BPF program created via 
perf_event_open() is a kprobe or an uprobe, we need to retrieve the type in
userspace by reading /sys/bus/event_source/devices/[uk]probe/type and 
subsequently store it in global variables within the LSM program. This
approach proves to be inconvenient.

Two new BPF helpers have been introduced to enhance the functionality.
These helpers allow us to directly obtain the perf type of a kprobe or
uprobe within a BPF program.

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 include/linux/bpf.h            |  2 ++
 include/uapi/linux/bpf.h       | 18 ++++++++++++++++++
 kernel/bpf/core.c              |  2 ++
 kernel/bpf/helpers.c           | 23 +++++++++++++++++++++++
 kernel/trace/bpf_trace.c       |  4 ++++
 tools/include/uapi/linux/bpf.h | 18 ++++++++++++++++++
 6 files changed, 67 insertions(+)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index f588958..27135d1 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -2909,6 +2909,8 @@ static inline int bpf_fd_reuseport_array_update_elem(struct bpf_map *map,
 extern const struct bpf_func_proto bpf_user_ringbuf_drain_proto;
 extern const struct bpf_func_proto bpf_cgrp_storage_get_proto;
 extern const struct bpf_func_proto bpf_cgrp_storage_delete_proto;
+extern const struct bpf_func_proto bpf_perf_type_kprobe_proto;
+extern const struct bpf_func_proto bpf_perf_type_uprobe_proto;
 
 const struct bpf_func_proto *tracing_prog_func_proto(
   enum bpf_func_id func_id, const struct bpf_prog *prog);
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index a7b5e91..1ddb1dc 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -5572,6 +5572,22 @@ struct bpf_stack_build_id {
  *		0 on success.
  *
  *		**-ENOENT** if the bpf_local_storage cannot be found.
+ *
+ * int bpf_perf_type_kprobe(void)
+ *	Description
+ *		Get perf_kprobe.type
+ *	Return
+ *		perf_kprobe.type on success.
+ *
+ *		**-EOPNOTSUPP** if CONFIG_KPROBE_EVENTS is not set.
+ *
+ * int bpf_perf_type_uprobe(void)
+ *	Description
+ *		Get perf_uprobe.type
+ *	Return
+ *		perf_uprobe.type on success.
+ *
+ *		**-EOPNOTSUPP** if CONFIG_UPROBE_EVENTS is not set.
  */
 #define ___BPF_FUNC_MAPPER(FN, ctx...)			\
 	FN(unspec, 0, ##ctx)				\
@@ -5786,6 +5802,8 @@ struct bpf_stack_build_id {
 	FN(user_ringbuf_drain, 209, ##ctx)		\
 	FN(cgrp_storage_get, 210, ##ctx)		\
 	FN(cgrp_storage_delete, 211, ##ctx)		\
+	FN(perf_type_kprobe, 212, ##ctx)		\
+	FN(perf_type_uprobe, 213, ##ctx)		\
 	/* */
 
 /* backwards-compatibility macros for users of __BPF_FUNC_MAPPER that don't
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 599136c..ab5fc7e 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -2666,6 +2666,8 @@ void bpf_user_rnd_init_once(void)
 const struct bpf_func_proto bpf_seq_printf_btf_proto __weak;
 const struct bpf_func_proto bpf_set_retval_proto __weak;
 const struct bpf_func_proto bpf_get_retval_proto __weak;
+const struct bpf_func_proto bpf_perf_type_kprobe__weak;
+const struct bpf_func_proto bpf_perf_type_uprobe__weak;
 
 const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void)
 {
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index 9e80efa..f139fe3 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -22,6 +22,7 @@
 #include <linux/security.h>
 #include <linux/btf_ids.h>
 #include <linux/bpf_mem_alloc.h>
+#include <linux/perf_event.h>
 
 #include "../../lib/kstrtox.h"
 
@@ -1654,6 +1655,28 @@ static int bpf_dynptr_check_off_len(const struct bpf_dynptr_kern *ptr, u32 offse
 	.arg3_type	= ARG_CONST_ALLOC_SIZE_OR_ZERO,
 };
 
+BPF_CALL_0(bpf_perf_type_kprobe)
+{
+	return perf_type_kprobe();
+}
+
+const struct bpf_func_proto bpf_perf_type_kprobe_proto = {
+	.func		= bpf_perf_type_kprobe,
+	.gpl_only	= false,
+	.ret_type	= RET_INTEGER,
+};
+
+BPF_CALL_0(bpf_perf_type_uprobe)
+{
+	return perf_type_uprobe();
+}
+
+const struct bpf_func_proto bpf_perf_type_uprobe_proto = {
+	.func		= bpf_perf_type_uprobe,
+	.gpl_only	= false,
+	.ret_type	= RET_INTEGER,
+};
+
 const struct bpf_func_proto bpf_get_current_task_proto __weak;
 const struct bpf_func_proto bpf_get_current_task_btf_proto __weak;
 const struct bpf_func_proto bpf_probe_read_user_proto __weak;
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 2bc41e6..59c66ad 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -1510,6 +1510,10 @@ static int __init bpf_key_sig_kfuncs_init(void)
 		return &bpf_find_vma_proto;
 	case BPF_FUNC_trace_vprintk:
 		return bpf_get_trace_vprintk_proto();
+	case BPF_FUNC_perf_type_kprobe:
+		return &bpf_perf_type_kprobe_proto;
+	case BPF_FUNC_perf_type_uprobe:
+		return &bpf_perf_type_uprobe_proto;
 	default:
 		return bpf_base_func_proto(func_id);
 	}
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index a7b5e91..1ddb1dc 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -5572,6 +5572,22 @@ struct bpf_stack_build_id {
  *		0 on success.
  *
  *		**-ENOENT** if the bpf_local_storage cannot be found.
+ *
+ * int bpf_perf_type_kprobe(void)
+ *	Description
+ *		Get perf_kprobe.type
+ *	Return
+ *		perf_kprobe.type on success.
+ *
+ *		**-EOPNOTSUPP** if CONFIG_KPROBE_EVENTS is not set.
+ *
+ * int bpf_perf_type_uprobe(void)
+ *	Description
+ *		Get perf_uprobe.type
+ *	Return
+ *		perf_uprobe.type on success.
+ *
+ *		**-EOPNOTSUPP** if CONFIG_UPROBE_EVENTS is not set.
  */
 #define ___BPF_FUNC_MAPPER(FN, ctx...)			\
 	FN(unspec, 0, ##ctx)				\
@@ -5786,6 +5802,8 @@ struct bpf_stack_build_id {
 	FN(user_ringbuf_drain, 209, ##ctx)		\
 	FN(cgrp_storage_get, 210, ##ctx)		\
 	FN(cgrp_storage_delete, 211, ##ctx)		\
+	FN(perf_type_kprobe, 212, ##ctx)		\
+	FN(perf_type_uprobe, 213, ##ctx)		\
 	/* */
 
 /* backwards-compatibility macros for users of __BPF_FUNC_MAPPER that don't
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [RFC PATCH bpf-next] bpf: Add two new bpf helpers bpf_perf_type_[uk]probe()
  2023-06-21 12:00 ` [RFC PATCH bpf-next] bpf: Add two new bpf helpers bpf_perf_type_[uk]probe() Yafang Shao
@ 2023-06-21 22:59   ` kernel test robot
  2023-06-22 23:37   ` Alexei Starovoitov
  1 sibling, 0 replies; 6+ messages in thread
From: kernel test robot @ 2023-06-21 22:59 UTC (permalink / raw
  To: Yafang Shao; +Cc: oe-kbuild-all

Hi Yafang,

[This is a private test report for your RFC patch.]
kernel test robot noticed the following build errors:

[auto build test ERROR on bpf-next/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Yafang-Shao/bpf-Add-two-new-bpf-helpers-bpf_perf_type_-uk-probe/20230621-200309
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
patch link:    https://lore.kernel.org/r/20230621120042.3903-3-laoar.shao%40gmail.com
patch subject: [RFC PATCH bpf-next] bpf: Add two new bpf helpers bpf_perf_type_[uk]probe()
config: x86_64-kexec (https://download.01.org/0day-ci/archive/20230622/202306220613.ELA8zSbJ-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce: (https://download.01.org/0day-ci/archive/20230622/202306220613.ELA8zSbJ-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202306220613.ELA8zSbJ-lkp@intel.com/

All errors (new ones prefixed by >>):

   kernel/bpf/helpers.c: In function '____bpf_perf_type_kprobe':
>> kernel/bpf/helpers.c:1660:16: error: implicit declaration of function 'perf_type_kprobe'; did you mean 'bpf_perf_type_kprobe'? [-Werror=implicit-function-declaration]
    1660 |         return perf_type_kprobe();
         |                ^~~~~~~~~~~~~~~~
         |                bpf_perf_type_kprobe
   kernel/bpf/helpers.c: In function '____bpf_perf_type_uprobe':
>> kernel/bpf/helpers.c:1671:16: error: implicit declaration of function 'perf_type_uprobe'; did you mean 'bpf_perf_type_uprobe'? [-Werror=implicit-function-declaration]
    1671 |         return perf_type_uprobe();
         |                ^~~~~~~~~~~~~~~~
         |                bpf_perf_type_uprobe
   cc1: some warnings being treated as errors


vim +1660 kernel/bpf/helpers.c

  1657	
  1658	BPF_CALL_0(bpf_perf_type_kprobe)
  1659	{
> 1660		return perf_type_kprobe();
  1661	}
  1662	
  1663	const struct bpf_func_proto bpf_perf_type_kprobe_proto = {
  1664		.func		= bpf_perf_type_kprobe,
  1665		.gpl_only	= false,
  1666		.ret_type	= RET_INTEGER,
  1667	};
  1668	
  1669	BPF_CALL_0(bpf_perf_type_uprobe)
  1670	{
> 1671		return perf_type_uprobe();
  1672	}
  1673	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC PATCH bpf-next] bpf: Add two new bpf helpers bpf_perf_type_[uk]probe()
  2023-06-21 12:00 ` [RFC PATCH bpf-next] bpf: Add two new bpf helpers bpf_perf_type_[uk]probe() Yafang Shao
  2023-06-21 22:59   ` kernel test robot
@ 2023-06-22 23:37   ` Alexei Starovoitov
  2023-06-23 10:17     ` Yafang Shao
  1 sibling, 1 reply; 6+ messages in thread
From: Alexei Starovoitov @ 2023-06-22 23:37 UTC (permalink / raw
  To: Yafang Shao
  Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa, bpf

On Wed, Jun 21, 2023 at 5:01 AM Yafang Shao <laoar.shao@gmail.com> wrote:
>
> We are utilizing BPF LSM to monitor BPF operations within our container
> environment. Our goal is to examine the program type and perform the
> respective audits in our LSM program.
>
> When it comes to the perf_event BPF program, there are no specific
> definitions for the perf types of kprobe or uprobe. In other words, there
> is no PERF_TYPE_[UK]PROBE. It appears that defining them as UAPI at this
> stage would be impractical.

and yet that's what your patch does.
New helpers are uapi too.
So no-go.

Just do in your filtering bpf prog:
        is_kprobe = event->tp_event->flags & TRACE_EVENT_FL_KPROBE;
        is_uprobe = event->tp_event->flags & TRACE_EVENT_FL_UPROBE;
when it's checking perf_ioctl.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC PATCH bpf-next] bpf: Add two new bpf helpers bpf_perf_type_[uk]probe()
  2023-06-22 23:37   ` Alexei Starovoitov
@ 2023-06-23 10:17     ` Yafang Shao
  0 siblings, 0 replies; 6+ messages in thread
From: Yafang Shao @ 2023-06-23 10:17 UTC (permalink / raw
  To: Alexei Starovoitov
  Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Song Liu, Yonghong Song, John Fastabend,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa, bpf

On Fri, Jun 23, 2023 at 7:37 AM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Wed, Jun 21, 2023 at 5:01 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> >
> > We are utilizing BPF LSM to monitor BPF operations within our container
> > environment. Our goal is to examine the program type and perform the
> > respective audits in our LSM program.
> >
> > When it comes to the perf_event BPF program, there are no specific
> > definitions for the perf types of kprobe or uprobe. In other words, there
> > is no PERF_TYPE_[UK]PROBE. It appears that defining them as UAPI at this
> > stage would be impractical.
>
> and yet that's what your patch does.
> New helpers are uapi too.
> So no-go.
>
> Just do in your filtering bpf prog:
>         is_kprobe = event->tp_event->flags & TRACE_EVENT_FL_KPROBE;
>         is_uprobe = event->tp_event->flags & TRACE_EVENT_FL_UPROBE;
> when it's checking perf_ioctl.

Right. We can hook security_perf_event_write.
Thanks for your suggestion.

-- 
Regards
Yafang

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-06-23 10:18 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-21 12:00 [RFC PATCH bpf-next] bpf: New bpf helpers to get perf type of [uk]probe Yafang Shao
2023-06-21 12:00 ` [RFC PATCH bpf-next] perf: Add perf_type_[uk]probe() Yafang Shao
2023-06-21 12:00 ` [RFC PATCH bpf-next] bpf: Add two new bpf helpers bpf_perf_type_[uk]probe() Yafang Shao
2023-06-21 22:59   ` kernel test robot
2023-06-22 23:37   ` Alexei Starovoitov
2023-06-23 10:17     ` Yafang Shao

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.