CVE-2020-28013: Heap buffer overflow in parse_fix_phrase()
[exim.git] / src / src / tls-gnu.c
index 875c82efa16976ba457e227a0e046c3c50163777..6ee603595dbd3c3ebbd1b7ff89b84865c6e25a04 100644 (file)
@@ -545,7 +545,10 @@ else
 
 /* peercert is set in peer_status() */
 tlsp->peerdn = state->peerdn;
-tlsp->sni =    state->received_sni;
+
+/* do not corrupt sni sent by client; record sni rxd by server */
+if (!state->host)
+  tlsp->sni = state->received_sni;
 
 /* record our certificate */
   {
@@ -2863,7 +2866,7 @@ DEBUG(D_tls) debug_printf("initialising GnuTLS as a client on fd %d\n", cctx->so
 /* If dane is flagged, have either request or require dane for this host, and
 a TLSA record found.  Therefore, dane verify required.  Which implies cert must
 be requested and supplied, dane verify must pass, and cert verify irrelevant
-(incl.  hostnames), and (caller handled) require_tls */
+(incl.  hostnames), and (caller handled) require_tls and sni=$domain */
 
 if (conn_args->dane && ob->dane_require_tls_ciphers)
   {
@@ -2890,6 +2893,7 @@ if (!cipher_list)
       cipher_list, &state, tlsp, errstr) != OK)
     return FALSE;
 
+
 #ifdef MEASURE_TIMING
   report_time_since(&t0, US"client tls_init (delta)");
 #endif
@@ -3158,6 +3162,7 @@ DEBUG(D_tls) debug_printf("Calling gnutls_record_recv(session=%p, buffer=%p, buf
 sigalrm_seen = FALSE;
 if (smtp_receive_timeout > 0) ALARM(smtp_receive_timeout);
 
+errno = 0;
 do
   inbytes = gnutls_record_recv(state->session, state->xfer_buffer,
     MIN(ssl_xfer_buffer_size, lim));
@@ -3318,6 +3323,7 @@ DEBUG(D_tls)
   debug_printf("Calling gnutls_record_recv(session=%p, buffer=%p, len=" SIZE_T_FMT ")\n",
       state->session, buff, len);
 
+errno = 0;
 do
   inbytes = gnutls_record_recv(state->session, buff, len);
 while (inbytes == GNUTLS_E_AGAIN);
@@ -3381,6 +3387,7 @@ while (left > 0)
   DEBUG(D_tls) debug_printf("gnutls_record_send(session=%p, buffer=%p, left=" SIZE_T_FMT ")\n",
       state->session, buff, left);
 
+  errno = 0;
   do
     outbytes = gnutls_record_send(state->session, buff, left);
   while (outbytes == GNUTLS_E_AGAIN);