From 40fa3929fc61ff095cd56c3481e51ad9e4e3716e Mon Sep 17 00:00:00 2001 From: deraadt Date: Sun, 14 Nov 2021 18:47:43 +0000 Subject: [PATCH] use ppoll() instead of pselect() with djm --- usr.bin/ssh/sshd.c | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/usr.bin/ssh/sshd.c b/usr.bin/ssh/sshd.c index ce419fe5ae4..78f5d647f60 100644 --- a/usr.bin/ssh/sshd.c +++ b/usr.bin/ssh/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.578 2021/07/19 02:21:50 dtucker Exp $ */ +/* $OpenBSD: sshd.c,v 1.579 2021/11/14 18:47:43 deraadt Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -1079,8 +1080,8 @@ server_listen(void) static void server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) { - fd_set *fdset; - int i, j, ret, maxfd; + struct pollfd *pfd = NULL; + int i, j, ret; int ostartups = -1, startups = 0, listening = 0, lameduck = 0; int startup_p[2] = { -1 , -1 }; char c = 0; @@ -1090,11 +1091,6 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) sigset_t nsigset, osigset; /* setup fd set for accept */ - fdset = NULL; - maxfd = 0; - for (i = 0; i < num_listen_socks; i++) - if (listen_socks[i] > maxfd) - maxfd = listen_socks[i]; /* pipes connected to unauthenticated child sshd processes */ startup_pipes = xcalloc(options.max_startups, sizeof(int)); startup_flags = xcalloc(options.max_startups, sizeof(int)); @@ -1104,7 +1100,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) /* * Prepare signal mask that we use to block signals that might set * received_sigterm or received_sighup, so that we are guaranteed - * to immediately wake up the pselect if a signal is received after + * to immediately wake up the ppoll if a signal is received after * the flag is checked. */ sigemptyset(&nsigset); @@ -1113,6 +1109,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) sigaddset(&nsigset, SIGTERM); sigaddset(&nsigset, SIGQUIT); + pfd = xcalloc(num_listen_socks + options.max_startups, + sizeof(struct pollfd)); + /* * Stay listening for connections until the system crashes or * the daemon is killed with a signal. @@ -1144,27 +1143,29 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) sighup_restart(); } } - free(fdset); - fdset = xcalloc(howmany(maxfd + 1, NFDBITS), - sizeof(fd_mask)); - for (i = 0; i < num_listen_socks; i++) - FD_SET(listen_socks[i], fdset); - for (i = 0; i < options.max_startups; i++) + for (i = 0; i < num_listen_socks; i++) { + pfd[i].fd = listen_socks[i]; + pfd[i].events = POLLIN; + } + for (i = 0; i < options.max_startups; i++) { + pfd[num_listen_socks+i].fd = startup_pipes[i]; if (startup_pipes[i] != -1) - FD_SET(startup_pipes[i], fdset); + pfd[num_listen_socks+i].events = POLLIN; + } /* Wait until a connection arrives or a child exits. */ - ret = pselect(maxfd+1, fdset, NULL, NULL, NULL, &osigset); + ret = ppoll(pfd, num_listen_socks + options.max_startups, + NULL, &osigset); if (ret == -1 && errno != EINTR) - error("pselect: %.100s", strerror(errno)); + error("ppoll: %.100s", strerror(errno)); sigprocmask(SIG_SETMASK, &osigset, NULL); if (ret == -1) continue; for (i = 0; i < options.max_startups; i++) { if (startup_pipes[i] == -1 || - !FD_ISSET(startup_pipes[i], fdset)) + !(pfd[num_listen_socks+i].revents & POLLIN)) continue; switch (read(startup_pipes[i], &c, sizeof(c))) { case -1: @@ -1195,7 +1196,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) } } for (i = 0; i < num_listen_socks; i++) { - if (!FD_ISSET(listen_socks[i], fdset)) + if (!(pfd[i].revents & POLLIN)) continue; fromlen = sizeof(from); *newsock = accept(listen_socks[i], @@ -1232,8 +1233,6 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) for (j = 0; j < options.max_startups; j++) if (startup_pipes[j] == -1) { startup_pipes[j] = startup_p[0]; - if (maxfd < startup_p[0]) - maxfd = startup_p[0]; startups++; startup_flags[j] = 1; break; @@ -1261,6 +1260,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) send_rexec_state(config_s[0], cfg); close(config_s[0]); } + free(pfd); return; } @@ -1301,6 +1301,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) (void)atomicio(vwrite, startup_pipe, "\0", 1); } + free(pfd); return; } -- 2.20.1