summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
authorae <ae@FreeBSD.org>2016-08-14 20:19:47 +0000
committerae <ae@FreeBSD.org>2016-08-14 20:19:47 +0000
commitb30706fc4deb4310a6e49820c9282c48f978b931 (patch)
tree71c18053e9fc6dc8c820825e4e90595738b2cd5d /sbin
parentb2936a4ebf9b21ab7dde3cef02c995a53d353797 (diff)
downloadFreeBSD-src-b30706fc4deb4310a6e49820c9282c48f978b931.zip
FreeBSD-src-b30706fc4deb4310a6e49820c9282c48f978b931.tar.gz
MFC r303374:
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.
Diffstat (limited to 'sbin')
-rw-r--r--sbin/route/route.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/sbin/route/route.c b/sbin/route/route.c
index a357a4d..ee312a4 100644
--- a/sbin/route/route.c
+++ b/sbin/route/route.c
@@ -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
OpenPOWER on IntegriCloud