]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix 392118 - unhandled amd64-linux syscall: 332 (statx)
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Sat, 11 Aug 2018 13:56:56 +0000 (15:56 +0200)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Sat, 11 Aug 2018 13:56:56 +0000 (15:56 +0200)
Code patch provided by Mattias AndrĂ©e

Added a regression test to (somewhat) test stat and statx.

Tested on amd64 only.

15 files changed:
.gitignore
coregrind/m_syswrap/priv_syswrap-linux.h
coregrind/m_syswrap/syswrap-amd64-linux.c
coregrind/m_syswrap/syswrap-arm-linux.c
coregrind/m_syswrap/syswrap-arm64-linux.c
coregrind/m_syswrap/syswrap-linux.c
coregrind/m_syswrap/syswrap-mips32-linux.c
coregrind/m_syswrap/syswrap-ppc32-linux.c
coregrind/m_syswrap/syswrap-ppc64-linux.c
coregrind/m_syswrap/syswrap-x86-linux.c
include/vki/vki-linux.h
memcheck/tests/linux/Makefile.am
memcheck/tests/linux/sys-statx.c [new file with mode: 0644]
memcheck/tests/linux/sys-statx.stderr.exp [new file with mode: 0644]
memcheck/tests/linux/sys-statx.vgtest [new file with mode: 0644]

index 72b7c3d46bade8d6a4ea04bffab77d75b4b8a9cf..fc22c9442558507f142a14783f6f8d3ad0287780 100644 (file)
 /memcheck/tests/linux/stack_changes
 /memcheck/tests/linux/stack_switch
 /memcheck/tests/linux/syscalls-2007
+/memcheck/tests/linux/sys-statx
 /memcheck/tests/linux/syslog-syscall
 /memcheck/tests/linux/timerfd-syscall
 /memcheck/tests/linux/proc-auxv
index 65704cd60594d86a4cbbd2da8cea3d40ecc5b537..296ef6599d811526a60ee7b1680b8d8fbe9464fa 100644 (file)
@@ -295,6 +295,9 @@ DECL_TEMPLATE(linux, sys_syncfs);
 
 DECL_TEMPLATE(linux, sys_membarrier);
 
+// Linux-specific (new in Linux 4.11)
+DECL_TEMPLATE(linux, sys_statx);
+
 /* ---------------------------------------------------------------------
    Wrappers for sockets and ipc-ery.  These are split into standalone
    procedures because x86-linux hides them inside multiplexors
index 407af7f76d80e82f278af0d76d494a473aba3e9e..9255e7bad82e8ccd4502c9f14a561f22a8eb00a4 100644 (file)
@@ -846,7 +846,10 @@ static SyscallTableEntry syscall_table[] = {
    LINXY(__NR_memfd_create,      sys_memfd_create),     // 319
 
 //   LIN__(__NR_kexec_file_load,   sys_ni_syscall),       // 320
-//   LIN__(__NR_bpf,               sys_ni_syscall)        // 321
+//   LIN__(__NR_bpf,               sys_ni_syscall),       // 321
+
+
+   LINXY(__NR_statx,             sys_statx),             // 332
 
    LINX_(__NR_membarrier,        sys_membarrier),        // 324
 };
index 4ae4e891d2ecd32a989ac8921fa4a072e2a3c44a..9f1bdab5f095488d769b525a394f07989e25382c 100644 (file)
@@ -1014,7 +1014,9 @@ static SyscallTableEntry syscall_main_table[] = {
    LINX_(__NR_renameat2,         sys_renameat2),        // 382
 
    LINXY(__NR_getrandom,         sys_getrandom),        // 384
-   LINXY(__NR_memfd_create,      sys_memfd_create)      // 385
+   LINXY(__NR_memfd_create,      sys_memfd_create),     // 385
+
+   LINXY(__NR_statx,             sys_statx),            // 397
 };
 
 
index 24a6493c60703ae865000ff04b0e18b1af92a44d..9ef54b40a25e11c5285f878b13698d1891721292 100644 (file)
@@ -821,6 +821,8 @@ static SyscallTableEntry syscall_main_table[] = {
    //   (__NR_pkey_mprotect,     sys_ni_syscall),        // 288
    //   (__NR_pkey_alloc,        sys_ni_syscall),        // 289
    //   (__NR_pkey_free,         sys_ni_syscall),        // 290
+
+   LINXY(__NR_statx,             sys_statx),             // 397
 };
 
 
index 2336c297840fd2875a337a55b2d4f70528d584f5..bd7d44776235e29279ca6b14839a9fe46edc4a48 100644 (file)
@@ -3659,6 +3659,22 @@ PRE(sys_syncfs)
    PRE_REG_READ1(long, "syncfs", unsigned int, fd);
 }
 
+PRE(sys_statx)
+{
+   FUSE_COMPATIBLE_MAY_BLOCK();
+   PRINT("sys_statx ( %ld, %#" FMT_REGWORD "x(%s), %ld, %ld, %#" FMT_REGWORD "x )",
+         ARG1,ARG2,(char*)(Addr)ARG2,ARG3,ARG4,ARG5);
+   PRE_REG_READ5(long, "statx",
+                 int, dirfd, char *, file_name, int, flags,
+                 unsigned int, mask, struct statx *, buf);
+   PRE_MEM_RASCIIZ( "statx(file_name)", ARG2 );
+   PRE_MEM_WRITE( "statx(buf)", ARG5, sizeof(struct vki_statx) );
+}
+POST(sys_statx)
+{
+   POST_MEM_WRITE( ARG5, sizeof(struct vki_statx) );
+}
+
 /* ---------------------------------------------------------------------
    utime wrapper
    ------------------------------------------------------------------ */
