The syscall number has to be put in register v0 before call into the kernel.
This was omitted when system call is __NR_syscall (and when the syscall
argument is the system call number of interest).
Patch by Nikola Milutinovic.
GCC 7 instroduced -Wimplicit-fallthrough
https://developers.redhat.com/blog/2017/03/10/wimplicit-fallthrough-in-gcc-7/
It caught a couple of bugs, but it does need a bit of extra comments to
explain when a switch case statement fall-through is deliberate. Luckily
with -Wimplicit-fallthrough=2 various existing comments already do that.
I have fixed the bugs, but adding explicit break statements where
necessary and added comments where the fall-through was correct.
https://bugs.kde.org/show_bug.cgi?id=405430
PTRACE_GET_THREAD_AREA is not handled by amd64 linux syswrap, which leads
to false positive errors in 64 bits program ptrace-ing 32 bits processes.
For example, the below error was wrongly reported on GDB:
==25377== Conditional jump or move depends on uninitialised value(s)
==25377== at 0x8A1D7EC: td_thr_get_info (td_thr_get_info.c:35)
==25377== by 0x526819: thread_from_lwp(thread_info*, ptid_t) (linux-thread-db.c:417)
==25377== by 0x5281D4: thread_db_notice_clone(ptid_t, ptid_t) (linux-thread-db.c:442)
==25377== by 0x51773B: linux_handle_extended_wait(lwp_info*, int) (linux-nat.c:2027)
....
==25377== Uninitialised value was created by a stack allocation
==25377== at 0x69A360: x86_linux_get_thread_area(int, void*, unsigned int*) (x86-linux-nat.c:278)
Fix this by implementing PTRACE_GET|SET_THREAD_AREA on amd64.
The sys_ptrace post didn't mark the thread as being in traceme mode.
This occassionally would make the memcheck/tests/linux/getregset.vgtest
testcase fail. With this patch it reliably passes.
When code uses utimensat with UTIME_NOW or UTIME_OMIT valgrind memcheck
would generate a warning. But as the utimensat manpage says:
If the tv_nsec field of one of the timespec structures has the special
value UTIME_NOW, then the corresponding file timestamp is set to the
current time. If the tv_nsec field of one of the timespec structures
has the special value UTIME_OMIT, then the corresponding file timestamp
is left unchanged. In both of these cases, the value of the corre‐
sponding tv_sec field is ignored.
So ignore the timespec tv_sec when tv_nsec is set to UTIME_NOW or
UTIME_OMIT.
Support for the bpf system call was added in a previous commit, but
did not include tracking for file descriptors handled by the call.
Add checks and tracking for file descriptors. Check in PRE() wrapper
that all file descriptors (pointing to object such as eBPF programs or
maps, cgroups, or raw tracepoints) used by the system call are valid,
then add tracking in POST() wrapper for newly produced file descriptors.
As the file descriptors are not always processed in the same way by the
bpf call, add to the header file some additional definitions from bpf.h
that are necessary to sort out under what conditions descriptors should
be checked in the PRE() helper.
Fixes: 388786 - Support bpf syscall in amd64 Linux
Add support for bpf() Linux-specific system call on amd64 platform. The
bpf() syscall is used to handle eBPF objects (programs and maps), and
can be used for a number of operations. It takes three arguments:
- "cmd" is an integer encoding a subcommand to run. Available subcommand
include loading a new program, creating a map or updating its entries,
retrieving information about an eBPF object, and may others.
- "attr" is a pointer to an object of type union bpf_attr. This object
converts to a struct related to selected subcommand, and embeds the
various parameters used with this subcommand. Some of those parameters
are read by the kernel (example for an eBPF map lookup: the key of the
entry to lookup), others are written into (the value retrieved from
the map lookup).
- "attr_size" is the size of the object pointed by "attr".
Since the action performed by the kernel, and the way "attr" attributes
are processed depends on the subcommand in use, the PRE() and POST()
wrappers need to make the distinction as well. For each subcommand, mark
the attributes that are read or written.
For some map operations, the only way to infer the size of the memory
areas used for read or write operations seems to involve reading
from /proc/<pid>/fdinfo/<fd> in order to retrieve the size of keys
and values for this map.
The definitions of union bpf_attr and of other eBPF-related elements
required for adequately performing the checks were added to the Linux
header file.
Processing related to file descriptors is added in a follow-up patch.
The sys_prctl wrapper with PR_SET_NAME option reads an ASCII string passed
as its second argument. This string is supposed to be shorter than a given
limit. As the actual length of the string is unknown, the PRE() wrapper
performs a number of checks on it, including, in worst case, trying to
dereference it byte by byte.
To avoid re-implementing all this logic for other wrappers that could
need it, get the string processing out of the wrapper and move it to a
static function. Note that passing tid as an argument to the function is
required for macros PRE_MEM_RASCIIZ and PRE_MEM_READ to work properly.
arch_prctl used to be amd64 only. But since linux 4.12 it is also
implemented for i386. And since glibc 2.28 ld.so will use it to see
if the cpu/kernel provides CET support.
To prevent seeing:
WARNING: unhandled x86-linux syscall: 384
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.
on every program run under valgrind just make it explicitly
not implemented (ENOSYS). This is fine for the glibc usage.
It just indicates there is no CET support.
Currently arch_prctl calls VG_(core_panic) when it sees an unknown
arch_prctl option which kills the process. glibc uses arch_prctl with
an (as yet) unknown option to see if the kernel supports CET. This
breaks any application running under valgrind on x86_64 with:
valgrind: the 'impossible' happened:
Unsupported arch_prctl option
Thread 1: status = VgTs_Runnable (lwpid 19934)
==19934== at 0x121A15: get_cet_status (cpu-features.c:28)
==19934== by 0x121A15: init_cpu_features (cpu-features.c:474)
==19934== by 0x121A15: dl_platform_init (dl-machine.h:228)
==19934== by 0x121A15: _dl_sysdep_start (dl-sysdep.c:231)
==19934== by 0x10A1D7: _dl_start_final (rtld.c:413)
==19934== by 0x10A1D7: _dl_start (rtld.c:520)
We already handle all known options. It would be better to do as the
kernel does and just return failure with EINVAL instead.
* In case a thread is executing a syscall, give the syscall no being
executed.
* Show the address range of the valgrind stack, similarly to the client
stack
Adding MIPS N32 ABI support.
BZ issue - #345763.
Contributed and maintained by mulitple people over the years:
Crestez Dan Leonard, Maran Pakkirisamy, Dimitrije Nikolic,
Aleksandar Rikalo, Tamara Vlahovic.
Follow up to "Introduce RegWord type" change.
Part of the changes required for BZ issue - #345763.
Contributed by:
Tamara Vlahovic and Dimitrije Nikolic.
On majority of architectures size of long matches register width.
On mips n32 size of long is 32 bits and register width is 64 bits.
Valgrind is written with assumption that long size matches register
width. This is the reason why both UWord for Valgrind and HWord for VEX
match size of long. Long size differs from register size on mips n32 ABI.
Introducing RegWord type that will match size of registers.
Part of the changes required for BZ issue - #345763.
Contributed by:
Tamara Vlahovic and Dimitrije Nikolic.
The modified test none/tests/sem crashes with a SEGV when valgrind is compiled
with lto on various amd64 platforms (debian/gcc 6.3, RHEL7/gcc 6.4,
Ubuntu/gcc 7.2)
The problem is that the vki_semid_ds buf is not what is expected by the kernel:
the kernel expects a bigger structure vki_semid64_ds (at least on
these platforms).
Getting the sem_nsems seems to work by chance, as sem_nsems is at
the same offset in both vki_semid_ds and vki_semid64_ds.
However, e.g. the ctime was not set properly after syscall return,
and 2 words after sem_nsems were set to 0 by the kernel, causing
the SEGV, as a spilled register became 0.
Fix consists in using the 64 bit version for __NR_semctl.
Tested on debian/amd64 and s390x.
Shingled magnetic recording drives support a command set called ZBC
(Zoned Block Commands). Two new ioctls have been added to the Linux
kernel to support such drives, namely VKI_BLKREPORTZONE and
VKI_BLKRESETZONE. Add support to Valgrind for these ioctls.
Changes in PRE(sys_prctl), necessary to support new floating-point modes
in MIPS R6.
Part of MIPS32/64 Revision 6 changes.
Contributed by:
Tamara Vlahovic, Aleksandar Rikalo and Aleksandra Karadzic.
Related BZ issue - #387410.
According to the epoll_pwait(2) man page:
The sigmask argument may be specified as NULL, in which case
epoll_pwait() is equivalent to epoll_wait().
But doing that under valgrind gives:
==13887== Syscall param epoll_pwait(sigmask) points to unaddressable byte(s)
==13887== at 0x4F2B940: epoll_pwait (epoll_pwait.c:43)
==13887== by 0x400ADE: main (syscalls-2007.c:89)
==13887== Address 0x0 is not stack'd, malloc'd or (recently) free'd
This is because the sys_epoll_pwait wrapper has:
if (ARG4)
PRE_MEM_READ( "epoll_pwait(sigmask)", ARG5, sizeof(vki_sigset_t) );
Which looks like a typo (ARG4 is timeout and ARG5 is sigmask).
This shows up with newer glibc which translates an epoll_wait call into
an epoll_pwait call with NULL sigmask.
Fix typo and add a testcase.
https://bugs.kde.org/show_bug.cgi?id=381289
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@16451
be printed only once, rather than every time it happens. Also make it
not be printed in silent mode (-q).
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@16407