+2002-03-29 Julian Seward <sewardj@localhost.localdomain>
+
+ * vg_signals.c (VG_(do__NR_sigaction)): Don't allow setting of
+ handlers for SIGKILL or SIGSTOP. This fixes
+ valgrind: vg_signals.c:723 (vgPlain_do__NR_sigaction):
+ Assertion `our_old_handler == ((void *)0)' failed.
+
2002-03-29 Alexandre Duret-Lutz <duret_g@epita.fr>
* vg_syscall_mem.c: wrapper for ioctl TIOCGPGRP.
#define VKI_MAP_PRIVATE 0x02 /* Changes are private. */
+/* Copied from /usr/src/linux-2.4.9-13/include/asm/errno.h */
+
+#define VKI_EINVAL 22 /* Invalid argument */
+
+
/* Gawd ... hack ... */
typedef struct vki__user_cap_header_struct {
(UInt)(new_action ? new_action->ksa_flags : 0) );
/* VG_(ppSigProcMask)(); */
- if (param1 < 1 || param1 >= VKI_KNSIG) goto bad;
+ /* Rule out various error conditions. The aim is to ensure that if
+ the call is passed to the kernel it will definitely succeed. */
+
+ /* Reject out-of-range signal numbers. */
+ if (param1 < 1 || param1 >= VKI_KNSIG) goto bad_signo;
+
+ /* Reject attempts to set a handler (or set ignore) for SIGKILL. */
+ if ( (param1 == VKI_SIGKILL || param1 == VKI_SIGSTOP)
+ && new_action
+ && new_action->ksa_handler != VKI_SIG_DFL)
+ goto bad_sigkill;
our_old_handler = VG_(sighandler)[param1];
/* VG_(printf)("old handler = 0x%x\n", our_old_handler); */
KERNEL_DO_SYSCALL(res);
/* VG_(printf)("RES = %d\n", res); */
+
/* If the client asks for the old handler, maintain our fiction
by stuffing in the handler it thought it asked for ... */
if (old_action) {
VG_(baseBlock)[VGOFF_(m_eax)] = (UInt)0;
return;
- bad:
+ bad_signo:
VG_(message)(Vg_UserMsg,
"Warning: bad signal number %d in __NR_sigaction.",
param1);
- VG_(baseBlock)[VGOFF_(m_eax)] = (UInt)(-1);
+ VG_(baseBlock)[VGOFF_(m_eax)] = (UInt)(-VKI_EINVAL);
+ return;
+
+ bad_sigkill:
+ VG_(message)(Vg_UserMsg,
+ "Warning: attempt to set SIGKILL handler in __NR_sigaction.",
+ param1);
+ VG_(baseBlock)[VGOFF_(m_eax)] = (UInt)(-VKI_EINVAL);
return;
}
--- /dev/null
+
+#include <errno.h>
+#include <stdio.h>
+#include <signal.h>
+#include <stdlib.h>
+
+static void
+abend (int sig)
+{
+ printf ("Abended on signal %d\n", sig);
+ exit (2);
+}
+
+int
+main (void)
+{
+ struct sigaction sa;
+
+ int i;
+ for (i = 1; i <= 64; i++) {
+ sa.sa_flags = 0;
+ sigemptyset( &sa.sa_mask );
+ sa.sa_handler = abend;
+ errno = 0;
+ fprintf(stderr, "setting signal %d: ", i);
+ sigaction (i /*SIGKILL*/, &sa, NULL);
+ perror ("");
+ errno = 0;
+ fprintf(stderr, "getting signal %d: ", i);
+ sigaction (i /*SIGKILL*/, NULL, &sa);
+ perror ("");
+ fprintf(stderr, "\n");
+ }
+ return 0;
+}
printf ( "signal returns\n" );
}
-void main ( void )
+int main ( void )
{
spin = 1;
printf ( "installing sig handler\n" );
printf ( "entering busy wait\n" );
while (spin) { };
printf ( "exited\n" );
+ return 0;
}
exit(1);
}
-void main ( void )
+int main ( void )
{
printf ( "installing sig handler\n" );
signal(SIGSEGV, sig_hdlr);
printf ( "doing bad thing\n" );
* (int*) 0 = 0;
printf ( "exited normally ?!\n" );
+ return 0;
}
assert(ret == 0);
}
-void main ( void )
+int main ( void )
{
hdp_init_profiling();
while (1) {}
+ return 0;
}
#define VKI_MAP_PRIVATE 0x02 /* Changes are private. */
+/* Copied from /usr/src/linux-2.4.9-13/include/asm/errno.h */
+
+#define VKI_EINVAL 22 /* Invalid argument */
+
+
/* Gawd ... hack ... */
typedef struct vki__user_cap_header_struct {
(UInt)(new_action ? new_action->ksa_flags : 0) );
/* VG_(ppSigProcMask)(); */
- if (param1 < 1 || param1 >= VKI_KNSIG) goto bad;
+ /* Rule out various error conditions. The aim is to ensure that if
+ the call is passed to the kernel it will definitely succeed. */
+
+ /* Reject out-of-range signal numbers. */
+ if (param1 < 1 || param1 >= VKI_KNSIG) goto bad_signo;
+
+ /* Reject attempts to set a handler (or set ignore) for SIGKILL. */
+ if ( (param1 == VKI_SIGKILL || param1 == VKI_SIGSTOP)
+ && new_action
+ && new_action->ksa_handler != VKI_SIG_DFL)
+ goto bad_sigkill;
our_old_handler = VG_(sighandler)[param1];
/* VG_(printf)("old handler = 0x%x\n", our_old_handler); */
KERNEL_DO_SYSCALL(res);
/* VG_(printf)("RES = %d\n", res); */
+
/* If the client asks for the old handler, maintain our fiction
by stuffing in the handler it thought it asked for ... */
if (old_action) {
VG_(baseBlock)[VGOFF_(m_eax)] = (UInt)0;
return;
- bad:
+ bad_signo:
VG_(message)(Vg_UserMsg,
"Warning: bad signal number %d in __NR_sigaction.",
param1);
- VG_(baseBlock)[VGOFF_(m_eax)] = (UInt)(-1);
+ VG_(baseBlock)[VGOFF_(m_eax)] = (UInt)(-VKI_EINVAL);
+ return;
+
+ bad_sigkill:
+ VG_(message)(Vg_UserMsg,
+ "Warning: attempt to set SIGKILL handler in __NR_sigaction.",
+ param1);
+ VG_(baseBlock)[VGOFF_(m_eax)] = (UInt)(-VKI_EINVAL);
return;
}