index c754987fd3d3ab74a55faab7d4897e76fdfe0cc3..89cf126a7ba5e614634f1299f988727c2a09826c 100644 (file)
@@ -1065,6 +1065,8 @@ static SyscallTableEntry syscall_main_table[] = {
    LINXY(__NR_memfd_create,            sys_memfd_create),            // 354
    //..
    LINX_(__NR_membarrier,              sys_membarrier),              // 358
+   //..
+   LINXY(__NR_statx,                   sys_statx)                    // 366
 };
 
 SyscallTableEntry* ML_(get_linux_syscall_entry) (UInt sysno)
index d1506028c245488c5d781b79523054a7a21071ad..f812f1f6cb3f88ca0c3194855421ef2c306bba45 100644 (file)
@@ -1019,7 +1019,9 @@ static SyscallTableEntry syscall_table[] = {
    LINX_(__NR_process_vm_writev, sys_process_vm_writev),// 352
 
    LINXY(__NR_getrandom,         sys_getrandom),        // 359
-   LINXY(__NR_memfd_create,      sys_memfd_create)      // 360
+   LINXY(__NR_memfd_create,      sys_memfd_create),     // 360
+
+   LINXY(__NR_statx,             sys_statx),            // 383
 };
 
 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
index 46bb3177837e5cf1c8d55ff37eb9c965dcbd2b69..2d699a4ed935e5f2fc4e433843b5a2b0497ca449 100644 (file)
@@ -937,7 +937,9 @@ static SyscallTableEntry syscall_table[] = {
    LINX_(__NR_renameat2,         sys_renameat2),        // 357
 
    LINXY(__NR_getrandom,         sys_getrandom),        // 359
-   LINXY(__NR_memfd_create,      sys_memfd_create)      // 360
+   LINXY(__NR_memfd_create,      sys_memfd_create),     // 360
+
+   LINXY(__NR_statx,             sys_statx),            // 383
 };
 
 SyscallTableEntry* ML_(get_linux_syscall_entry) ( UInt sysno )
index 11bb13d89468003dc73e2abe023ffd063c58dda1..ea4f354195fb4c96aca31a2a5812968d8abebccd 100644 (file)
@@ -1606,6 +1606,8 @@ static SyscallTableEntry syscall_table[] = {
    LINXY(__NR_recvmsg,           sys_recvmsg),          // 372
    LINX_(__NR_shutdown,          sys_shutdown),         // 373
 
+   LINXY(__NR_statx,             sys_statx),            // 383
+
    /* Explicitly not supported on i386 yet. */
    GENX_(__NR_arch_prctl,        sys_ni_syscall)        // 384
 };
