mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-06 21:15:22 +00:00
virnetserver: handle sigaction correctly
POSIX says that sa_sigaction is only safe to use if sa_flags includes SA_SIGINFO; conversely, sa_handler is only safe to use when flags excludes that bit. Gnulib doesn't guarantee an implementation of SA_SIGINFO, but does guarantee that if SA_SIGINFO is undefined, we can safely define it to 0 as long as we don't dereference the 2nd or 3rd argument of any handler otherwise registered via sa_sigaction. Based on a report by Wen Congyang. * src/rpc/virnetserver.c (SA_SIGINFO): Stub for mingw. (virNetServerSignalHandler): Avoid bogus dereference. (virNetServerFatalSignal, virNetServerNew): Set flags properly. (virNetServerAddSignalHandler): Drop unneeded #ifdef.
This commit is contained in:
parent
8a55d381ae
commit
ac620c2e4a
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* virnetserver.c: generic network RPC server
|
* virnetserver.c: generic network RPC server
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2011 Red Hat, Inc.
|
* Copyright (C) 2006-2012 Red Hat, Inc.
|
||||||
* Copyright (C) 2006 Daniel P. Berrange
|
* Copyright (C) 2006 Daniel P. Berrange
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
@ -43,6 +43,10 @@
|
|||||||
# include <dbus/dbus.h>
|
# include <dbus/dbus.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef SA_SIGINFO
|
||||||
|
# define SA_SIGINFO 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_RPC
|
#define VIR_FROM_THIS VIR_FROM_RPC
|
||||||
#define virNetError(code, ...) \
|
#define virNetError(code, ...) \
|
||||||
virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \
|
virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \
|
||||||
@ -277,8 +281,9 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void virNetServerFatalSignal(int sig, siginfo_t *siginfo ATTRIBUTE_UNUSED,
|
static void
|
||||||
void *context ATTRIBUTE_UNUSED)
|
virNetServerFatalSignal(int sig, siginfo_t *siginfo ATTRIBUTE_UNUSED,
|
||||||
|
void *context ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
struct sigaction sig_action;
|
struct sigaction sig_action;
|
||||||
int origerrno;
|
int origerrno;
|
||||||
@ -293,6 +298,7 @@ static void virNetServerFatalSignal(int sig, siginfo_t *siginfo ATTRIBUTE_UNUSED
|
|||||||
#ifdef SIGUSR2
|
#ifdef SIGUSR2
|
||||||
if (sig != SIGUSR2) {
|
if (sig != SIGUSR2) {
|
||||||
#endif
|
#endif
|
||||||
|
memset(&sig_action, 0, sizeof(sig_action));
|
||||||
sig_action.sa_handler = SIG_DFL;
|
sig_action.sa_handler = SIG_DFL;
|
||||||
sigaction(sig, &sig_action, NULL);
|
sigaction(sig, &sig_action, NULL);
|
||||||
raise(sig);
|
raise(sig);
|
||||||
@ -390,6 +396,7 @@ virNetServerPtr virNetServerNew(size_t min_workers,
|
|||||||
* debugging purposes or testing
|
* debugging purposes or testing
|
||||||
*/
|
*/
|
||||||
sig_action.sa_sigaction = virNetServerFatalSignal;
|
sig_action.sa_sigaction = virNetServerFatalSignal;
|
||||||
|
sig_action.sa_flags = SA_SIGINFO;
|
||||||
sigaction(SIGFPE, &sig_action, NULL);
|
sigaction(SIGFPE, &sig_action, NULL);
|
||||||
sigaction(SIGSEGV, &sig_action, NULL);
|
sigaction(SIGSEGV, &sig_action, NULL);
|
||||||
sigaction(SIGILL, &sig_action, NULL);
|
sigaction(SIGILL, &sig_action, NULL);
|
||||||
@ -455,17 +462,24 @@ static sig_atomic_t sigErrors = 0;
|
|||||||
static int sigLastErrno = 0;
|
static int sigLastErrno = 0;
|
||||||
static int sigWrite = -1;
|
static int sigWrite = -1;
|
||||||
|
|
||||||
static void virNetServerSignalHandler(int sig, siginfo_t * siginfo,
|
static void
|
||||||
void* context ATTRIBUTE_UNUSED)
|
virNetServerSignalHandler(int sig, siginfo_t * siginfo,
|
||||||
|
void* context ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
int origerrno;
|
int origerrno;
|
||||||
int r;
|
int r;
|
||||||
|
siginfo_t tmp;
|
||||||
|
|
||||||
|
if (SA_SIGINFO)
|
||||||
|
tmp = *siginfo;
|
||||||
|
else
|
||||||
|
memset(&tmp, 0, sizeof(tmp));
|
||||||
|
|
||||||
/* set the sig num in the struct */
|
/* set the sig num in the struct */
|
||||||
siginfo->si_signo = sig;
|
tmp.si_signo = sig;
|
||||||
|
|
||||||
origerrno = errno;
|
origerrno = errno;
|
||||||
r = safewrite(sigWrite, siginfo, sizeof(*siginfo));
|
r = safewrite(sigWrite, &tmp, sizeof(tmp));
|
||||||
if (r == -1) {
|
if (r == -1) {
|
||||||
sigErrors++;
|
sigErrors++;
|
||||||
sigLastErrno = errno;
|
sigLastErrno = errno;
|
||||||
@ -568,9 +582,7 @@ int virNetServerAddSignalHandler(virNetServerPtr srv,
|
|||||||
|
|
||||||
memset(&sig_action, 0, sizeof(sig_action));
|
memset(&sig_action, 0, sizeof(sig_action));
|
||||||
sig_action.sa_sigaction = virNetServerSignalHandler;
|
sig_action.sa_sigaction = virNetServerSignalHandler;
|
||||||
#ifdef SA_SIGINFO
|
|
||||||
sig_action.sa_flags = SA_SIGINFO;
|
sig_action.sa_flags = SA_SIGINFO;
|
||||||
#endif
|
|
||||||
sigemptyset(&sig_action.sa_mask);
|
sigemptyset(&sig_action.sa_mask);
|
||||||
|
|
||||||
sigaction(signum, &sig_action, &sigdata->oldaction);
|
sigaction(signum, &sig_action, &sigdata->oldaction);
|
||||||
|
Loading…
Reference in New Issue
Block a user