]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 508777 - amd64-linux: add minimal scalar test
authorMatthias Schwarzott <zzam@gentoo.org>
Sat, 23 Aug 2025 11:37:46 +0000 (13:37 +0200)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Fri, 29 Aug 2025 17:24:39 +0000 (19:24 +0200)
.gitignore
NEWS
memcheck/tests/amd64-linux/Makefile.am
memcheck/tests/amd64-linux/filter_scalar [new file with mode: 0755]
memcheck/tests/amd64-linux/scalar.c [new file with mode: 0644]
memcheck/tests/amd64-linux/scalar.h [new file with mode: 0644]
memcheck/tests/amd64-linux/scalar.stderr.exp [new file with mode: 0644]
memcheck/tests/amd64-linux/scalar.vgtest [new file with mode: 0644]

index 569a8fd5c763adabe92fdcdc93002b38eda2ad6b..80924f997cc117ba91864c7d8928df1effa66b5b 100644 (file)
 /memcheck/tests/amd64-linux/defcfaexpr
 /memcheck/tests/amd64-linux/int3-amd64
 /memcheck/tests/amd64-linux/reallocarray
+/memcheck/tests/amd64-linux/scalar
 /memcheck/tests/amd64-linux/Makefile
 /memcheck/tests/amd64-linux/Makefile.in
 
diff --git a/NEWS b/NEWS
index 0d0ed35ba258edd287c7871705dcde6bf3dc0739..b3bce54003ddf3de30a4190bddf59118df07595b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -87,6 +87,7 @@ are not entered into bugzilla tend to get forgotten about or ignored.
 508093  VALGRIND_CLO_CHANGE does not update vex_control
 508154  PRE(sys_fchownat) not handling VKI_AT_FDCWD
 508638  Self-hosting not working on FreeBSD
+508777  amd64-linux: add minimal scalar test
 508869  x86-linux: simplify scalar test output
 
 To see details of a given bug, visit
index 26e8c8ed549cef20e85eeae4de4166cf86070b5c..a3b5df5a6742771caee72876c65eb17a2c48a943 100644 (file)
@@ -2,7 +2,9 @@
 include $(top_srcdir)/Makefile.tool-tests.am
 
 dist_noinst_SCRIPTS = \
-       filter_stderr filter_defcfaexpr
+       filter_defcfaexpr filter_scalar filter_stderr
+
+noinst_HEADERS = scalar.h
 
 EXTRA_DIST = \
        access_below_sp_1.vgtest \
@@ -11,12 +13,14 @@ EXTRA_DIST = \
        access_below_sp_2.stderr.exp access_below_sp_2.stdout.exp \
        defcfaexpr.vgtest defcfaexpr.stderr.exp \
        int3-amd64.vgtest int3-amd64.stderr.exp int3-amd64.stdout.exp \
+       scalar.stderr.exp scalar.vgtest \
        reallocarray.vgtest reallocarray.stderr.exp
 
 check_PROGRAMS = \
        access_below_sp \
        defcfaexpr \
-       int3-amd64
+       int3-amd64 \
+       scalar
 
 if HAVE_REALLOCARRAY
 check_PROGRAMS += reallocarray
@@ -29,3 +33,4 @@ AM_CCASFLAGS += @FLAG_M64@
 defcfaexpr_SOURCES     = defcfaexpr.S
 defcfaexpr_CFLAGS      = $(AM_CFLAGS) @FLAG_NO_PIE@ 
 reallocarray_CFLAGS    = $(AM_CFLAGS) @FLAG_W_NO_ALLOC_SIZE_LARGER_THAN@
