OpenVAS Scanner  5.1.3
sighand.c
Go to the documentation of this file.
1 /* OpenVAS
2 * $Id$
3 * Description: Provides signal handling functions.
4 *
5 * Authors: - Renaud Deraison <deraison@nessus.org> (Original pre-fork develoment)
6 * - Tim Brown <mailto:timb@openvas.org> (Initial fork)
7 * - Laban Mwangi <mailto:labanm@openvas.org> (Renaming work)
8 * - Tarik El-Yassem <mailto:tarik@openvas.org> (Headers section)
9 *
10 * Copyright:
11 * Portions Copyright (C) 2006 Software in the Public Interest, Inc.
12 * Based on work Copyright (C) 1998 - 2006 Tenable Network Security, Inc.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2,
16 * as published by the Free Software Foundation
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26 */
27 
28 #include <signal.h> /* for kill() */
29 #include <unistd.h> /* for getpid() */
30 #include <errno.h> /* for errno() */
31 #include <sys/wait.h> /* for wait() */
32 #include <sys/socket.h> /* for shutdown() */
33 #include <execinfo.h>
34 
35 #include "log.h"
36 #include "sighand.h"
37 #include "utils.h"
38 #include "string.h"
39 
40 #include <openvas/base/pidfile.h>
41 
42 /* do not leave a zombie, hanging around if possible */
43 void
44 let_em_die (int pid)
45 {
46  int status;
47 
48  waitpid (pid, &status, WNOHANG);
49 }
50 
51 
52 void
53 make_em_die (int sig)
54 {
55  /* number of times, the sig is sent at most */
56  int n = 3;
57 
58  /* leave if we are session leader */
59  if (getpgrp () != getpid ())
60  return;
61 
62  /* quickly send signals and check the result */
63  if (kill (0, sig) < 0)
64  return;
65  let_em_die (0);
66  if (kill (0, 0) < 0)
67  return;
68 
69  do
70  {
71  /* send the signal to everybody in the group */
72  if (kill (0, sig) < 0)
73  return;
74  sleep (1);
75  /* do not leave a zombie, hanging around if possible */
76  let_em_die (0);
77  }
78  while (--n > 0);
79 
80  if (kill (0, 0) < 0)
81  return;
82 
83  kill (0, SIGKILL);
84  sleep (1);
85  let_em_die (0);
86 }
87 
88 /*
89  * Replacement for the signal() function, written
90  * by Sagi Zeevi <sagiz@yahoo.com>
91  */
92 void (*openvas_signal (int signum, void (*handler) (int))) (int)
93 {
94  struct sigaction saNew, saOld;
95 
96  /* Init new handler */
97  sigfillset (&saNew.sa_mask);
98  sigdelset (&saNew.sa_mask, SIGALRM); /* make sleep() work */
99 
100  saNew.sa_flags = 0;
101  saNew.sa_handler = handler;
102 
103  sigaction (signum, &saNew, &saOld);
104  return saOld.sa_handler;
105 }
106 
107 
108 void
109 sighand_chld (pid_t pid)
110 {
111  int status;
112 
113  waitpid (pid, &status, WNOHANG);
114 }
115 
116 static void
117 print_trace ()
118 {
119  void *array[10];
120  int fd, ret = 0, left;
121  char *message = "SIGSEGV occured !\n";
122 
123  fd = log_get_fd ();
124  if (fd < 0)
125  return;
126 
127  left = strlen (message);
128  while (left)
129  {
130  ret = write (fd, message, left);
131  if (ret == -1)
132  {
133  if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
134  continue;
135  break;
136  }
137  left -= ret;
138  message += ret;
139  }
140  ret = backtrace (array, 10);
141  backtrace_symbols_fd (array, ret, fd);
142 }
143 
144 void
145 sighand_segv (int given_signal)
146 {
147  signal (SIGSEGV, _exit);
148  print_trace ();
149  make_em_die (SIGTERM);
150  /* Raise signal again, to exit with the correct return value,
151  * and to enable core dumping. */
152  openvas_signal (given_signal, SIG_DFL);
153  raise (given_signal);
154 }
void(*)(int) openvas_signal(int signum, void(*handler)(int))
Definition: sighand.c:92
int log_get_fd()
Get the open log file descriptor.
Definition: log.c:84
void sighand_chld(pid_t pid)
Definition: sighand.c:109
void sighand_segv(int given_signal)
Definition: sighand.c:145
void make_em_die(int sig)
Definition: sighand.c:53
void let_em_die(int pid)
Definition: sighand.c:44