OpenVAS Scanner  7.0.0~git
pluginlaunch.c File Reference

Manages the launching of plugins within processes. More...

#include "pluginlaunch.h"
#include "../misc/network.h"
#include "../misc/nvt_categories.h"
#include "pluginload.h"
#include "pluginscheduler.h"
#include "plugs_req.h"
#include "processes.h"
#include "sighand.h"
#include "utils.h"
#include <errno.h>
#include <gvm/base/prefs.h>
#include <gvm/util/nvticache.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <unistd.h>
Include dependency graph for pluginlaunch.c:

Go to the source code of this file.

Data Structures

struct  running
 Structure to represent a process in the sense of a running NVT. More...
 

Macros

#define G_LOG_DOMAIN   "sd main"
 GLib log domain. More...
 
#define MAX_PROCESSES   32
 'Hard' limit of the max. number of concurrent plugins per host. More...
 

Functions

static void update_running_processes (kb_t kb)
 
static int common (GSList *list1, GSList *list2)
 
static GSList * required_ports_in_list (const char *oid, GSList *list)
 
static int simult_ports (const char *oid, const char *next_oid)
 
static int next_free_process (kb_t kb, struct scheduler_plugin *upcoming)
 
void pluginlaunch_init (const char *host)
 
void pluginlaunch_disable_parallel_checks (void)
 
void pluginlaunch_enable_parallel_checks (void)
 
void pluginlaunch_stop ()
 
static int plugin_timeout (nvti_t *nvti)
 
int plugin_launch (struct scan_globals *globals, struct scheduler_plugin *plugin, struct in6_addr *ip, GSList *vhosts, kb_t kb, nvti_t *nvti)
 
void pluginlaunch_wait (kb_t kb)
 Waits and 'pushes' processes until num_running_processes is 0. More...
 
static int timeout_running_processes ()
 Return shortest timeout of the running processes. More...
 
void pluginlaunch_wait_for_free_process (kb_t kb)
 Waits and 'pushes' processes until the number of running processes has changed. More...
 

Variables

static struct running processes [MAX_PROCESSES]
 
static int num_running_processes
 
static int max_running_processes
 
static int old_max_running_processes
 
static GSList * non_simult_ports = NULL
 
const char * hostname = NULL
 

Detailed Description

Manages the launching of plugins within processes.

Definition in file pluginlaunch.c.

Macro Definition Documentation

◆ G_LOG_DOMAIN

#define G_LOG_DOMAIN   "sd main"

GLib log domain.

Definition at line 52 of file pluginlaunch.c.

◆ MAX_PROCESSES

#define MAX_PROCESSES   32

'Hard' limit of the max. number of concurrent plugins per host.

Definition at line 57 of file pluginlaunch.c.

Function Documentation

◆ common()

static int common ( GSList *  list1,
GSList *  list2 
)
static

Definition at line 168 of file pluginlaunch.c.

169 {
170  if (!list1 || !list2)
171  return 0;
172 
173  while (list1)
174  {
175  GSList *tmp = list2;
176  while (tmp)
177  {
178  if (!strcmp (list1->data, tmp->data))
179  return 1;
180  tmp = tmp->next;
181  }
182  list1 = list1->next;
183  }
184  return 0;
185 }

Referenced by simult_ports().

Here is the caller graph for this function:

◆ next_free_process()

static int next_free_process ( kb_t  kb,
struct scheduler_plugin upcoming 
)
static

If another NVT with same port requirements is running, wait.

Returns
-1 if MAX_PROCESSES are running, the index of the first free "slot" in the processes array otherwise.

Definition at line 242 of file pluginlaunch.c.

243 {
244  int r;
245 
246  for (r = 0; r < MAX_PROCESSES; r++)
247  {
248  if (processes[r].pid > 0
249  && simult_ports (processes[r].plugin->oid, upcoming->oid))
250  {
251  while (process_alive (processes[r].pid))
252  {
254  usleep (250000);
255  }
256  }
257  }
258  for (r = 0; r < MAX_PROCESSES; r++)
259  if (processes[r].pid <= 0)
260  return r;
261  return -1;
262 }

References MAX_PROCESSES, scheduler_plugin::oid, pid, process_alive(), processes, simult_ports(), and update_running_processes().

Referenced by plugin_launch().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ plugin_launch()

int plugin_launch ( struct scan_globals globals,
struct scheduler_plugin plugin,
struct in6_addr *  ip,
GSList *  vhosts,
kb_t  kb,
nvti_t *  nvti 
)
Returns
PID of process that is connected to the plugin as returned by plugin classes pl_launch function (<=0 means there was a problem).

Definition at line 343 of file pluginlaunch.c.

