Due to dropped mbuf in netisr queue route(8) can fall into infinity

loop of reading the rtsock's feed. When it used by some scripts,
this leads to growing number of not finished route(8) instances and
thus growing number of rtsock consumers. Add SIGALRM handler to prevent this.

Reviewed by:	melifaro
Obtained from:	Yandex LLC
MFC after:	2 weeks
Sponsored by:	Yandex LLC
This commit is contained in:
Andrey V. Elsukov 2016-07-27 08:26:34 +00:00
parent a7c6b160b3
commit 6a5d9be9fe
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=303374

View File

@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
#include <err.h>
#include <errno.h>
#include <paths.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@ -144,6 +145,16 @@ static int fiboptlist_range(const char *, struct fibl_head_t *);
static void usage(const char *) __dead2;
#define READ_TIMEOUT 10
static volatile sig_atomic_t stop_read;
static void
stopit(int sig __unused)
{
stop_read = 1;
}
static void
usage(const char *cp)
{
@ -776,6 +787,7 @@ set_metric(char *value, int key)
static void
newroute(int argc, char **argv)
{
struct sigaction sa;
struct hostent *hp;
struct fibl *fl;
char *cmd;
@ -791,6 +803,12 @@ newroute(int argc, char **argv)
hp = NULL;
TAILQ_INIT(&fibl_head);
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = stopit;
if (sigaction(SIGALRM, &sa, 0) == -1)
warn("sigaction SIGALRM");
cmd = argv[0];
if (*cmd != 'g' && *cmd != 's')
shutdown(s, SHUT_RD); /* Don't want to read back our messages */
@ -1541,9 +1559,17 @@ rtmsg(int cmd, int flags, int fib)
return (-1);
}
if (cmd == RTM_GET) {
stop_read = 0;
alarm(READ_TIMEOUT);
do {
l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
} while (l > 0 && (rtm.rtm_seq != rtm_seq || rtm.rtm_pid != pid));
} while (l > 0 && stop_read == 0 &&
(rtm.rtm_seq != rtm_seq || rtm.rtm_pid != pid));
if (stop_read != 0) {
warnx("read from routing socket timed out");
return (-1);
} else
alarm(0);
if (l < 0)
warn("read from routing socket");
else