aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorMattias EngdegÄrd2021-07-12 13:58:28 +0200
committerMattias EngdegÄrd2021-07-13 19:07:41 +0200
commit7a803ecd3d455999cfc9266fa219d58109fac786 (patch)
treee24f82c78991b57c2144240a2d831833e240ae60 /src/process.c
parenta41f585bf111b239601ca7d915994fed600852af (diff)
downloademacs-7a803ecd3d455999cfc9266fa219d58109fac786.tar.gz
emacs-7a803ecd3d455999cfc9266fa219d58109fac786.zip
Block TLS handshake until TCP connection established
If a TLS handshake is attempted before the completion of an asynchronous TCP connection has been ascertained, our local state will not be set up correctly for further progress and the sentinel "open" event will never be sent. This can occur if sufficient time passes after the initiation of an async TCP connection so that by the time `wait_reading_process_output` is called, the connection has already been established on the TCP level. This somewhat timing-sensitive bug has plagued HTTPS connections on some platforms, notably macOS, for a long time (bug#49449). * src/process.c (wait_reading_process_output): Gate the TLS handshake by the NON_BLOCKING_CONNECT_FD flag. The flag will be cleared as soon as the TCP socket is found to be writable. * test/src/process-tests.el (process-async-https-with-delay): New test.
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/process.c b/src/process.c
index b8c3e4ecfbc..c3186eed750 100644
--- a/src/process.c
+++ b/src/process.c
@@ -5232,7 +5232,10 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5232#ifdef HAVE_GNUTLS 5232#ifdef HAVE_GNUTLS
5233 /* Continue TLS negotiation. */ 5233 /* Continue TLS negotiation. */
5234 if (p->gnutls_initstage == GNUTLS_STAGE_HANDSHAKE_TRIED 5234 if (p->gnutls_initstage == GNUTLS_STAGE_HANDSHAKE_TRIED
5235 && p->is_non_blocking_client) 5235 && p->is_non_blocking_client
5236 /* Don't proceed until we have established a connection. */
5237 && !(fd_callback_info[p->outfd].flags
5238 & NON_BLOCKING_CONNECT_FD))
5236 { 5239 {
5237 gnutls_try_handshake (p); 5240 gnutls_try_handshake (p);
5238 p->gnutls_handshakes_tried++; 5241 p->gnutls_handshakes_tried++;