Skip to content

Commit

Permalink
Improve error handling for plugin_launch.
Browse files Browse the repository at this point in the history
Improve messages and docstrings.
Set warning log level instead of debug log level for plugin_launch error messages.
  • Loading branch information
jjnicola committed Aug 9, 2021
1 parent 61c76a4 commit b43156e
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 27 deletions.
35 changes: 20 additions & 15 deletions src/attack.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@
#include <unistd.h> /* for close() */

#define ERR_HOST_DEAD -1
#define ERR_CANT_FORK -2

#define MAX_FORK_RETRIES 10
/**
Expand Down Expand Up @@ -346,13 +345,14 @@ check_new_vhosts (void)
* Does not launch a plugin twice if !save_kb_replay.
*
* @return ERR_HOST_DEAD if host died, ERR_CANT_FORK if forking failed,
* 0 otherwise.
* ERR_NO_FREE_SLOT if the process table is full, 0 otherwise.
*/
static int
launch_plugin (struct scan_globals *globals, struct scheduler_plugin *plugin,
struct in6_addr *ip, GSList *vhosts, kb_t kb, kb_t main_kb)
{
int optimize = prefs_get_bool ("optimize_test"), pid, ret = 0;
int optimize = prefs_get_bool ("optimize_test");
int launch_error, pid, ret = 0;
char *oid, *name, *error = NULL, ip_str[INET6_ADDRSTRLEN];
nvti_t *nvti;

Expand Down Expand Up @@ -428,14 +428,13 @@ launch_plugin (struct scan_globals *globals, struct scheduler_plugin *plugin,

/* Update vhosts list and start the plugin */
check_new_vhosts ();
pid = plugin_launch (globals, plugin, ip, vhosts, kb, main_kb, nvti);
if (pid < 0)
launch_error = 0;
pid = plugin_launch (globals, plugin, ip, vhosts, kb, main_kb, nvti,
&launch_error);
if (launch_error == ERR_NO_FREE_SLOT || launch_error == ERR_CANT_FORK)
{
plugin->running_state = PLUGIN_STATUS_UNRUN;
if (pid == ERR_NO_FREE_SLOT)
ret = ERR_NO_FREE_SLOT;
else
ret = ERR_CANT_FORK;
ret = launch_error;
goto finish_launch_plugin;
}

Expand Down Expand Up @@ -524,25 +523,31 @@ attack_host (struct scan_globals *globals, struct in6_addr *ip, GSList *vhosts,
}
else if (e == ERR_NO_FREE_SLOT)
{
g_debug (
"fork() failed for %s. No free slot to run a plugin.",
plugin->oid);
goto again;
if (forks_retry < MAX_FORK_RETRIES)
{
forks_retry++;
g_warning ("Launch failed for %s. No free slot available "
"in the internal process table for starting a "
"plugin.",
plugin->oid);
fork_sleep (forks_retry);
goto again;
}
}
else if (e == ERR_CANT_FORK)
{
if (forks_retry < MAX_FORK_RETRIES)
{
forks_retry++;
g_debug (
g_warning (
"fork() failed for %s - sleeping %d seconds (%s)",
plugin->oid, forks_retry, strerror (errno));
fork_sleep (forks_retry);
goto again;
}
else
{
g_debug ("fork() failed too many times - aborting");
g_warning ("fork() failed too many times - aborting");
goto host_died;
}
}
Expand Down
28 changes: 18 additions & 10 deletions src/pluginlaunch.c
Original file line number Diff line number Diff line change
Expand Up @@ -388,13 +388,20 @@ check_sysload ()
}

/**
* @brief Start a plugin.
*
* Check for free slots available in the process table. Set error with
* ERR_NO_FREE_SLOT if the process table is full. Set error with ERR_CANT_FORK
* if was not possible to fork() a new child.
*
* @return PID of process that is connected to the plugin as returned by plugin
* classes pl_launch function (<=0 means there was a problem).
* classes pl_launch function. Less than 0 means there was a problem,
* but error param should be checked.
*/
int
plugin_launch (struct scan_globals *globals, struct scheduler_plugin *plugin,
struct in6_addr *ip, GSList *vhosts, kb_t kb, kb_t main_kb,
nvti_t *nvti)
nvti_t *nvti, int *error)
{
int p;

Expand All @@ -403,12 +410,11 @@ plugin_launch (struct scan_globals *globals, struct scheduler_plugin *plugin,
p = next_free_process (main_kb, plugin);
if (p < 0)
{
g_debug ("There is currently no free slot available for starting a new "
"plugin, probably because the parallel check is temporarily "
"disabled. Current parallel checks: %d. Old parallel checks: %d",
max_running_processes, old_max_running_processes);
usleep (250000);
return ERR_NO_FREE_SLOT;
g_warning ("%s. There is currently no free slot available for starting a "
"new plugin.",
__func__);
*error = ERR_NO_FREE_SLOT;
return -1;
}

processes[p].plugin = plugin;
Expand All @@ -420,8 +426,10 @@ plugin_launch (struct scan_globals *globals, struct scheduler_plugin *plugin,
if (processes[p].pid > 0)
num_running_processes++;
else
processes[p].plugin->running_state = PLUGIN_STATUS_UNRUN;

{
processes[p].plugin->running_state = PLUGIN_STATUS_UNRUN;
*error = ERR_CANT_FORK;
}
return processes[p].pid;
}

Expand Down
8 changes: 6 additions & 2 deletions src/pluginlaunch.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@
#include "pluginscheduler.h" /* for struct plugins_scheduler_t */

/**
* @brief Error for max. number of concurrent plugins per host reached.
* @brief Error for when it is not possible to fork a new plugin process.
*/
#define ERR_CANT_FORK -2
/**
* @brief Error for when the process table is full
*/
#define ERR_NO_FREE_SLOT -99

Expand All @@ -44,7 +48,7 @@ pluginlaunch_stop (void);

int
plugin_launch (struct scan_globals *, struct scheduler_plugin *,
struct in6_addr *, GSList *, kb_t, kb_t, nvti_t *);
struct in6_addr *, GSList *, kb_t, kb_t, nvti_t *, int *);

void
pluginlaunch_disable_parallel_checks (void);
Expand Down

0 comments on commit b43156e

Please sign in to comment.