345 {
346  int p;
347 
348  /* Wait for a free slot */
350  p = next_free_process (kb, plugin);
351  if (p < 0)
352  return -1;
353  processes[p].plugin = plugin;
354  processes[p].timeout = plugin_timeout (nvti);
355  gettimeofday (&(processes[p].start), NULL);
356  processes[p].pid = nasl_plugin_launch (globals, ip, vhosts, kb, plugin->oid);
357 
358  if (processes[p].pid > 0)
360  else
362 
363  return processes[p].pid;
364 }

References nasl_plugin_launch(), next_free_process(), num_running_processes, scheduler_plugin::oid, running::pid, pid, running::plugin, PLUGIN_STATUS_UNRUN, plugin_timeout(), pluginlaunch_wait_for_free_process(), processes, scheduler_plugin::running_state, and running::timeout.

Referenced by launch_plugin().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ plugin_timeout()

static int plugin_timeout ( nvti_t *  nvti)
static

Definition at line 319 of file pluginlaunch.c.

320 {
321  int timeout;
322 
323  assert (nvti);
324  timeout = prefs_nvt_timeout (nvti_oid (nvti));
325  if (timeout == 0)
326  timeout = nvti_timeout (nvti);
327  if (timeout == 0)
328  {
329  if (nvti_category (nvti) == ACT_SCANNER)
330  timeout =
331  atoi (prefs_get ("scanner_plugins_timeout")) ?: SCANNER_NVT_TIMEOUT;
332  else
333  timeout = atoi (prefs_get ("plugins_timeout")) ?: NVT_TIMEOUT;
334  }
335  return timeout;
336 }

References ACT_SCANNER.

Referenced by plugin_launch().

Here is the caller graph for this function:

◆ pluginlaunch_disable_parallel_checks()

void pluginlaunch_disable_parallel_checks ( void  )

Definition at line 290 of file pluginlaunch.c.

291 {
293 }

References max_running_processes.

Referenced by get_next_in_range().

Here is the caller graph for this function:

◆ pluginlaunch_enable_parallel_checks()

void pluginlaunch_enable_parallel_checks ( void  )

Definition at line 296 of file pluginlaunch.c.

References max_running_processes, and old_max_running_processes.

Referenced by get_next_in_range().

Here is the caller graph for this function:

◆ pluginlaunch_init()

void pluginlaunch_init ( const char *  host)

Definition at line 265 of file pluginlaunch.c.

