]> sourceware.org Git - systemtap.git/commitdiff
Add support for new syscall memfd_secret
authorDi Chen <dichen@redhat.com>
Tue, 15 Feb 2022 09:39:29 +0000 (17:39 +0800)
committerAaron Merey <amerey@redhat.com>
Fri, 4 Mar 2022 00:40:13 +0000 (19:40 -0500)
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
tapset/linux/aux_syscalls.stp
tapset/linux/sysc_memfd_secret.stp [new file with mode: 0644]
testsuite/systemtap.syscall/memfd_secret.c [new file with mode: 0644]

index 5a932cc17076ca22e4da5e3d835b905d70990c90..2bbb0bac54869401bca994e015b0e919a3106da5 100644 (file)
 #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
 #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
index 3313fb441fafc47466bd5b667d486053cf07e1ff..4a4bac4dfa992db4b7e93efa4dac8ebccd7c6288 100644 (file)
@@ -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 (file)
index 0000000..396077c
--- /dev/null
@@ -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 (file)
index 0000000..9a467db
--- /dev/null
@@ -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
This page took 0.040848 seconds and 5 git commands to generate.