+scalar_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNINITIALIZED@
diff --git a/memcheck/tests/amd64-linux/filter_scalar b/memcheck/tests/amd64-linux/filter_scalar
new file mode 100755 (executable)
index 0000000..ee19ffa
--- /dev/null
@@ -0,0 +1,7 @@
+#! /bin/sh
+
+# remove line numbers as they just cause larger patches
+sed "/: main /s/\(scalar.c\):[0-9]*)/\1)/" |
+
+../filter_stderr "$@"
+
diff --git a/memcheck/tests/amd64-linux/scalar.c b/memcheck/tests/amd64-linux/scalar.c
new file mode 100644 (file)
index 0000000..703d468
--- /dev/null
@@ -0,0 +1,58 @@
+#define _GNU_SOURCE
+
+#include "../../memcheck.h"
+#include "scalar.h"
+#include <unistd.h>
+
+// Here we are trying to trigger every syscall error (scalar errors and
+// memory errors) for every syscall.  We do this by passing a lot of bogus
+// arguments, mostly 0 and 1 (often it's 1 because NULL ptr args often aren't
+// checked for memory errors, or in order to have a non-zero length used
+// with some buffer).  So most of the syscalls don't actually succeed and do
+// anything.
+//
+// Occasionally we have to be careful not to cause Valgrind to seg fault in
+// its pre-syscall wrappers;  it does so because it can't know in general
+// when memory is unaddressable, and so tries to dereference it when doing
+// PRE_MEM_READ/PRE_MEM_WRITE calls.  (Note that Memcheck will
+// always issue an error message immediately before these seg faults occur).
+//
+// The output has numbers like "3s 2m" for each syscall.  "s" is short for
+// "scalar", ie. the argument itself is undefined.  "m" is short for "memory",
+// ie. the argument points to memory which is unaddressable.
+
+int main(void)
+{
+   // uninitialised, but we know px[0] is 0x0
+   long* px  = malloc(sizeof(long));
+   long  x0  = px[0];
+   long  res;
+
+   // All __NR_xxx numbers are taken from amd64
+
+   /* Check the syscall number 0 and 1 two trivial generic syscalls. */
+
+   /* __NR_read 0 */
+   /* Nb: here we are also getting an error from the syscall arg itself. */
+   GO(__NR_read, "1+3s 1m");
+   SY(__NR_read + x0, x0, x0, x0 + 1); FAIL;
+
+   /* __NR_write 1 */
+   GO(__NR_write, "3s 1m");
+   SY(__NR_write, x0, x0, x0 + 1); FAIL;
+
+   // __NR_exit 60
+   GO(__NR_exit, "below");
+   // (see below)
+
+    // no such syscall...
+   GO(9999, "1e");
+   SY(9999); FAIL;
+
+   // __NR_exit 1
+   GO(__NR_exit, "1s 0m");
+   SY(__NR_exit, x0); FAIL;
+
+   assert(0);
+}
+
diff --git a/memcheck/tests/amd64-linux/scalar.h b/memcheck/tests/amd64-linux/scalar.h
new file mode 100644 (file)
index 0000000..52f742e
--- /dev/null
@@ -0,0 +1,65 @@
+#include "../../../include/vki/vki-scnums-x86-linux.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/syscall.h>
+#include <sys/stat.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#ifndef __THROW
+#define __THROW
+#endif
+
+// Since we use vki_unistd.h, we can't include <unistd.h>.  So we have to
+// declare this ourselves.
+extern long int syscall (long int __sysno, ...) __THROW;
+
+// Thorough syscall scalar arg checking.  Also serves as thorough checking
+// for (very) basic syscall use.  Generally not trying to do anything
+// meaningful with the syscalls.
+
+#define GO(__NR_xxx, s) \
+   fprintf(stderr, "-----------------------------------------------------\n"  \
+                   "%3d:%20s %s\n"                                            \
+                   "-----------------------------------------------------\n", \
+                   __NR_xxx, #__NR_xxx, s);
+
+#define SY  res = syscall
+
+#define FAIL  assert(-1 == res);
+#define SUCC  assert(-1 != res);
+#define SUCC_OR_FAIL    /* no test */
+
+#define FAILx(E) \
+   do { \
+      int myerrno = errno; \
+      if (-1 == res) { \
+         if (E == myerrno) { \
+            /* as expected */ \
+         } else { \
+         fprintf(stderr, "Expected error %s (%d), got %d\n", #E, E, myerrno); \
+         exit(1); \
+         } \
+      } else { \
+         fprintf(stderr, "Expected error %s (%d), got success\n", #E, E); \
+         exit(1); \
+      } \
+   } while (0);
+
+#define SUCC_OR_FAILx(E) \
+   do { \
+      int myerrno = errno; \
+      if (-1 == res) { \
+         if (E == myerrno) { \
+            /* as expected */ \
+         } else { \
+         fprintf(stderr, "Expected error %s (%d), got %d\n", #E, E, myerrno); \
+         exit(1); \
+         } \
+      } \
+   } while (0);
diff --git a/memcheck/tests/amd64-linux/scalar.stderr.exp b/memcheck/tests/amd64-linux/scalar.stderr.exp
new file mode 100644 (file)
index 0000000..8f7c307
--- /dev/null
@@ -0,0 +1,62 @@
+-----------------------------------------------------
+  0:           __NR_read 1+3s 1m
+-----------------------------------------------------
+Syscall param (syscallno) contains uninitialised byte(s)
+   ...
+   by 0x........: main (scalar.c)
+
+Syscall param read(fd) contains uninitialised byte(s)
+   ...
+   by 0x........: main (scalar.c)
+
+Syscall param read(buf) contains uninitialised byte(s)
+   ...
+   by 0x........: main (scalar.c)
+
+Syscall param read(count) contains uninitialised byte(s)
+   ...
+   by 0x........: main (scalar.c)
+
+Syscall param read(buf) points to unaddressable byte(s)
+   ...
+   by 0x........: main (scalar.c)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
+-----------------------------------------------------
+  1:          __NR_write 3s 1m
+-----------------------------------------------------
+Syscall param write(fd) contains uninitialised byte(s)
+   ...
+   by 0x........: main (scalar.c)
+
+Syscall param write(buf) contains uninitialised byte(s)
+   ...
+   by 0x........: main (scalar.c)
+
+Syscall param write(count) contains uninitialised byte(s)
+   ...
+   by 0x........: main (scalar.c)
+
+Syscall param write(buf) points to unaddressable byte(s)
+   ...
+   by 0x........: main (scalar.c)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
+-----------------------------------------------------
+ 60:           __NR_exit below
+-----------------------------------------------------
+-----------------------------------------------------
+9999:                9999 1e
+-----------------------------------------------------
+WARNING: unhandled amd64-linux syscall: 9999
+You may be able to write your own handler.
+Read the file README_MISSING_SYSCALL_OR_IOCTL.
+Nevertheless we consider this a bug.  Please report
+it at http://valgrind.org/support/bug_reports.html.
+-----------------------------------------------------
+ 60:           __NR_exit 1s 0m
+-----------------------------------------------------
+Syscall param exit(status) contains uninitialised byte(s)
+   ...
+   by 0x........: main (scalar.c)
+
diff --git a/memcheck/tests/amd64-linux/scalar.vgtest b/memcheck/tests/amd64-linux/scalar.vgtest
new file mode 100644 (file)
index 0000000..81e72b0
--- /dev/null
@@ -0,0 +1,6 @@
+prog: scalar
+# Do not run under root
+prereq: [ `id -u` -ne 0 ]
+vgopts: -q --error-limit=no
+stderr_filter: filter_scalar
+args: < scalar.c