svn commit: r303374 - head/sbin/route

Andrey V. Elsukov ae at FreeBSD.org
Wed Jul 27 08:26:36 UTC 2016


Author: ae
Date: Wed Jul 27 08:26:34 2016
New Revision: 303374
URL: https://svnweb.freebsd.org/changeset/base/303374

Log:
  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

Modified:
  head/sbin/route/route.c

Modified: head/sbin/route/route.c
==============================================================================
--- head/sbin/route/route.c	Wed Jul 27 08:11:08 2016	(r303373)
+++ head/sbin/route/route.c	Wed Jul 27 08:26:34 2016	(r303374)
@@ -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 *
 
 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


More information about the svn-src-all mailing list