/memcheck/tests/linux/lsframe2
/memcheck/tests/linux/Makefile
/memcheck/tests/linux/Makefile.in
+/memcheck/tests/linux/memfd
/memcheck/tests/linux/rfcomm
/memcheck/tests/linux/sigqueue
/memcheck/tests/linux/stack_changes
140939 --track-fds reports leakage of stdout/in/err and doesn't respect -q
217695 malloc/calloc/realloc/memalign failure doesn't set errno to ENOMEM
345077 linux syscall execveat support (linux 3.19)
+361770 Missing F_ADD_SEALS
369029 handle linux syscalls sched_getattr and sched_setattr
384729 __libc_freeres inhibits cross-platform valgrind
391853 Makefile.all.am:L247 and @SOLARIS_UNDEF_LARGESOURCE@ being empty
klogctl \
mallinfo \
memchr \
+ memfd_create \
memset \
mkdir \
mremap \
[test x$ac_cv_func_preadv = xyes && test x$ac_cv_func_pwritev = xyes])
AM_CONDITIONAL([HAVE_PREADV2_PWRITEV2],
[test x$ac_cv_func_preadv2 = xyes && test x$ac_cv_func_pwritev2 = xyes])
+AM_CONDITIONAL([HAVE_MEMFD_CREATE],
+ [test x$ac_cv_func_memfd_create = xyes])
if test x$VGCONF_PLATFORM_PRI_CAPS = xMIPS32_LINUX \
-o x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX \
case VKI_F_GETSIG:
case VKI_F_GETLEASE:
case VKI_F_GETPIPE_SZ:
+ case VKI_F_GET_SEALS:
PRINT("sys_fcntl ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
break;
case VKI_F_SETOWN:
case VKI_F_SETSIG:
case VKI_F_SETPIPE_SZ:
+ case VKI_F_ADD_SEALS:
PRINT("sys_fcntl[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
"u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
PRE_REG_READ3(long, "fcntl",
case VKI_F_GETSIG:
case VKI_F_SETSIG:
case VKI_F_GETLEASE:
+ case VKI_F_GET_SEALS:
PRINT("sys_fcntl64 ( %" FMT_REGWORD "u, %" FMT_REGWORD "u )", ARG1, ARG2);
PRE_REG_READ2(long, "fcntl64", unsigned int, fd, unsigned int, cmd);
break;
case VKI_F_SETFL:
case VKI_F_SETLEASE:
case VKI_F_NOTIFY:
+ case VKI_F_ADD_SEALS:
PRINT("sys_fcntl64[ARG3=='arg'] ( %" FMT_REGWORD "u, %" FMT_REGWORD
"u, %" FMT_REGWORD "u )", ARG1, ARG2, ARG3);
PRE_REG_READ3(long, "fcntl64",
#define VKI_F_SETPIPE_SZ (VKI_F_LINUX_SPECIFIC_BASE + 7)
#define VKI_F_GETPIPE_SZ (VKI_F_LINUX_SPECIFIC_BASE + 8)
+#define VKI_F_ADD_SEALS (VKI_F_LINUX_SPECIFIC_BASE + 9)
+#define VKI_F_GET_SEALS (VKI_F_LINUX_SPECIFIC_BASE + 10)
+
struct vki_flock {
short l_type;
short l_whence;
ioctl-tiocsig.vgtest ioctl-tiocsig.stderr.exp \
lsframe1.vgtest lsframe1.stdout.exp lsframe1.stderr.exp \
lsframe2.vgtest lsframe2.stdout.exp lsframe2.stderr.exp \
+ memfd.vgtest memfd.stderr.exp \
rfcomm.vgtest rfcomm.stderr.exp \
sigqueue.vgtest sigqueue.stderr.exp \
stack_changes.stderr.exp stack_changes.stdout.exp \
check_PROGRAMS += sys-openat
endif
+if HAVE_MEMFD_CREATE
+check_PROGRAMS += memfd
+endif
+
if HAVE_COPY_FILE_RANGE
check_PROGRAMS += sys-copy_file_range
endif
--- /dev/null
+#define _GNU_SOURCE
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include "../../memcheck.h"
+
+static void
+assert_expected (int fd, int expected_seals)
+{
+ int current_seals = fcntl (fd, F_GET_SEALS);
+ assert (current_seals == expected_seals);
+}
+
+static void
+add_seal (int fd, int *expected_seals, int new_seal)
+{
+ int r = fcntl (fd, F_ADD_SEALS, new_seal);
+ assert (r == 0);
+
+ *expected_seals |= new_seal;
+
+ // Make sure we get the result we expected.
+ assert_expected (fd, *expected_seals);
+}
+
+static void
+add_seal_expect_fail (int fd, int new_seal, int expected_errno)
+{
+ int r = fcntl (fd, F_ADD_SEALS, new_seal);
+ assert (r == -1 && errno == expected_errno);
+}
+
+int
+main (void)
+{
+ int expected_seals = 0;
+ int fd;
+
+ // Try with an fd that doesn't support sealing.
+ fd = memfd_create ("xyz", 0);
+ if (fd < 0)
+ {
+ // Not supported, nothing to test...
+ return 1;
+ }
+
+ assert_expected (fd, F_SEAL_SEAL);
+ add_seal_expect_fail (fd, F_SEAL_WRITE, EPERM);
+ assert_expected (fd, F_SEAL_SEAL); // ...should still be unset after failed attempt
+ close (fd);
+
+ // Now, try the successful case.
+ fd = memfd_create ("xyz", MFD_ALLOW_SEALING);
+ add_seal (fd, &expected_seals, F_SEAL_SHRINK);
+ add_seal (fd, &expected_seals, F_SEAL_GROW);
+
+ // Now prevent more sealing.
+ add_seal (fd, &expected_seals, F_SEAL_SEAL);
+
+ // And make sure that it indeed fails.
+ add_seal_expect_fail (fd, F_SEAL_WRITE, EPERM);
+ assert_expected (fd, expected_seals);
+ close (fd);
+
+ // Test the only memory failure possible: passing an undefined argument to F_ADD_SEALS
+ int undefined_seal = 0;
+ VALGRIND_MAKE_MEM_UNDEFINED(&undefined_seal, sizeof undefined_seal);
+ fcntl (-1, F_ADD_SEALS, undefined_seal);
+
+ return 0;
+}
--- /dev/null
+Syscall param fcntl(arg) contains uninitialised byte(s)
+ ...
+ by 0x........: main (memfd.c:72)
+ Uninitialised value was created by a client request
+ at 0x........: main (memfd.c:71)
+
--- /dev/null
+prereq: test -e memfd
+vgopts: -q --track-origins=yes
+prog: memfd