266 {
267  int i;
268 
269  char **split = g_strsplit (prefs_get ("non_simult_ports"), ", ", 0);
270  for (i = 0; split[i]; i++)
271  non_simult_ports = g_slist_prepend (non_simult_ports, g_strdup (split[i]));
272  g_strfreev (split);
275  hostname = host;
276 
278  {
279  g_debug ("max_checks (%d) > MAX_PROCESSES (%d) - modify "
280  "openvas/openvas/pluginlaunch.c",
283  }
284 
286  bzero (&(processes), sizeof (processes));
287 }

References get_max_checks_number(), hostname, MAX_PROCESSES, max_running_processes, non_simult_ports, num_running_processes, old_max_running_processes, and processes.

Referenced by attack_host().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pluginlaunch_stop()

void pluginlaunch_stop ( )

Definition at line 302 of file pluginlaunch.c.

303 {
304  int i;
305 
306  for (i = 0; i < MAX_PROCESSES; i++)
307  {
308  if (processes[i].pid > 0)
309  {
310  terminate_process (processes[i].pid * -1);
313  bzero (&(processes[i]), sizeof (struct running));
314  }
315  }
316 }

References MAX_PROCESSES, num_running_processes, pid, running::plugin, PLUGIN_STATUS_DONE, processes, scheduler_plugin::running_state, and terminate_process().

Referenced by attack_host(), handle_scan_stop_signal(), and launch_plugin().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pluginlaunch_wait()

void pluginlaunch_wait ( kb_t  kb)

Waits and 'pushes' processes until num_running_processes is 0.

Definition at line 370 of file pluginlaunch.c.

371 {
372  while (num_running_processes)
373  {
376  waitpid (-1, NULL, 0);
377  }
378 }

References num_running_processes, and update_running_processes().

Referenced by attack_host().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pluginlaunch_wait_for_free_process()

void pluginlaunch_wait_for_free_process ( kb_t  kb)

Waits and 'pushes' processes until the number of running processes has changed.

Definition at line 403 of file pluginlaunch.c.

404 {
406  return;
408  /* Max number of processes are still running, wait for a child to exit or
409  * to timeout. */
411  {
412  sigset_t mask;
413  struct timespec ts = {0, 0};
414 
415  ts.tv_sec = timeout_running_processes ();
416  assert (ts.tv_sec);
417  sigemptyset (&mask);
418  sigaddset (&mask, SIGCHLD);
419  if (sigtimedwait (&mask, NULL, &ts) < 0 && errno != EAGAIN)
420  g_warning ("%s: %s", __FUNCTION__, strerror (errno));
422  }
423 }

References max_running_processes, num_running_processes, timeout_running_processes(), and update_running_processes().

Referenced by attack_host(), and plugin_launch().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ required_ports_in_list()

static GSList* required_ports_in_list ( const char *  oid,
GSList *  list 
)
static

Definition at line 188 of file pluginlaunch.c.

189 {
190  GSList *common_ports = NULL;
191  char **array, *ports;
192  int i;
193 
194  if (!oid || !list)
195  return 0;
196  ports = nvticache_get_required_ports (oid);
197  if (!ports)
198  return 0;
199  array = g_strsplit (ports, ", ", 0);
200  g_free (ports);
201  if (!array)
202  return 0;
203 
204  for (i = 0; array[i]; i++)
205  {
206  GSList *tmp = list;
207  while (tmp)
208  {
209  if (!strcmp (tmp->data, array[i]))
210  common_ports = g_slist_prepend (common_ports, g_strdup (tmp->data));
211  tmp = tmp->next;
212  }
213  }
214 
215  g_strfreev (array);
216  return common_ports;
217 }

References oid.

Referenced by simult_ports().

Here is the caller graph for this function:

◆ simult_ports()

static int simult_ports ( const char *  oid,
const char *  next_oid 
)
static

Definition at line 220 of file pluginlaunch.c.

221 {
222  int ret = 0;
223  GSList *common_ports1 = NULL, *common_ports2 = NULL;
224 
225  common_ports1 = required_ports_in_list (oid, non_simult_ports);
226  if (common_ports1)
227  common_ports2 = required_ports_in_list (next_oid, non_simult_ports);
228  if (common_ports1 && common_ports2 && common (common_ports1, common_ports2))
229  ret = 1;
230  g_slist_free_full (common_ports1, g_free);
231  g_slist_free_full (common_ports2, g_free);
232  return ret;
233 }

References common(), non_simult_ports, oid, and required_ports_in_list().

Referenced by next_free_process().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ timeout_running_processes()

static int timeout_running_processes ( )
static

Return shortest timeout of the running processes.

Definition at line 384 of file pluginlaunch.c.

385 {
386  int i, timeout = 0;
387 
388  for (i = 0; i < MAX_PROCESSES; i++)
389  {
390  if (processes[i].pid <= 0)
391  continue;
392  if (!timeout || processes[i].timeout < timeout)
393  timeout = processes[i].timeout;
394  }
395  return timeout;
396 }

References MAX_PROCESSES, pid, processes, and running::timeout.

Referenced by pluginlaunch_wait_for_free_process().

Here is the caller graph for this function:

◆ update_running_processes()

static void update_running_processes ( kb_t  kb)
static

Definition at line 82 of file pluginlaunch.c.

83 {
84  int i;
85  struct timeval now;
86  int log_whole = prefs_get_bool ("log_whole_attack");
87 
88  if (num_running_processes == 0)
89  return;
90 
91  gettimeofday (&now, NULL);
92  for (i = 0; i < MAX_PROCESSES; i++)
93  {
94  if (processes[i].pid > 0)
95  {
96  int is_alive = process_alive (processes[i].pid);
97  int ret_terminate = 0;
98 
99  // If process dead or timed out
100  if (!is_alive
101  || (processes[i].timeout > 0
102  && ((now.tv_sec - processes[i].start.tv_sec)
103  > processes[i].timeout)))
104  {
105  char *oid = processes[i].plugin->oid;
106 
107  if (is_alive)
108  {
109  char msg[2048];
110 
111  if (log_whole)
112  g_message ("%s (pid %d) is slow to finish - killing it",
113  oid, processes[i].pid);
114 
115  sprintf (msg,
116  "ERRMSG||| |||general/tcp|||%s|||"
117  "NVT timed out after %d seconds.",
118  oid ?: " ", processes[i].timeout);
119  kb_item_push_str (kb, "internal/results", msg);
120 
121  ret_terminate = terminate_process (processes[i].pid);
122  if (ret_terminate == 0)
123  {
124  terminate_process (processes[i].pid * -1);
127  bzero (&(processes[i]), sizeof (processes[i]));
128  }
129  }
130  else
131  {
132  struct timeval old_now = now;
133  int e;
134  if (now.tv_usec < processes[i].start.tv_usec)
135  {
136  processes[i].start.tv_sec++;
137  now.tv_usec += 1000000;
138  }
139  if (log_whole)
140  {
141  char *name = nvticache_get_filename (oid);
142  g_message (
143  "%s (%s) [%d] finished its job in %ld.%.3ld seconds",
144  name, oid, processes[i].pid,
145  (long) (now.tv_sec - processes[i].start.tv_sec),
146  (long) ((now.tv_usec - processes[i].start.tv_usec)
147  / 1000));
148  g_free (name);
149  }
150  now = old_now;
151  do
152  {
153  e = waitpid (processes[i].pid, NULL, 0);
154  }
155  while (e < 0 && errno == EINTR);
156 
157  terminate_process (processes[i].pid * -1);
160  bzero (&(processes[i]), sizeof (processes[i]));
161  }
162  }
163  }
164  }
165 }

References MAX_PROCESSES, name, num_running_processes, scheduler_plugin::oid, oid, pid, running::plugin, PLUGIN_STATUS_DONE, process_alive(), processes, scheduler_plugin::running_state, running::start, terminate_process(), running::timeout, and timeval().

Referenced by next_free_process(), pluginlaunch_wait(), and pluginlaunch_wait_for_free_process().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ hostname

◆ max_running_processes

◆ non_simult_ports

GSList* non_simult_ports = NULL
static

Definition at line 75 of file pluginlaunch.c.

Referenced by pluginlaunch_init(), and simult_ports().

◆ num_running_processes

◆ old_max_running_processes

int old_max_running_processes
static

Definition at line 74 of file pluginlaunch.c.

Referenced by pluginlaunch_enable_parallel_checks(), and pluginlaunch_init().

◆ processes

terminate_process
int terminate_process(pid_t pid)
Send SIGTERM to the pid process. Try to wait the the process. In case of the process has still not ch...
Definition: processes.c:58
plugin_timeout
static int plugin_timeout(nvti_t *nvti)
Definition: pluginlaunch.c:319
non_simult_ports
static GSList * non_simult_ports
Definition: pluginlaunch.c:75
simult_ports
static int simult_ports(const char *oid, const char *next_oid)
Definition: pluginlaunch.c:220
running::timeout
int timeout
Definition: pluginlaunch.c:67
running
Structure to represent a process in the sense of a running NVT.
Definition: pluginlaunch.c:62
timeval
struct timeval timeval(unsigned long val)
Definition: nasl_builtin_synscan.c:105
pid
static pid_t pid
Definition: nasl_builtin_nmap.c:499
running::start
struct timeval start
Definition: pluginlaunch.c:65
num_running_processes
static int num_running_processes
Definition: pluginlaunch.c:72
common
static int common(GSList *list1, GSList *list2)
Definition: pluginlaunch.c:168
PLUGIN_STATUS_DONE
@ PLUGIN_STATUS_DONE
Definition: pluginscheduler.h:37
name
const char * name
Definition: nasl_init.c:377
oid
const char * oid
Definition: nasl_builtin_find_service.c:57
scheduler_plugin::running_state
enum plugin_status running_state
Definition: pluginscheduler.h:44
next_free_process
static int next_free_process(kb_t kb, struct scheduler_plugin *upcoming)
Definition: pluginlaunch.c:242
required_ports_in_list
static GSList * required_ports_in_list(const char *oid, GSList *list)
Definition: pluginlaunch.c:188
MAX_PROCESSES
#define MAX_PROCESSES
'Hard' limit of the max. number of concurrent plugins per host.
Definition: pluginlaunch.c:57
running::pid
pid_t pid
Definition: pluginlaunch.c:66
update_running_processes
static void update_running_processes(kb_t kb)
Definition: pluginlaunch.c:82
process_alive
int process_alive(pid_t pid)
Definition: utils.c:204
scheduler_plugin::oid
char * oid
Definition: pluginscheduler.h:42
PLUGIN_STATUS_UNRUN
@ PLUGIN_STATUS_UNRUN
Definition: pluginscheduler.h:35
host
Host information, implemented as doubly linked list.
Definition: hosts.c:46
get_max_checks_number
int get_max_checks_number(void)
Definition: utils.c:174
ACT_SCANNER
@ ACT_SCANNER
Definition: nvt_categories.h:39
pluginlaunch_wait_for_free_process
void pluginlaunch_wait_for_free_process(kb_t kb)
Waits and 'pushes' processes until the number of running processes has changed.
Definition: pluginlaunch.c:403
hostname
const char * hostname
Definition: pluginlaunch.c:76
running::plugin
struct scheduler_plugin * plugin
Definition: pluginlaunch.c:64
timeout_running_processes
static int timeout_running_processes()
Return shortest timeout of the running processes.
Definition: pluginlaunch.c:384
nasl_plugin_launch
int nasl_plugin_launch(struct scan_globals *globals, struct in6_addr *ip, GSList *vhosts, kb_t kb, const char *oid)
Launch a NASL plugin.
Definition: nasl_plugins.c:151
max_running_processes
static int max_running_processes
Definition: pluginlaunch.c:73
list
Definition: nasl_builtin_synscan.c:259
processes
static struct running processes[MAX_PROCESSES]
Definition: pluginlaunch.c:71
old_max_running_processes
static int old_max_running_processes
Definition: pluginlaunch.c:74