mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 18:13:01 +00:00
Linux: Add wrapper for fcntl(F_{GET,ADD}_SEALS)
Add also a testcase to memcheck/tests/linux, enabled according to a new check for memfd_create() in configure.ac. https://bugs.kde.org/show_bug.cgi?id=361770
This commit is contained in:
parent
7aac53c6d0
commit
dec3050653
1
.gitignore
vendored
1
.gitignore
vendored
@ -1047,6 +1047,7 @@
|
||||
/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
|
||||
|
||||
1
NEWS
1
NEWS
@ -78,6 +78,7 @@ where XXXXXX is the bug number as listed below.
|
||||
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
|
||||
|
||||
@ -4358,6 +4358,7 @@ AC_CHECK_FUNCS([ \
|
||||
klogctl \
|
||||
mallinfo \
|
||||
memchr \
|
||||
memfd_create \
|
||||
memset \
|
||||
mkdir \
|
||||
mremap \
|
||||
@ -4409,6 +4410,8 @@ AM_CONDITIONAL([HAVE_PREADV_PWRITEV],
|
||||
[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 \
|
||||
|
||||
@ -6784,6 +6784,7 @@ PRE(sys_fcntl)
|
||||
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;
|
||||
@ -6798,6 +6799,7 @@ PRE(sys_fcntl)
|
||||
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",
|
||||
@ -6930,6 +6932,7 @@ PRE(sys_fcntl64)
|
||||
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;
|
||||
@ -6941,6 +6944,7 @@ PRE(sys_fcntl64)
|
||||
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",
|
||||
|
||||
@ -1504,6 +1504,9 @@ struct vki_dirent64 {
|
||||
#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;
|
||||
|
||||
@ -13,6 +13,7 @@ EXTRA_DIST = \
|
||||
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 \
|
||||
@ -58,6 +59,10 @@ if HAVE_AT_FDCWD
|
||||
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
|
||||
|
||||
75
memcheck/tests/linux/memfd.c
Normal file
75
memcheck/tests/linux/memfd.c
Normal file
@ -0,0 +1,75 @@
|
||||
#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;
|
||||
}
|
||||
6
memcheck/tests/linux/memfd.stderr.exp
Normal file
6
memcheck/tests/linux/memfd.stderr.exp
Normal file
@ -0,0 +1,6 @@
|
||||
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)
|
||||
|
||||
3
memcheck/tests/linux/memfd.vgtest
Normal file
3
memcheck/tests/linux/memfd.vgtest
Normal file
@ -0,0 +1,3 @@
|
||||
prereq: test -e memfd
|
||||
vgopts: -q --track-origins=yes
|
||||
prog: memfd
|
||||
Loading…
x
Reference in New Issue
Block a user