index 707208040c7248e0a2ffd630ff62e70bfb03daba..1beeebba11ce3b0822ca69caba522549bd5116c2 100644 (file)
@@ -1381,6 +1381,44 @@ struct vki_robust_list_head {
 #define VKI_S_IWOTH 00002
 #define VKI_S_IXOTH 00001
 
+struct vki_statx_timestamp {
+        __vki_s64   tv_sec;
+        __vki_u32   tv_nsec;
+        __vki_s32   __reserved;
+};
+
+struct vki_statx {
+        /* 0x00 */
+        __vki_u32   stx_mask;       /* What results were written [uncond] */
+        __vki_u32   stx_blksize;    /* Preferred general I/O size [uncond] */
+        __vki_u64   stx_attributes; /* Flags conveying information about the file [uncond] */
+        /* 0x10 */
+        __vki_u32   stx_nlink;      /* Number of hard links */
+        __vki_u32   stx_uid;        /* User ID of owner */
+        __vki_u32   stx_gid;        /* Group ID of owner */
+        __vki_u16   stx_mode;       /* File mode */
+        __vki_u16   __spare0[1];
+        /* 0x20 */
+        __vki_u64   stx_ino;        /* Inode number */
+        __vki_u64   stx_size;       /* File size */
+        __vki_u64   stx_blocks;     /* Number of 512-byte blocks allocated */
+        __vki_u64   stx_attributes_mask; /* Mask to show what's supported in stx_attributes */
+        /* 0x40 */
+        struct vki_statx_timestamp  stx_atime;      /* Last access time */
+        struct vki_statx_timestamp  stx_btime;      /* File creation time */
+        struct vki_statx_timestamp  stx_ctime;      /* Last attribute change time */
+        struct vki_statx_timestamp  stx_mtime;      /* Last data modification time */
+        /* 0x80 */
+        __vki_u32   stx_rdev_major; /* Device ID of special file [if bdev/cdev] */
+        __vki_u32   stx_rdev_minor;
+        __vki_u32   stx_dev_major;  /* ID of device containing file [uncond] */
+        __vki_u32   stx_dev_minor;
+        /* 0x90 */
+        __vki_u64   __spare2[14];   /* Spare space for future expansion */
+        /* 0x100 */
+};
+
+
 //----------------------------------------------------------------------
 // From linux-2.6.8.1/include/linux/dirent.h
 //----------------------------------------------------------------------
index 5f49a3fe2213c1c2292a48e804753f4394344613..d7515d9c7593f2698c9379f84e16cb9c43d3e983 100644 (file)
@@ -21,6 +21,7 @@ EXTRA_DIST = \
        syscalls-2007.vgtest syscalls-2007.stderr.exp \
        syslog-syscall.vgtest syslog-syscall.stderr.exp \
        sys-openat.vgtest sys-openat.stderr.exp sys-openat.stdout.exp \
+       sys-statx.vgtest sys-statx.stderr.exp \
        timerfd-syscall.vgtest timerfd-syscall.stderr.exp \
        with-space.stderr.exp with-space.stdout.exp with-space.vgtest \
        proc-auxv.vgtest proc-auxv.stderr.exp getregset.vgtest \
@@ -40,6 +41,7 @@ check_PROGRAMS = \
        stack_switch \
        syscalls-2007 \
        syslog-syscall \
+       sys-statx \
        timerfd-syscall \
        proc-auxv
 
diff --git a/memcheck/tests/linux/sys-statx.c b/memcheck/tests/linux/sys-statx.c
new file mode 100644 (file)
index 0000000..7b6ee34
--- /dev/null
@@ -0,0 +1,56 @@
+/* Test (somewhat) stats and stat.  */
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <linux/stat.h>
+#include <errno.h>
+
+int check_stat2;
+
+#define field(fieldname,s) s->st_##fieldname
+#if defined(__NR_statx)
+#define checkfield(fieldname) \
+   assert(!check_stat2 || stat1.st_##fieldname == stat2.stx_##fieldname)
+#else
+#define checkfield(fieldname) \
+   assert(!check_stat2 || stat1.st_##fieldname == stat2.st_##fieldname)
+#endif
+
+int main (void)
+{
+   struct stat stat1;
+
+   memset(&stat1, 0x55, sizeof(stat1));
+
+   assert (stat ("/tmp", &stat1) == 0);
+#if defined(__NR_statx)
+   struct statx stat2;
+   memset(&stat2, 0x22, sizeof(stat2));
+   if (syscall (__NR_statx, 0, "/tmp", 0, STATX_ALL, &stat2) == 0)
+      check_stat2 = 1;
+   else {
+      if (errno == ENOSYS)
+         check_stat2 = 0; // Defined but not provided by kernel.
+      else
+         check_stat2 = 1; // Probably better fail ...
+   }
+#else
+   struct stat stat2;
+   check_stat2 = 1;
+   memset(&stat2, 0x22, sizeof(stat2));
+   assert (stat ("/tmp", &stat2) == 0);
+#endif
+
+   checkfield(nlink);
+   checkfield(uid);
+   checkfield(gid);
+   checkfield(mode);
+   checkfield(ino);
+
+   return 0;
+}
diff --git a/memcheck/tests/linux/sys-statx.stderr.exp b/memcheck/tests/linux/sys-statx.stderr.exp
new file mode 100644 (file)
index 0000000..c22dd7f
--- /dev/null
@@ -0,0 +1,10 @@
+
+
+HEAP SUMMARY:
+    in use at exit: 0 bytes in 0 blocks
+  total heap usage: 0 allocs, 0 frees, 0 bytes allocated
+
+For a detailed leak analysis, rerun with: --leak-check=full
+
+For counts of detected and suppressed errors, rerun with: -v
+ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
diff --git a/memcheck/tests/linux/sys-statx.vgtest b/memcheck/tests/linux/sys-statx.vgtest
new file mode 100644 (file)
index 0000000..e4864ac
--- /dev/null
@@ -0,0 +1 @@
+prog: sys-statx