Blame SOURCES/0007-libndp-ndptool-use-poll-instead-of-select.patch

c48acd
From 682b0ccabdc7970f89544c0d19477515583a5f5b Mon Sep 17 00:00:00 2001
c48acd
From: Beniamino Galvani <bgalvani@redhat.com>
c48acd
Date: Thu, 25 Feb 2021 14:38:16 +0100
c48acd
Subject: [PATCH] libndp,ndptool: use poll() instead of select()
c48acd
c48acd
select() doesn't support file descriptors greater than 1023. If the
c48acd
program has many files open, the socket descriptor can be > 1023 and
c48acd
then FD_SET(fd, &rfds) causes a buffer overflow.
c48acd
c48acd
Switch to poll() and ppoll() which don't have this limitation.
c48acd
c48acd
Signed-off-by: Beniamino Galvani <bgalvani@redhat.com>
c48acd
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
c48acd
---
c48acd
 libndp/libndp.c   | 20 +++++++++-----------
c48acd
 utils/Makefile.am |  2 +-
c48acd
 utils/Makefile.in |  2 +-
c48acd
 utils/ndptool.c   | 22 +++++++++-------------
c48acd
 4 files changed, 20 insertions(+), 26 deletions(-)
c48acd
c48acd
diff --git a/libndp/libndp.c b/libndp/libndp.c
c48acd
index 06a3d23..6314717 100644
c48acd
--- a/libndp/libndp.c
c48acd
+++ b/libndp/libndp.c
c48acd
@@ -25,7 +25,7 @@
c48acd
 #include <errno.h>
c48acd
 #include <ctype.h>
c48acd
 #include <sys/socket.h>
c48acd
-#include <sys/select.h>
c48acd
+#include <poll.h>
c48acd
 #include <netinet/in.h>
c48acd
 #include <netinet/icmp6.h>
c48acd
 #include <arpa/inet.h>
c48acd
@@ -2107,22 +2107,20 @@ int ndp_call_eventfd_handler(struct ndp *ndp)
c48acd
 NDP_EXPORT
c48acd
 int ndp_callall_eventfd_handler(struct ndp *ndp)
