diff --git a/coregrind/vg_syscalls.c b/coregrind/vg_syscalls.c index dbfac09e3..ead332e0c 100644 --- a/coregrind/vg_syscalls.c +++ b/coregrind/vg_syscalls.c @@ -5911,32 +5911,69 @@ POSTx(sys_rt_sigaction) POST_MEM_WRITE( arg3, sizeof(struct vki_sigaction)); } -PRE(sigprocmask) +PREx(sys_sigprocmask, SIG_SIM) { - /* int sigprocmask(int how, k_sigset_t *set, - k_sigset_t *oldset); */ - PRINT("sigprocmask ( %d, %p, %p )",arg1,arg2,arg3); + PRINT("sys_sigprocmask ( %d, %p, %p )",arg1,arg2,arg3); + PRE_REG_READ3(long, "sigprocmask", + int, how, vki_old_sigset_t *, set, vki_old_sigset_t *, oldset); if (arg2 != (UWord)NULL) - PRE_MEM_READ( "sigprocmask(set)", arg2, sizeof(vki_sigset_t)); + PRE_MEM_READ( "sigprocmask(set)", arg2, sizeof(vki_old_sigset_t)); if (arg3 != (UWord)NULL) - PRE_MEM_WRITE( "sigprocmask(oldset)", arg3, sizeof(vki_sigset_t)); + PRE_MEM_WRITE( "sigprocmask(oldset)", arg3, sizeof(vki_old_sigset_t)); - if (SIGNAL_SIMULATION) + if (SIGNAL_SIMULATION) { + // Nb: We must convert the smaller vki_old_sigset_t params into bigger + // vki_sigset_t params. + vki_old_sigset_t* set = (vki_old_sigset_t*)arg2; + vki_old_sigset_t* oldset = (vki_old_sigset_t*)arg3; + vki_sigset_t bigger_set; + vki_sigset_t bigger_oldset; + + VG_(memset)(&bigger_set, 0, sizeof(vki_sigset_t)); + bigger_set.sig[0] = *(vki_old_sigset_t*)set; + + VG_(do_sys_sigprocmask) ( tid, + arg1 /*how*/, + &bigger_set, + &bigger_oldset ); + + *oldset = bigger_oldset.sig[0]; + } +} + +POSTx(sys_sigprocmask) +{ + if (res == 0 && arg3 != (UWord)NULL) + POST_MEM_WRITE( arg3, sizeof(vki_old_sigset_t)); +} + +PREx(sys_rt_sigprocmask, SIG_SIM) +{ + PRINT("sys_rt_sigprocmask ( %d, %p, %p, %llu )",arg1,arg2,arg3,(ULong)arg4); + PRE_REG_READ4(long, "rt_sigprocmask", + int, how, vki_sigset_t *, set, vki_sigset_t *, oldset, + vki_size_t, sigsetsize); + if (arg2 != (UWord)NULL) + PRE_MEM_READ( "rt_sigprocmask(set)", arg2, sizeof(vki_sigset_t)); + if (arg3 != (UWord)NULL) + PRE_MEM_WRITE( "rt_sigprocmask(oldset)", arg3, sizeof(vki_sigset_t)); + + // Like the kernel, we fail if the sigsetsize is not exactly what we expect. + if (sizeof(vki_sigset_t) != arg4) + set_result( -VKI_EMFILE ); + else if (SIGNAL_SIMULATION) VG_(do_sys_sigprocmask) ( tid, arg1 /*how*/, (vki_sigset_t*) arg2, (vki_sigset_t*) arg3 ); } -POST(sigprocmask) +POSTx(sys_rt_sigprocmask) { if (res == 0 && arg3 != (UWord)NULL) POST_MEM_WRITE( arg3, sizeof(vki_sigset_t)); } -PREALIAS(rt_sigprocmask, sigprocmask); -POSTALIAS(rt_sigprocmask, sigprocmask); - PREx(sys_sigpending, NBRunInLWP) { PRINT( "sys_sigpending ( %p )", arg1 ); @@ -6503,7 +6540,7 @@ static const struct sys_info sys_info[] = { SYSXY(__NR_adjtimex, sys_adjtimex), // 124 * L SYSXY(__NR_mprotect, sys_mprotect), // 125 * P - SYSBA(__NR_sigprocmask, sys_sigprocmask, SIG_SIM), // 126 * + SYSXY(__NR_sigprocmask, sys_sigprocmask), // 126 * P // Nb: create_module() was removed 2.4-->2.6 SYSX_(__NR_create_module, sys_ni_syscall), // 127 * P -- unimplemented SYSX_(__NR_init_module, sys_init_module), // 128 * L? @@ -6564,7 +6601,7 @@ static const struct sys_info sys_info[] = { // (__NR_rt_sigreturn, sys_rt_sigreturn), // 173 (x86) () SYSXY(__NR_rt_sigaction, sys_rt_sigaction), // 174 (x86) () - SYSBA(__NR_rt_sigprocmask, sys_rt_sigprocmask, SIG_SIM), // 175 * + SYSXY(__NR_rt_sigprocmask, sys_rt_sigprocmask), // 175 * ? SYSBA(__NR_rt_sigpending, sys_rt_sigpending, NBRunInLWP), // 176 * SYSBA(__NR_rt_sigtimedwait, sys_rt_sigtimedwait, MayBlock), // 177 * SYSBA(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo, 0), // 178 * diff --git a/memcheck/tests/.cvsignore b/memcheck/tests/.cvsignore index 04d1dab9f..b1dfc525c 100644 --- a/memcheck/tests/.cvsignore +++ b/memcheck/tests/.cvsignore @@ -55,6 +55,7 @@ scalar_supp scalar_vfork sigaltstack signal2 +sigprocmask str_tester supp1 supp2 diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am index 2c6f9c274..9328cc23f 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -59,8 +59,8 @@ EXTRA_DIST = $(noinst_SCRIPTS) \ scalar_supp.stderr.exp scalar_supp.vgtest scalar_supp.supp \ scalar_vfork.stderr.exp scalar_vfork.vgtest \ sigaltstack.stderr.exp sigaltstack.vgtest \ - signal2.stderr.exp \ - signal2.stdout.exp signal2.vgtest \ + signal2.stderr.exp signal2.stdout.exp signal2.vgtest \ + sigprocmask.stderr.exp sigprocmask.vgtest \ str_tester.stderr.exp str_tester.vgtest \ supp1.stderr.exp supp1.vgtest \ supp2.stderr.exp supp2.vgtest \ @@ -88,7 +88,7 @@ check_PROGRAMS = \ null_socket overlap \ realloc1 realloc2 realloc3 \ scalar scalar_exit_group scalar_fork scalar_supp scalar_vfork \ - sigaltstack signal2 \ + sigaltstack signal2 sigprocmask \ str_tester supp1 supp2 suppfree \ trivialleak weirdioctl \ mismatches new_override metadata threadederrno \ @@ -146,6 +146,7 @@ scalar_fork_SOURCES = scalar_fork.c scalar_supp_SOURCES = scalar_supp.c scalar_vfork_SOURCES = scalar_vfork.c signal2_SOURCES = signal2.c +sigprocmask_SOURCES = sigprocmask.c supp1_SOURCES = supp.c supp2_SOURCES = supp.c suppfree_SOURCES = suppfree.c diff --git a/memcheck/tests/scalar.c b/memcheck/tests/scalar.c index 0555207f4..d2f909895 100644 --- a/memcheck/tests/scalar.c +++ b/memcheck/tests/scalar.c @@ -1,3 +1,4 @@ +#include "../memcheck.h" #include "scalar.h" int main(void) @@ -541,8 +542,10 @@ int main(void) SY(__NR_mprotect, x0, x0, x0); // __NR_sigprocmask 126 - //GO(__NR_sigprocmask, ".s .m"); - //SY(__NR_sigprocmask); + { + GO(__NR_sigprocmask, "3s 2m"); + SY(__NR_sigprocmask, x0, x0+&px[1], x0+&px[1]); + } // __NR_create_module 127 GO(__NR_create_module, "ni"); @@ -737,8 +740,8 @@ int main(void) SY(__NR_rt_sigaction, x0, x0+1, x0+1, x0); // __NR_rt_sigprocmask 175 - //GO(__NR_rt_sigprocmask, ".s .m"); - //SY(__NR_rt_sigprocmask); + GO(__NR_rt_sigprocmask, "4s 2m"); + SY(__NR_rt_sigprocmask, x0, x0+1, x0+1, x0); // __NR_rt_sigpending 176 //GO(__NR_rt_sigpending, ".s .m"); diff --git a/memcheck/tests/scalar.stderr.exp b/memcheck/tests/scalar.stderr.exp index d3415d24e..0230c8606 100644 --- a/memcheck/tests/scalar.stderr.exp +++ b/memcheck/tests/scalar.stderr.exp @@ -1601,6 +1601,40 @@ Syscall param mprotect(prot) contains uninitialised byte(s) by 0x........: __libc_start_main (...libc...) by 0x........: ... ----------------------------------------------------- +126: __NR_sigprocmask 3s 2m +----------------------------------------------------- + +Syscall param sigprocmask(how) contains uninitialised byte(s) + at 0x........: syscall (in /...libc...) + by 0x........: __libc_start_main (...libc...) + by 0x........: ... + +Syscall param sigprocmask(set) contains uninitialised byte(s) + at 0x........: syscall (in /...libc...) + by 0x........: __libc_start_main (...libc...) + by 0x........: ... + +Syscall param sigprocmask(oldset) contains uninitialised byte(s) + at 0x........: syscall (in /...libc...) + by 0x........: __libc_start_main (...libc...) + by 0x........: ... + +Syscall param sigprocmask(set) points to unaddressable byte(s) + at 0x........: syscall (in /...libc...) + by 0x........: __libc_start_main (...libc...) + by 0x........: ... + Address 0x........ is 0 bytes after a block of size 4 alloc'd + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (scalar.c:7) + +Syscall param sigprocmask(oldset) points to unaddressable byte(s) + at 0x........: syscall (in /...libc...) + by 0x........: __libc_start_main (...libc...) + by 0x........: ... + Address 0x........ is 0 bytes after a block of size 4 alloc'd + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (scalar.c:7) +----------------------------------------------------- 127: __NR_create_module ni ----------------------------------------------------- ----------------------------------------------------- @@ -2289,6 +2323,41 @@ Syscall param rt_sigaction(oldact) points to unaddressable byte(s) by 0x........: ... Address 0x........ is not stack'd, malloc'd or (recently) free'd ----------------------------------------------------- +175: __NR_rt_sigprocmask 4s 2m +----------------------------------------------------- + +Syscall param rt_sigprocmask(how) contains uninitialised byte(s) + at 0x........: syscall (in /...libc...) + by 0x........: __libc_start_main (...libc...) + by 0x........: ... + +Syscall param rt_sigprocmask(set) contains uninitialised byte(s) + at 0x........: syscall (in /...libc...) + by 0x........: __libc_start_main (...libc...) + by 0x........: ... + +Syscall param rt_sigprocmask(oldset) contains uninitialised byte(s) + at 0x........: syscall (in /...libc...) + by 0x........: __libc_start_main (...libc...) + by 0x........: ... + +Syscall param rt_sigprocmask(sigsetsize) contains uninitialised byte(s) + at 0x........: syscall (in /...libc...) + by 0x........: __libc_start_main (...libc...) + by 0x........: ... + +Syscall param rt_sigprocmask(set) points to unaddressable byte(s) + at 0x........: syscall (in /...libc...) + by 0x........: __libc_start_main (...libc...) + by 0x........: ... + Address 0x........ is not stack'd, malloc'd or (recently) free'd + +Syscall param rt_sigprocmask(oldset) points to unaddressable byte(s) + at 0x........: syscall (in /...libc...) + by 0x........: __libc_start_main (...libc...) + by 0x........: ... + Address 0x........ is not stack'd, malloc'd or (recently) free'd +----------------------------------------------------- 182: __NR_chown 3s 1m ----------------------------------------------------- diff --git a/memcheck/tests/sigprocmask.c b/memcheck/tests/sigprocmask.c new file mode 100644 index 000000000..dc00102ed --- /dev/null +++ b/memcheck/tests/sigprocmask.c @@ -0,0 +1,47 @@ + +#include +#include +#include +#include + +// Reg test for bug #93328: we were using too-big sigset types, and thus +// trashing memory when we wrote out the 'oldset' param from sigprocmask(). + +int main(void) +{ + int x[6], *s, *os, i; + + x[0] = 0x11111111; + x[1] = 0x89abcdef; + x[2] = 0x22222222; + x[3] = 0x33333333; + x[4] = 0x0; + x[5] = 0x44444444; + + s = &x[1]; + os = &x[4]; + + fprintf(stderr, "before\n"); + for (i = 0; i < 6; i++) { + fprintf(stderr, "%x ", x[i]); + } + fprintf(stderr, "\n"); + + syscall(__NR_sigprocmask, SIG_BLOCK, s, os); + + fprintf(stderr, "after1\n"); + for (i = 0; i < 6; i++) { + fprintf(stderr, "%x ", x[i]); + } + fprintf(stderr, "\n"); + + syscall(__NR_sigprocmask, SIG_BLOCK, s, os); + + fprintf(stderr, "after2\n"); + for (i = 0; i < 6; i++) { + fprintf(stderr, "%x ", x[i]); + } + fprintf(stderr, "\n"); + + return(0); +} diff --git a/memcheck/tests/sigprocmask.stderr.exp b/memcheck/tests/sigprocmask.stderr.exp new file mode 100644 index 000000000..e69de29bb diff --git a/memcheck/tests/sigprocmask.vgtest b/memcheck/tests/sigprocmask.vgtest new file mode 100644 index 000000000..e0331280c --- /dev/null +++ b/memcheck/tests/sigprocmask.vgtest @@ -0,0 +1,2 @@ +prog: sigprocmask +vgopts: -q