aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChong Yidong2011-10-27 14:07:09 +0800
committerChong Yidong2011-10-27 14:07:09 +0800
commit9c6c6f495b8469ca5e105f5ddb02a69d1303a106 (patch)
tree0858a59fdd543e7dca46fb6a3ab495c21c417f07 /src
parent15de15c66d96905aa21f1781861067eebd68b24b (diff)
downloademacs-9c6c6f495b8469ca5e105f5ddb02a69d1303a106.tar.gz
emacs-9c6c6f495b8469ca5e105f5ddb02a69d1303a106.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog9
-rw-r--r--src/gnutls.c89
-rw-r--r--src/gnutls.h1
-rw-r--r--src/process.c7
4 files changed, 61 insertions, 45 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 3caecf32049..65995d0ac92 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,12 @@
12011-10-27 Chong Yidong <cyd@gnu.org>
2
3 * gnutls.c (emacs_gnutls_deinit): New function. Deallocate
4 credentials structures as well as calling gnutls_deinit.
5 (Fgnutls_deinit, Fgnutls_boot): Use it.
6
7 * process.c (make_process): Initialize GnuTLS credentials to NULL.
8 (deactivate_process): Call emacs_gnutls_deinit.
9
12011-10-27 Juanma Barranquero <lekktu@gmail.com> 102011-10-27 Juanma Barranquero <lekktu@gmail.com>
2 11
3 * image.c (x_create_x_image_and_pixmap): 12 * image.c (x_create_x_image_and_pixmap):
diff --git a/src/gnutls.c b/src/gnutls.c
index 0743ef3f4ee..f836692198c 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -464,6 +464,42 @@ gnutls_make_error (int err)
464 return make_number (err); 464 return make_number (err);
465} 465}
466 466
467Lisp_Object
468emacs_gnutls_deinit (Lisp_Object proc)
469{
470 int log_level;
471
472 CHECK_PROCESS (proc);
473
474 if (XPROCESS (proc)->gnutls_p == 0)
475 return Qnil;
476
477 log_level = XPROCESS (proc)->gnutls_log_level;
478
479 if (XPROCESS (proc)->gnutls_x509_cred)
480 {
481 GNUTLS_LOG (2, log_level, "Deallocating x509 credentials");
482 fn_gnutls_certificate_free_credentials (XPROCESS (proc)->gnutls_x509_cred);
483 XPROCESS (proc)->gnutls_x509_cred = NULL;
484 }
485
486 if (XPROCESS (proc)->gnutls_anon_cred)
487 {
488 GNUTLS_LOG (2, log_level, "Deallocating anon credentials");
489 fn_gnutls_anon_free_client_credentials (XPROCESS (proc)->gnutls_anon_cred);
490 XPROCESS (proc)->gnutls_anon_cred = NULL;
491 }
492
493 if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT)
494 {
495 fn_gnutls_deinit (XPROCESS (proc)->gnutls_state);
496 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT - 1;
497 }
498
499 XPROCESS (proc)->gnutls_p = 0;
500 return Qt;
501}
502
467DEFUN ("gnutls-get-initstage", Fgnutls_get_initstage, Sgnutls_get_initstage, 1, 1, 0, 503DEFUN ("gnutls-get-initstage", Fgnutls_get_initstage, Sgnutls_get_initstage, 1, 1, 0,
468 doc: /* Return the GnuTLS init stage of process PROC. 504 doc: /* Return the GnuTLS init stage of process PROC.
469See also `gnutls-boot'. */) 505See also `gnutls-boot'. */)
@@ -551,18 +587,7 @@ DEFUN ("gnutls-deinit", Fgnutls_deinit, Sgnutls_deinit, 1, 1, 0,
551See also `gnutls-init'. */) 587See also `gnutls-init'. */)
552 (Lisp_Object proc) 588 (Lisp_Object proc)
553{ 589{
554 gnutls_session_t state; 590 return emacs_gnutls_deinit (proc);
555
556 CHECK_PROCESS (proc);
557 state = XPROCESS (proc)->gnutls_state;
558
559 if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT)
560 {
561 fn_gnutls_deinit (state);
562 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT - 1;
563 }
564
565 return Qt;
566} 591}
567 592
568DEFUN ("gnutls-available-p", Fgnutls_available_p, Sgnutls_available_p, 0, 0, 0, 593DEFUN ("gnutls-available-p", Fgnutls_available_p, Sgnutls_available_p, 0, 0, 0,
@@ -733,9 +758,6 @@ one trustfile (usually a CA bundle). */)
733 758
734 c_hostname = SSDATA (hostname); 759 c_hostname = SSDATA (hostname);
735 760
736 state = XPROCESS (proc)->gnutls_state;
737 XPROCESS (proc)->gnutls_p = 1;
738
739 if (NUMBERP (loglevel)) 761 if (NUMBERP (loglevel))
740 { 762 {
741 fn_gnutls_global_set_log_function (gnutls_log_function); 763 fn_gnutls_global_set_log_function (gnutls_log_function);
@@ -749,40 +771,17 @@ one trustfile (usually a CA bundle). */)
749 if (! NILP (Fgnutls_errorp (global_init))) 771 if (! NILP (Fgnutls_errorp (global_init)))
750 return global_init; 772 return global_init;
751 773
752 /* deinit and free resources. */ 774 /* Before allocating new credentials, deallocate any credentials
753 if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_CRED_ALLOC) 775 that PROC might already have. */
754 { 776 emacs_gnutls_deinit (proc);
755 GNUTLS_LOG (1, max_log_level, "deallocating credentials");
756
757 if (EQ (type, Qgnutls_x509pki))
758 {
759 GNUTLS_LOG (2, max_log_level, "deallocating x509 credentials");
760 x509_cred = XPROCESS (proc)->gnutls_x509_cred;
761 fn_gnutls_certificate_free_credentials (x509_cred);
762 }
763 else if (EQ (type, Qgnutls_anon))
764 {
765 GNUTLS_LOG (2, max_log_level, "deallocating anon credentials");
766 anon_cred = XPROCESS (proc)->gnutls_anon_cred;
767 fn_gnutls_anon_free_client_credentials (anon_cred);
768 }
769 else
770 {
771 error ("unknown credential type");
772 ret = GNUTLS_EMACS_ERROR_INVALID_TYPE;
773 }
774
775 if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT)
776 {
777 GNUTLS_LOG (1, max_log_level, "deallocating x509 credentials");
778 Fgnutls_deinit (proc);
779 }
780 }
781 777
778 /* Mark PROC as a GnuTLS process. */
779 XPROCESS (proc)->gnutls_p = 1;
780 XPROCESS (proc)->gnutls_x509_cred = NULL;
781 XPROCESS (proc)->gnutls_anon_cred = NULL;
782 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_EMPTY; 782 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_EMPTY;
783 783
784 GNUTLS_LOG (1, max_log_level, "allocating credentials"); 784 GNUTLS_LOG (1, max_log_level, "allocating credentials");
785
786 if (EQ (type, Qgnutls_x509pki)) 785 if (EQ (type, Qgnutls_x509pki))
787 { 786 {
788 GNUTLS_LOG (2, max_log_level, "allocating x509 credentials"); 787 GNUTLS_LOG (2, max_log_level, "allocating x509 credentials");
diff --git a/src/gnutls.h b/src/gnutls.h
index e2a9bc9eaea..5ec6fb76c01 100644
--- a/src/gnutls.h
+++ b/src/gnutls.h
@@ -60,6 +60,7 @@ emacs_gnutls_read (struct Lisp_Process *proc, char *buf, EMACS_INT nbyte);
60 60
61extern int emacs_gnutls_record_check_pending (gnutls_session_t state); 61extern int emacs_gnutls_record_check_pending (gnutls_session_t state);
62extern void emacs_gnutls_transport_set_errno (gnutls_session_t state, int err); 62extern void emacs_gnutls_transport_set_errno (gnutls_session_t state, int err);
63extern Lisp_Object emacs_gnutls_deinit (Lisp_Object);
63 64
64extern void syms_of_gnutls (void); 65extern void syms_of_gnutls (void);
65 66
diff --git a/src/process.c b/src/process.c
index 90ad9c21681..3daa55b259e 100644
--- a/src/process.c
+++ b/src/process.c
@@ -642,6 +642,8 @@ make_process (Lisp_Object name)
642 p->gnutls_initstage = GNUTLS_STAGE_EMPTY; 642 p->gnutls_initstage = GNUTLS_STAGE_EMPTY;
643 p->gnutls_log_level = 0; 643 p->gnutls_log_level = 0;
644 p->gnutls_p = 0; 644 p->gnutls_p = 0;
645 p->gnutls_x509_cred = NULL;
646 p->gnutls_anon_cred = NULL;
645#endif 647#endif
646 648
647 /* If name is already in use, modify it until it is unused. */ 649 /* If name is already in use, modify it until it is unused. */
@@ -3867,6 +3869,11 @@ deactivate_process (Lisp_Object proc)
3867 register int inchannel, outchannel; 3869 register int inchannel, outchannel;
3868 register struct Lisp_Process *p = XPROCESS (proc); 3870 register struct Lisp_Process *p = XPROCESS (proc);
3869 3871
3872#ifdef HAVE_GNUTLS
3873 /* Delete GnuTLS structures in PROC, if any. */
3874 emacs_gnutls_deinit (proc);
3875#endif /* HAVE_GNUTLS */
3876
3870 inchannel = p->infd; 3877 inchannel = p->infd;
3871 outchannel = p->outfd; 3878 outchannel = p->outfd;
3872 3879