[openssh-commits] [openssh] 02/05: upstream: mask SIGINT/TERM/QUIT/HUP before checking quit_pending

git+noreply at mindrot.org git+noreply at mindrot.org
Thu Oct 12 13:22:08 AEDT 2023


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit a612b93de5d86e955bfb6e24278f621118eea500
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Thu Oct 12 02:12:53 2023 +0000

    upstream: mask SIGINT/TERM/QUIT/HUP before checking quit_pending
    
    and use ppoll() to unmask them in the mainloop. Avoids race condition between
    signaling ssh to exit and polling. bz3531; ok dtucker
    
    OpenBSD-Commit-ID: 5c14e1aabcddedb95cdf972283d9c0d5083229e7
---
 clientloop.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/clientloop.c b/clientloop.c
index e8131637..8e323a60 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.c,v 1.399 2023/10/11 22:42:26 djm Exp $ */
+/* $OpenBSD: clientloop.c,v 1.400 2023/10/12 02:12:53 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -681,7 +681,7 @@ obfuscate_keystroke_timing(struct ssh *ssh, struct timespec *timeout,
 static void
 client_wait_until_can_do_something(struct ssh *ssh, struct pollfd **pfdp,
     u_int *npfd_allocp, u_int *npfd_activep, int channel_did_enqueue,
-    int *conn_in_readyp, int *conn_out_readyp)
+    sigset_t *sigsetp, int *conn_in_readyp, int *conn_out_readyp)
 {
 	struct timespec timeout;
 	int ret, oready;
@@ -728,7 +728,7 @@ client_wait_until_can_do_something(struct ssh *ssh, struct pollfd **pfdp,
 		    ssh_packet_get_rekey_timeout(ssh));
 	}
 
-	ret = ppoll(*pfdp, *npfd_activep, ptimeout_get_tsp(&timeout), NULL);
+	ret = ppoll(*pfdp, *npfd_activep, ptimeout_get_tsp(&timeout), sigsetp);
 
 	if (ret == -1) {
 		/*
@@ -1448,6 +1448,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
 	int channel_did_enqueue = 0, r, len;
 	u_int64_t ibytes, obytes;
 	int conn_in_ready, conn_out_ready;
+	sigset_t bsigset, osigset;
 
 	debug("Entering interactive session.");
 	session_ident = ssh2_chan_id;
@@ -1533,6 +1534,13 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
 
 	schedule_server_alive_check();
 
+	if (sigemptyset(&bsigset) == -1 ||
+	    sigaddset(&bsigset, SIGHUP) == -1 ||
+	    sigaddset(&bsigset, SIGINT) == -1 ||
+	    sigaddset(&bsigset, SIGQUIT) == -1 ||
+	    sigaddset(&bsigset, SIGTERM) == -1)
+		error_f("bsigset setup: %s", strerror(errno));
+
 	/* Main loop of the client for the interactive session mode. */
 	while (!quit_pending) {
 		channel_did_enqueue = 0;
@@ -1564,17 +1572,20 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
 			 * message about it to the server if so.
 			 */
 			client_check_window_change(ssh);
-
-			if (quit_pending)
-				break;
 		}
 		/*
 		 * Wait until we have something to do (something becomes
 		 * available on one of the descriptors).
 		 */
+		if (sigprocmask(SIG_BLOCK, &bsigset, &osigset) == -1)
+			error_f("bsigset sigprocmask: %s", strerror(errno));
+		if (quit_pending)
+			break;
 		client_wait_until_can_do_something(ssh, &pfd, &npfd_alloc,
-		    &npfd_active, channel_did_enqueue,
+		    &npfd_active, channel_did_enqueue, &osigset,
 		    &conn_in_ready, &conn_out_ready);
+		if (sigprocmask(SIG_UNBLOCK, &bsigset, &osigset) == -1)
+			error_f("osigset sigprocmask: %s", strerror(errno));
 
 		if (quit_pending)
 			break;

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list