Fix memory leak on (Gnu)TLS close.
authorHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
Wed, 23 Nov 2016 11:02:26 +0000 (12:02 +0100)
committerHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
Wed, 23 Nov 2016 13:17:41 +0000 (14:17 +0100)
This leak doesn't show up under normal operation, as the process
normally dies right after closing the session.

But during callout repetitive TLS sessions are opened and closed from
the same process (the process receiving the message). Depending on
the amount of RAM and the number of callouts the same process does,
this may be a problem. (On an amd64 machine with 4GB RAM, at about 1000
recipients the memory is exhausted.)

src/src/tls-gnu.c

index 0dead1c18a6487185e67e76ada5bc10ea874b80a..10bfaca32ecf888f9c1e65ecf1ff13fe66c872b7 100644 (file)
@@ -1836,6 +1836,7 @@ if (rc != GNUTLS_E_SUCCESS)
     tls_error(US"gnutls_handshake", gnutls_strerror(rc), NULL);
     (void) gnutls_alert_send_appropriate(state->session, rc);
     gnutls_deinit(state->session);
     tls_error(US"gnutls_handshake", gnutls_strerror(rc), NULL);
     (void) gnutls_alert_send_appropriate(state->session, rc);
     gnutls_deinit(state->session);
+    gnutls_certificate_free_credentials(state->x509_cred);
     millisleep(500);
     shutdown(state->fd_out, SHUT_WR);
     for (rc = 1024; fgetc(smtp_in) != EOF && rc > 0; ) rc--;   /* drain skt */
     millisleep(500);
     shutdown(state->fd_out, SHUT_WR);
     for (rc = 1024; fgetc(smtp_in) != EOF && rc > 0; ) rc--;   /* drain skt */
@@ -2130,6 +2131,8 @@ if (shutdown)
   }
 
 gnutls_deinit(state->session);
   }
 
 gnutls_deinit(state->session);
+gnutls_certificate_free_credentials(state->x509_cred);
+
 
 state->tlsp->active = -1;
 memcpy(state, &exim_gnutls_state_init, sizeof(exim_gnutls_state_init));
 
 state->tlsp->active = -1;
 memcpy(state, &exim_gnutls_state_init, sizeof(exim_gnutls_state_init));
@@ -2199,6 +2202,8 @@ if (state->xfer_buffer_lwm >= state->xfer_buffer_hwm)
     receive_smtp_buffered = smtp_buffered;
 
     gnutls_deinit(state->session);
     receive_smtp_buffered = smtp_buffered;
 
     gnutls_deinit(state->session);
+    gnutls_certificate_free_credentials(state->x509_cred);
+
     state->session = NULL;
     state->tlsp->active = -1;
     state->tlsp->bits = 0;
     state->session = NULL;
     state->tlsp->active = -1;
     state->tlsp->bits = 0;