c48acd
 {
c48acd
-	fd_set rfds;
c48acd
-	int fdmax;
c48acd
-	struct timeval tv;
c48acd
-	int fd = ndp_get_eventfd(ndp);
c48acd
+	struct pollfd pfd;
c48acd
 	int ret;
c48acd
 	int err;
c48acd
 
c48acd
-	memset(&tv, 0, sizeof(tv));
c48acd
-	FD_ZERO(&rfds);
c48acd
-	FD_SET(fd, &rfds);
c48acd
-	fdmax = fd + 1;
c48acd
+	pfd = (struct pollfd) {
c48acd
+		.fd = ndp_get_eventfd(ndp),
c48acd
+		.events = POLLIN,
c48acd
+	};
c48acd
+
c48acd
 	while (true) {
c48acd
-		ret = select(fdmax, &rfds, NULL, NULL, &tv;;
c48acd
+		ret = poll(&pfd, 1, 0);
c48acd
 		if (ret == -1)
c48acd
 			return -errno;
c48acd
-		if (!FD_ISSET(fd, &rfds))
c48acd
+		if (!(pfd.revents & POLLIN))
c48acd
 			return 0;
c48acd
 		err = ndp_call_eventfd_handler(ndp);
c48acd
 		if (err)
c48acd
diff --git a/utils/Makefile.am b/utils/Makefile.am
c48acd
index cca00c2..75e452c 100644
c48acd
--- a/utils/Makefile.am
c48acd
+++ b/utils/Makefile.am
c48acd
@@ -2,7 +2,7 @@ MAINTAINERCLEANFILES = Makefile.in
c48acd
 
c48acd
 ACLOCAL_AMFLAGS = -I m4
c48acd
 
c48acd
-AM_CFLAGS = -I${top_srcdir}/include
c48acd
+AM_CFLAGS = -I${top_srcdir}/include -D_GNU_SOURCE
c48acd
 
c48acd
 ndptool_LDADD = $(top_builddir)/libndp/libndp.la
c48acd
 
c48acd
diff --git a/utils/Makefile.in b/utils/Makefile.in
c48acd
index e339b19..d81de50 100644
c48acd
--- a/utils/Makefile.in
c48acd
+++ b/utils/Makefile.in
c48acd
@@ -294,7 +294,7 @@ top_builddir = @top_builddir@
c48acd
 top_srcdir = @top_srcdir@
c48acd
 MAINTAINERCLEANFILES = Makefile.in
c48acd
 ACLOCAL_AMFLAGS = -I m4
c48acd
-AM_CFLAGS = -I${top_srcdir}/include
c48acd
+AM_CFLAGS = -I${top_srcdir}/include -D_GNU_SOURCE
c48acd
 ndptool_LDADD = $(top_builddir)/libndp/libndp.la
c48acd
 ndptool_SOURCES = ndptool.c
c48acd
 all: all-am
c48acd
diff --git a/utils/ndptool.c b/utils/ndptool.c
c48acd
index 662ff01..618f167 100644
c48acd
--- a/utils/ndptool.c
c48acd
+++ b/utils/ndptool.c
c48acd
@@ -28,7 +28,7 @@
c48acd
 #include <arpa/inet.h>
c48acd
 #include <errno.h>
c48acd
 #include <ndp.h>
c48acd
-#include <sys/select.h>
c48acd
+#include <poll.h>
c48acd
 
c48acd
 enum verbosity_level {
c48acd
 	VERB1,
c48acd
@@ -59,13 +59,10 @@ static void empty_signal_handler(int signal)
c48acd
 
c48acd
 static int run_main_loop(struct ndp *ndp)
c48acd
 {
c48acd
-	fd_set rfds;
c48acd
-	fd_set rfds_tmp;
c48acd
-	int fdmax;
c48acd
+	struct pollfd pfd;
c48acd
 	int ret;
c48acd
 	struct sigaction siginfo;
c48acd
 	sigset_t mask;
c48acd
-	int ndp_fd;
c48acd
 	int err = 0;
c48acd
 
c48acd
 	sigemptyset(&siginfo.sa_mask);
c48acd
@@ -100,23 +97,22 @@ static int run_main_loop(struct ndp *ndp)
c48acd
 
c48acd
 	sigemptyset(&mask);
c48acd
 
c48acd
-	FD_ZERO(&rfds);
c48acd
-	ndp_fd = ndp_get_eventfd(ndp);
c48acd
-	FD_SET(ndp_fd, &rfds);
c48acd
-	fdmax = ndp_fd + 1;
c48acd
+	pfd = (struct pollfd) {
c48acd
+		.fd = ndp_get_eventfd(ndp),
c48acd
+		.events = POLLIN,
c48acd
+	};
c48acd
 
c48acd
 	for (;;) {
c48acd
-		rfds_tmp = rfds;
c48acd
-		ret = pselect(fdmax, &rfds_tmp, NULL, NULL, NULL, &mask);
c48acd
+		ret = ppoll(&pfd, 1, NULL, &mask);
c48acd
 		if (ret == -1) {
c48acd
 			if (errno == EINTR) {
c48acd
 				goto out;
c48acd
 			}
c48acd
-			pr_err("Select failed\n");
c48acd
+			pr_err("Poll failed\n");
c48acd
 			err = -errno;
c48acd
 			goto out;
c48acd
 		}
c48acd
-		if (FD_ISSET(ndp_fd, &rfds_tmp)) {
c48acd
+		if (pfd.revents & POLLIN) {
c48acd
 			err = ndp_call_eventfd_handler(ndp);
c48acd
 			if (err) {
c48acd
 				pr_err("ndp eventfd handler call failed\n");
c48acd
-- 
c48acd
2.26.2
c48acd