emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r106203: Fix a memory leak in the bui


From: Chong Yidong
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r106203: Fix a memory leak in the built-in GnuTLS support.
Date: Thu, 27 Oct 2011 14:07:09 +0800
User-agent: Bazaar (2.3.1)

------------------------------------------------------------
revno: 106203
committer: Chong Yidong <address@hidden>
branch nick: trunk
timestamp: Thu 2011-10-27 14:07:09 +0800
message:
  Fix a memory leak in the built-in GnuTLS support.
  * src/gnutls.c (emacs_gnutls_deinit): New function.  Deallocate
  credentials structures as well as calling gnutls_deinit.
  (Fgnutls_deinit, Fgnutls_boot): Use it.
  
  * src/process.c (make_process): Initialize GnuTLS credentials to NULL.
  (deactivate_process): Call emacs_gnutls_deinit.
modified:
  src/ChangeLog
  src/gnutls.c
  src/gnutls.h
  src/process.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2011-10-27 00:59:21 +0000
+++ b/src/ChangeLog     2011-10-27 06:07:09 +0000
@@ -1,3 +1,12 @@
+2011-10-27  Chong Yidong  <address@hidden>
+
+       * gnutls.c (emacs_gnutls_deinit): New function.  Deallocate
+       credentials structures as well as calling gnutls_deinit.
+       (Fgnutls_deinit, Fgnutls_boot): Use it.
+
+       * process.c (make_process): Initialize GnuTLS credentials to NULL.
+       (deactivate_process): Call emacs_gnutls_deinit.
+
 2011-10-27  Juanma Barranquero  <address@hidden>
 
        * image.c (x_create_x_image_and_pixmap):

=== modified file 'src/gnutls.c'
--- a/src/gnutls.c      2011-08-14 09:08:02 +0000
+++ b/src/gnutls.c      2011-10-27 06:07:09 +0000
@@ -464,6 +464,42 @@
   return make_number (err);
 }
 
+Lisp_Object
+emacs_gnutls_deinit (Lisp_Object proc)
+{
+  int log_level;
+
+  CHECK_PROCESS (proc);
+
+  if (XPROCESS (proc)->gnutls_p == 0)
+    return Qnil;
+
+  log_level = XPROCESS (proc)->gnutls_log_level;
+
+  if (XPROCESS (proc)->gnutls_x509_cred)
+    {
+      GNUTLS_LOG (2, log_level, "Deallocating x509 credentials");
+      fn_gnutls_certificate_free_credentials (XPROCESS 
(proc)->gnutls_x509_cred);
+      XPROCESS (proc)->gnutls_x509_cred = NULL;
+    }
+
+  if (XPROCESS (proc)->gnutls_anon_cred)
+    {
+      GNUTLS_LOG (2, log_level, "Deallocating anon credentials");
+      fn_gnutls_anon_free_client_credentials (XPROCESS 
(proc)->gnutls_anon_cred);
+      XPROCESS (proc)->gnutls_anon_cred = NULL;
+    }
+
+  if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT)
+    {
+      fn_gnutls_deinit (XPROCESS (proc)->gnutls_state);
+      GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT - 1;
+    }
+
+  XPROCESS (proc)->gnutls_p = 0;
+  return Qt;
+}
+
 DEFUN ("gnutls-get-initstage", Fgnutls_get_initstage, Sgnutls_get_initstage, 
1, 1, 0,
        doc: /* Return the GnuTLS init stage of process PROC.
 See also `gnutls-boot'.  */)
