/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
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
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 \
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
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@
--- /dev/null
+#! /bin/sh
+
+# remove line numbers as they just cause larger patches
+sed "/: main /s/\(scalar.c\):[0-9]*)/\1)/" |
+
+../filter_stderr "$@"
+
--- /dev/null
+#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);
+}
+
--- /dev/null
+#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);
--- /dev/null
+-----------------------------------------------------
+ 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)
+
--- /dev/null
+prog: scalar
+# Do not run under root
+prereq: [ `id -u` -ne 0 ]
+vgopts: -q --error-limit=no
+stderr_filter: filter_scalar
+args: < scalar.c