* Re: [PATCH] Add support for new syscall memfd_secret
2021-12-03 6:46 [PATCH] Add support for new syscall memfd_secret Di Chen
@ 2022-02-24 22:47 ` Di Chen
2022-02-25 23:36 ` Aaron Merey
0 siblings, 1 reply; 4+ messages in thread
From: Di Chen @ 2022-02-24 22:47 UTC (permalink / raw)
To: systemtap
[-- Attachment #1: Type: text/plain, Size: 6487 bytes --]
Hey team systemtap,
I have fixed some formatting issues, here is the new patch for it.
Could you please help review it?
On Fri, Dec 3, 2021 at 2:46 PM Di Chen <dichen@redhat.com> wrote:
>
> From d2afae5de4c5135046606420787d539865b1832c Mon Sep 17 00:00:00 2001
> From: Di Chen <dichen@redhat.com>
> Date: Fri, 5 Nov 2021 22:34:37 +0800
> Subject: [PATCH] Add support for new syscall memfd_secret
>
> Linux 5.14 added the memfd_secret syscall, adding tapset support.
>
> memfd_secret() was disabled by default and a command-line option
> was added to enable it at boot time.
>
> $ cat /proc/cmdline
> [...] secretmem.enable=y
>
> https://sourceware.org/bugzilla/show_bug.cgi?id=28418
> https://lwn.net/Articles/865256/
>
> Signed-off-by: Di Chen <dichen@redhat.com>
> ---
> runtime/linux/compat_unistd.h | 4 +
> tapset/linux/aux_syscalls.stp | 3 +
> tapset/linux/sysc_memfd_secret.stp | 102 +++++++++++++++++++++
> testsuite/systemtap.syscall/memfd_secret.c | 22 +++++
> 4 files changed, 131 insertions(+)
> create mode 100644 tapset/linux/sysc_memfd_secret.stp
> create mode 100644 testsuite/systemtap.syscall/memfd_secret.c
>
> diff --git a/runtime/linux/compat_unistd.h b/runtime/linux/compat_unistd.h
> index 5a932cc17..5e73950b9 100644
> --- a/runtime/linux/compat_unistd.h
> +++ b/runtime/linux/compat_unistd.h
> @@ -920,6 +920,9 @@
> #ifndef __NR_ia32_memfd_create
> #define __NR_ia32_memfd_create 356
> #endif
> +#ifndef __NR_ia32_memfd_secret
> +#define __NR_ia32_memfd_secret 447
> +#endif
> #ifndef __NR_ia32_migrate_pages
> #define __NR_ia32_migrate_pages 294
> #endif
> @@ -1999,6 +2002,7 @@
> #define __NR_compat_mbind __NR_mbind
> #define __NR_compat_membarrier __NR_membarrier
> #define __NR_compat_memfd_create __NR_memfd_create
> +#define __NR_compat_memfd_secret __NR_memfd_secret
> #define __NR_compat_migrate_pages __NR_migrate_pages
> #define __NR_compat_mincore __NR_mincore
> #define __NR_compat_mkdir __NR_mkdir
> diff --git a/tapset/linux/aux_syscalls.stp b/tapset/linux/aux_syscalls.stp
> index 3313fb441..4a4bac4df 100644
> --- a/tapset/linux/aux_syscalls.stp
> +++ b/tapset/linux/aux_syscalls.stp
> @@ -1703,6 +1703,9 @@ static const _stp_val_array _stp_mfd_flags_list[] = {
> #endif
> #ifdef MFD_ALLOW_SEALING
> V(MFD_ALLOW_SEALING),
> +#endif
> +#ifdef O_CLOEXEC
> + V(O_CLOEXEC),
> #endif
> {0, NULL}
> };
> diff --git a/tapset/linux/sysc_memfd_secret.stp
> b/tapset/linux/sysc_memfd_secret.stp
> new file mode 100644
> index 000000000..aa9b125ec
> --- /dev/null
> +++ b/tapset/linux/sysc_memfd_secret.stp
> @@ -0,0 +1,102 @@
> +# memfd_secret _____________________________________________________
> +# long sys_memfd_secret (unsigned int flags)
> +
> +/* kernel 5.14+ */
> +@define _SYSCALL_MEMFD_SECRET_NAME
> +%(
> + name = "memfd_secret"
> +%)
> +
> +@define _SYSCALL_MEMFD_SECRET_ARGSTR
> +%(
> + argstr = sprintf("%s", flags_str)
> +%)
> +
> +@define _SYSCALL_MEMFD_SECRET_REGARGS
> +%(
> + flags = uint_arg(1)
> + flags_str = _mfd_flags_str(uint_arg(1))
> +%)
> +
> +@define _SYSCALL_MEMFD_SECRET_REGARGS_STORE
> +%(
> + if (@probewrite(flags))
> + set_uint_arg(1, flags)
> +%)
> +
> +probe syscall.memfd_secret = dw_syscall.memfd_secret !,
> nd_syscall.memfd_secret ? {}
> +probe syscall.memfd_secret.return = dw_syscall.memfd_secret.return !,
> nd_syscall.memfd_secret.return ? {}
> +
> +# dw_memfd_secret _____________________________________________________
> +
> +probe dw_syscall.memfd_secret = kernel.function("sys_memfd_secret").call ?
> +{
> + @_SYSCALL_MEMFD_SECRET_NAME
> + flags = $flags
> + flags_str = _mfd_flags_str($flags)
> + @_SYSCALL_MEMFD_SECRET_ARGSTR
> +}
> +probe dw_syscall.memfd_secret.return =
> kernel.function("sys_memfd_secret").return ?
> +{
> + @_SYSCALL_MEMFD_SECRET_NAME
> + @SYSC_RETVALSTR($return)
> +}
> +
> +# nd_memfd_secret _____________________________________________________
> +
> +probe nd_syscall.memfd_secret = nd1_syscall.memfd_secret!,
> nd2_syscall.memfd_secret!, tp_syscall.memfd_secret
> + { }
> +
> +probe nd1_syscall.memfd_secret = kprobe.function("sys_memfd_secret") ?
> +{
> + @_SYSCALL_MEMFD_SECRET_NAME
> + asmlinkage()
> + @_SYSCALL_MEMFD_SECRET_REGARGS
> + @_SYSCALL_MEMFD_SECRET_ARGSTR
> +}
> +
> +probe nd2_syscall.memfd_secret = kprobe.function(@arch_syscall_prefix
> "sys_memfd_secret") ?
> +{
> + __set_syscall_pt_regs(pointer_arg(1))
> + @_SYSCALL_MEMFD_SECRET_NAME
> + @_SYSCALL_MEMFD_SECRET_REGARGS
> + @_SYSCALL_MEMFD_SECRET_ARGSTR
> +},
> +{
> + %( @_IS_SREG_KERNEL %? @_SYSCALL_MEMFD_SECRET_REGARGS_STORE %)
> +}
> +
> +probe tp_syscall.memfd_secret = kernel.trace("sys_enter")
> +{
> + __set_syscall_pt_regs($regs)
> + @__syscall_compat_gate(@const("__NR_memfd_secret"),
> @const("__NR_compat_memfd_secret"))
> + @_SYSCALL_MEMFD_SECRET_NAME
> + @_SYSCALL_MEMFD_SECRET_REGARGS
> + @_SYSCALL_MEMFD_SECRET_ARGSTR
> +},
> +{
> + %( @_IS_SREG_KERNEL %? @_SYSCALL_MEMFD_SECRET_REGARGS_STORE %)
> +}
> +
> +probe nd_syscall.memfd_secret.return = nd1_syscall.memfd_secret.return!,
> nd2_syscall.memfd_secret.return!, tp_syscall.memfd_secret.return
> + { }
> +
> +probe nd1_syscall.memfd_secret.return =
> kprobe.function("sys_memfd_secret").return ?
> +{
> + @_SYSCALL_MEMFD_SECRET_NAME
> + @SYSC_RETVALSTR(returnval())
> +}
> +
> +probe nd2_syscall.memfd_secret.return =
> kprobe.function(@arch_syscall_prefix "sys_memfd_secret").return ?
> +{
> + @_SYSCALL_MEMFD_SECRET_NAME
> + @SYSC_RETVALSTR(returnval())
> +}
> +
> +probe tp_syscall.memfd_secret.return = kernel.trace("sys_exit")
> +{
> + __set_syscall_pt_regs($regs)
> + @__syscall_compat_gate(@const("__NR_memfd_secret"),
> @const("__NR_compat_memfd_secret"))
> + @_SYSCALL_MEMFD_SECRET_NAME
> + @SYSC_RETVALSTR($ret)
> +}
> diff --git a/testsuite/systemtap.syscall/memfd_secret.c
> b/testsuite/systemtap.syscall/memfd_secret.c
> new file mode 100644
> index 000000000..9a467db86
> --- /dev/null
> +++ b/testsuite/systemtap.syscall/memfd_secret.c
> @@ -0,0 +1,22 @@
> +/* COVERAGE: memfd_secret */
> +
> +/*
> + * Glibc doesn't support memfd_secret yet, so we have to use syscall(2)
> + */
> +#define _GNU_SOURCE
> +#include <sys/syscall.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +
> +#ifdef __NR_memfd_secret
> +
> +int main()
> +{
> + int fd;
> + fd = syscall(__NR_memfd_secret, O_CLOEXEC);
> + //staptest// memfd_secret (O_CLOEXEC) = NNNN
> +
> + close(fd);
> +}
> +
> +#endif
> --
> 2.33.1
>
>
>
[-- Attachment #2: 0001-Add-support-for-new-syscall-memfd_secret.patch --]
[-- Type: text/x-patch, Size: 5879 bytes --]
From 2f0d9ada4f887f28118904b87de9552b47d10d0f Mon Sep 17 00:00:00 2001
From: Di Chen <dichen@redhat.com>
Date: Tue, 15 Feb 2022 17:39:29 +0800
Subject: [PATCH] Add support for new syscall memfd_secret
Linux 5.14 added the memfd_secret syscall, adding tapset support.
memfd_secret() was disabled by default and a command-line option
was added to enable it at boot time.
$ cat /proc/cmdline
[...] secretmem.enable=y
https://sourceware.org/bugzilla/show_bug.cgi?id=28418
https://lwn.net/Articles/865256/
Signed-off-by: Di Chen <dichen@redhat.com>
---
runtime/linux/compat_unistd.h | 4 +
tapset/linux/aux_syscalls.stp | 3 +
tapset/linux/sysc_memfd_secret.stp | 102 +++++++++++++++++++++
testsuite/systemtap.syscall/memfd_secret.c | 22 +++++
4 files changed, 131 insertions(+)
create mode 100644 tapset/linux/sysc_memfd_secret.stp
create mode 100644 testsuite/systemtap.syscall/memfd_secret.c
diff --git a/runtime/linux/compat_unistd.h b/runtime/linux/compat_unistd.h
index 5a932cc17..2bbb0bac5 100644
--- a/runtime/linux/compat_unistd.h
+++ b/runtime/linux/compat_unistd.h
@@ -920,6 +920,9 @@
#ifndef __NR_ia32_memfd_create
#define __NR_ia32_memfd_create 356
#endif
+#ifndef __NR_ia32_memfd_secret
+#define __NR_ia32_memfd_secret 447
+#endif
#ifndef __NR_ia32_migrate_pages
#define __NR_ia32_migrate_pages 294
#endif
@@ -1999,6 +2002,7 @@
#define __NR_compat_mbind __NR_mbind
#define __NR_compat_membarrier __NR_membarrier
#define __NR_compat_memfd_create __NR_memfd_create
+#define __NR_compat_memfd_secret __NR_memfd_secret
#define __NR_compat_migrate_pages __NR_migrate_pages
#define __NR_compat_mincore __NR_mincore
#define __NR_compat_mkdir __NR_mkdir
diff --git a/tapset/linux/aux_syscalls.stp b/tapset/linux/aux_syscalls.stp
index 3313fb441..4a4bac4df 100644
--- a/tapset/linux/aux_syscalls.stp
+++ b/tapset/linux/aux_syscalls.stp
@@ -1703,6 +1703,9 @@ static const _stp_val_array _stp_mfd_flags_list[] = {
#endif
#ifdef MFD_ALLOW_SEALING
V(MFD_ALLOW_SEALING),
+#endif
+#ifdef O_CLOEXEC
+ V(O_CLOEXEC),
#endif
{0, NULL}
};
diff --git a/tapset/linux/sysc_memfd_secret.stp b/tapset/linux/sysc_memfd_secret.stp
new file mode 100644
index 000000000..396077c9d
--- /dev/null
+++ b/tapset/linux/sysc_memfd_secret.stp
@@ -0,0 +1,102 @@
+# memfd_secret _____________________________________________________
+# long sys_memfd_secret (unsigned int flags)
+
+/* kernel 5.14+ */
+@define _SYSCALL_MEMFD_SECRET_NAME
+%(
+ name = "memfd_secret"
+%)
+
+@define _SYSCALL_MEMFD_SECRET_ARGSTR
+%(
+ argstr = sprintf("%s", flags_str)
+%)
+
+@define _SYSCALL_MEMFD_SECRET_REGARGS
+%(
+ flags = uint_arg(1)
+ flags_str = _mfd_flags_str(uint_arg(1))
+%)
+
+@define _SYSCALL_MEMFD_SECRET_REGARGS_STORE
+%(
+ if (@probewrite(flags))
+ set_uint_arg(1, flags)
+%)
+
+probe syscall.memfd_secret = dw_syscall.memfd_secret !, nd_syscall.memfd_secret ? {}
+probe syscall.memfd_secret.return = dw_syscall.memfd_secret.return !, nd_syscall.memfd_secret.return ? {}
+
+# dw_memfd_secret _____________________________________________________
+
+probe dw_syscall.memfd_secret = kernel.function("sys_memfd_secret").call ?
+{
+ @_SYSCALL_MEMFD_SECRET_NAME
+ flags = $flags
+ flags_str = _mfd_flags_str($flags)
+ @_SYSCALL_MEMFD_SECRET_ARGSTR
+}
+probe dw_syscall.memfd_secret.return = kernel.function("sys_memfd_secret").return ?
+{
+ @_SYSCALL_MEMFD_SECRET_NAME
+ @SYSC_RETVALSTR($return)
+}
+
+# nd_memfd_secret _____________________________________________________
+
+probe nd_syscall.memfd_secret = nd1_syscall.memfd_secret!, nd2_syscall.memfd_secret!, tp_syscall.memfd_secret
+ { }
+
+probe nd1_syscall.memfd_secret = kprobe.function("sys_memfd_secret") ?
+{
+ @_SYSCALL_MEMFD_SECRET_NAME
+ asmlinkage()
+ @_SYSCALL_MEMFD_SECRET_REGARGS
+ @_SYSCALL_MEMFD_SECRET_ARGSTR
+}
+
+probe nd2_syscall.memfd_secret = kprobe.function(@arch_syscall_prefix "sys_memfd_secret") ?
+{
+ __set_syscall_pt_regs(pointer_arg(1))
+ @_SYSCALL_MEMFD_SECRET_NAME
+ @_SYSCALL_MEMFD_SECRET_REGARGS
+ @_SYSCALL_MEMFD_SECRET_ARGSTR
+},
+{
+ %( @_IS_SREG_KERNEL %? @_SYSCALL_MEMFD_SECRET_REGARGS_STORE %)
+}
+
+probe tp_syscall.memfd_secret = kernel.trace("sys_enter")
+{
+ __set_syscall_pt_regs($regs)
+ @__syscall_compat_gate(@const("__NR_memfd_secret"), @const("__NR_compat_memfd_secret"))
+ @_SYSCALL_MEMFD_SECRET_NAME
+ @_SYSCALL_MEMFD_SECRET_REGARGS
+ @_SYSCALL_MEMFD_SECRET_ARGSTR
+},
+{
+ %( @_IS_SREG_KERNEL %? @_SYSCALL_MEMFD_SECRET_REGARGS_STORE %)
+}
+
+probe nd_syscall.memfd_secret.return = nd1_syscall.memfd_secret.return!, nd2_syscall.memfd_secret.return!, tp_syscall.memfd_secret.return
+ { }
+
+probe nd1_syscall.memfd_secret.return = kprobe.function("sys_memfd_secret").return ?
+{
+ @_SYSCALL_MEMFD_SECRET_NAME
+ @SYSC_RETVALSTR(returnval())
+}
+
+probe nd2_syscall.memfd_secret.return = kprobe.function(@arch_syscall_prefix "sys_memfd_secret").return ?
+{
+ @_SYSCALL_MEMFD_SECRET_NAME
+ @SYSC_RETVALSTR(returnval())
+}
+
+probe tp_syscall.memfd_secret.return = kernel.trace("sys_exit")
+{
+ __set_syscall_pt_regs($regs)
+ @__syscall_compat_gate(@const("__NR_memfd_secret"), @const("__NR_compat_memfd_secret"))
+ @_SYSCALL_MEMFD_SECRET_NAME
+ @SYSC_RETVALSTR($ret)
+}
diff --git a/testsuite/systemtap.syscall/memfd_secret.c b/testsuite/systemtap.syscall/memfd_secret.c
new file mode 100644
index 000000000..9a467db86
--- /dev/null
+++ b/testsuite/systemtap.syscall/memfd_secret.c
@@ -0,0 +1,22 @@
+/* COVERAGE: memfd_secret */
+
+/*
+ * Glibc doesn't support memfd_secret yet, so we have to use syscall(2)
+ */
+#define _GNU_SOURCE
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#ifdef __NR_memfd_secret
+
+int main()
+{
+ int fd;
+ fd = syscall(__NR_memfd_secret, O_CLOEXEC);
+ //staptest// memfd_secret (O_CLOEXEC) = NNNN
+
+ close(fd);
+}
+
+#endif
--
2.34.1
^ permalink raw reply [flat|nested] 4+ messages in thread