@@ -551,18 +587,7 @@
 See also `gnutls-init'.  */)
   (Lisp_Object proc)
 {
-  gnutls_session_t state;
-
-  CHECK_PROCESS (proc);
-  state = XPROCESS (proc)->gnutls_state;
-
-  if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT)
-    {
-      fn_gnutls_deinit (state);
-      GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT - 1;
-    }
-
-  return Qt;
+  return emacs_gnutls_deinit (proc);
 }
 
 DEFUN ("gnutls-available-p", Fgnutls_available_p, Sgnutls_available_p, 0, 0, 0,
@@ -733,9 +758,6 @@
 
   c_hostname = SSDATA (hostname);
 
-  state = XPROCESS (proc)->gnutls_state;
-  XPROCESS (proc)->gnutls_p = 1;
-
   if (NUMBERP (loglevel))
     {
       fn_gnutls_global_set_log_function (gnutls_log_function);
@@ -749,40 +771,17 @@
   if (! NILP (Fgnutls_errorp (global_init)))
     return global_init;
 
-  /* deinit and free resources.  */
-  if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_CRED_ALLOC)
-    {
-      GNUTLS_LOG (1, max_log_level, "deallocating credentials");
-
-      if (EQ (type, Qgnutls_x509pki))
-       {
-         GNUTLS_LOG (2, max_log_level, "deallocating x509 credentials");
-         x509_cred = XPROCESS (proc)->gnutls_x509_cred;
-         fn_gnutls_certificate_free_credentials (x509_cred);
-       }
-      else if (EQ (type, Qgnutls_anon))
-       {
-         GNUTLS_LOG (2, max_log_level, "deallocating anon credentials");
-         anon_cred = XPROCESS (proc)->gnutls_anon_cred;
-         fn_gnutls_anon_free_client_credentials (anon_cred);
-       }
-      else
-       {
-         error ("unknown credential type");
-         ret = GNUTLS_EMACS_ERROR_INVALID_TYPE;
-       }
-
-      if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT)
-       {
-         GNUTLS_LOG (1, max_log_level, "deallocating x509 credentials");
-         Fgnutls_deinit (proc);
-       }
-    }
-
+  /* Before allocating new credentials, deallocate any credentials
+     that PROC might already have.  */
+  emacs_gnutls_deinit (proc);
+
+  /* Mark PROC as a GnuTLS process.  */
+  XPROCESS (proc)->gnutls_p = 1;
+  XPROCESS (proc)->gnutls_x509_cred = NULL;
+  XPROCESS (proc)->gnutls_anon_cred = NULL;
   GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_EMPTY;
 
   GNUTLS_LOG (1, max_log_level, "allocating credentials");
-
   if (EQ (type, Qgnutls_x509pki))
     {
       GNUTLS_LOG (2, max_log_level, "allocating x509 credentials");

=== modified file 'src/gnutls.h'
--- a/src/gnutls.h      2011-05-04 23:56:09 +0000
+++ b/src/gnutls.h      2011-10-27 06:07:09 +0000
@@ -60,6 +60,7 @@
 
 extern int emacs_gnutls_record_check_pending (gnutls_session_t state);
 extern void emacs_gnutls_transport_set_errno (gnutls_session_t state, int err);
+extern Lisp_Object emacs_gnutls_deinit (Lisp_Object);
 
 extern void syms_of_gnutls (void);
 

=== modified file 'src/process.c'
--- a/src/process.c     2011-09-09 01:06:52 +0000
+++ b/src/process.c     2011-10-27 06:07:09 +0000
@@ -642,6 +642,8 @@
   p->gnutls_initstage = GNUTLS_STAGE_EMPTY;
   p->gnutls_log_level = 0;
   p->gnutls_p = 0;
+  p->gnutls_x509_cred = NULL;
+  p->gnutls_anon_cred = NULL;
 #endif
 
   /* If name is already in use, modify it until it is unused.  */
@@ -3867,6 +3869,11 @@
   register int inchannel, outchannel;
   register struct Lisp_Process *p = XPROCESS (proc);
 
+#ifdef HAVE_GNUTLS
+  /* Delete GnuTLS structures in PROC, if any.  */
+  emacs_gnutls_deinit (proc);
+#endif /* HAVE_GNUTLS */
+
   inchannel  = p->infd;
   outchannel = p->outfd;
 


reply via email to

[Prev in Thread] Current Thread [Next in Thread]