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