aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey V. Elsukov <ae@FreeBSD.org>2016-07-27 08:26:34 +0000
committerAndrey V. Elsukov <ae@FreeBSD.org>2016-07-27 08:26:34 +0000
commit6a5d9be9fe56f8cffa872e4af2ca8a817fd557a5 (patch)
tree3358aa662bf910929e4f41e2b5ce957fc99730c3
parenta7c6b160b3cf55c33913907d2efe3d851e304b65 (diff)
downloadsrc-6a5d9be9fe56f8cffa872e4af2ca8a817fd557a5.tar.gz
src-6a5d9be9fe56f8cffa872e4af2ca8a817fd557a5.zip
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
Notes
Notes: svn path=/head/; revision=303374
-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 a357a4d03851..ee312a4d36cb 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