aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2014-12-27 23:44:25 -0800
committerPaul Eggert2014-12-27 23:45:46 -0800
commitb54f5721bfb6bf21cac5402cf34a8130e11bfb70 (patch)
tree69b72a16ac4ad7522ef061870f85c95b1e60caac /src
parent433af0a06089885f5a57ef0f3e7d6283e8d51bd5 (diff)
downloademacs-b54f5721bfb6bf21cac5402cf34a8130e11bfb70.tar.gz
emacs-b54f5721bfb6bf21cac5402cf34a8130e11bfb70.zip
Port memory-full checking to GnuTLS 3.3
Instead of using gnutls_global_set_mem_functions, check every call to a GnuTLS function that might return an indication of memory exhaustion. Suggested by Dmitry Antipov in: http://lists.gnu.org/archive/html/emacs-devel/2014-12/msg02056.html * src/gnutls.c (gnutls_global_set_mem_functions) [WINDOWSNT]: Remove. (init_gnutls_functions): Do not load gnutls_global_set_mem_functions. (fn_gnutls_global_set_mem_functions) [!WINDOWSNT]: Remove. All uses removed. (check_memory_full): New function. (emacs_gnutls_handshake, emacs_gnutls_handle_error) (gnutls_make_error, Fgnutls_boot): Use it. (emacs_gnutls_global_init): Avoid gnutls_global_set_mem_functions.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog16
-rw-r--r--src/gnutls.c40
2 files changed, 41 insertions, 15 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 2df83082fbd..3ea60571a15 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,19 @@
12014-12-28 Paul Eggert <eggert@Penguin.CS.UCLA.EDU>
2
3 Port memory-full checking to GnuTLS 3.3
4 Instead of using gnutls_global_set_mem_functions, check every call
5 to a GnuTLS function that might return an indication of memory
6 exhaustion. Suggested by Dmitry Antipov in:
7 http://lists.gnu.org/archive/html/emacs-devel/2014-12/msg02056.html
8 * gnutls.c (gnutls_global_set_mem_functions) [WINDOWSNT]: Remove.
9 (init_gnutls_functions): Do not load gnutls_global_set_mem_functions.
10 (fn_gnutls_global_set_mem_functions) [!WINDOWSNT]: Remove.
11 All uses removed.
12 (check_memory_full): New function.
13 (emacs_gnutls_handshake, emacs_gnutls_handle_error)
14 (gnutls_make_error, Fgnutls_boot): Use it.
15 (emacs_gnutls_global_init): Avoid gnutls_global_set_mem_functions.
16
12014-12-25 Eli Zaretskii <eliz@gnu.org> 172014-12-25 Eli Zaretskii <eliz@gnu.org>
2 18
3 * xdisp.c (set_iterator_to_next) <GET_FROM_STRING>: Limit search in 19 * xdisp.c (set_iterator_to_next) <GET_FROM_STRING>: Limit search in
diff --git a/src/gnutls.c b/src/gnutls.c
index ffa3c982572..f093568bb54 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -116,10 +116,6 @@ DEF_GNUTLS_FN (void, gnutls_global_set_log_function, (gnutls_log_func));
116DEF_GNUTLS_FN (void, gnutls_global_set_audit_log_function, (gnutls_audit_log_func)); 116DEF_GNUTLS_FN (void, gnutls_global_set_audit_log_function, (gnutls_audit_log_func));
117#endif 117#endif
118DEF_GNUTLS_FN (void, gnutls_global_set_log_level, (int)); 118DEF_GNUTLS_FN (void, gnutls_global_set_log_level, (int));
119DEF_GNUTLS_FN (void, gnutls_global_set_mem_functions,
120 (gnutls_alloc_function, gnutls_alloc_function,
121 gnutls_is_secure_function, gnutls_realloc_function,
122 gnutls_free_function));
123DEF_GNUTLS_FN (int, gnutls_handshake, (gnutls_session_t)); 119DEF_GNUTLS_FN (int, gnutls_handshake, (gnutls_session_t));
124DEF_GNUTLS_FN (int, gnutls_init, (gnutls_session_t *, unsigned int)); 120DEF_GNUTLS_FN (int, gnutls_init, (gnutls_session_t *, unsigned int));
125DEF_GNUTLS_FN (int, gnutls_priority_set_direct, 121DEF_GNUTLS_FN (int, gnutls_priority_set_direct,
@@ -184,7 +180,6 @@ init_gnutls_functions (void)
184 LOAD_GNUTLS_FN (library, gnutls_global_set_audit_log_function); 180 LOAD_GNUTLS_FN (library, gnutls_global_set_audit_log_function);
185#endif 181#endif
186 LOAD_GNUTLS_FN (library, gnutls_global_set_log_level); 182 LOAD_GNUTLS_FN (library, gnutls_global_set_log_level);
187 LOAD_GNUTLS_FN (library, gnutls_global_set_mem_functions);
188 LOAD_GNUTLS_FN (library, gnutls_handshake); 183 LOAD_GNUTLS_FN (library, gnutls_handshake);
189 LOAD_GNUTLS_FN (library, gnutls_init); 184 LOAD_GNUTLS_FN (library, gnutls_init);
190 LOAD_GNUTLS_FN (library, gnutls_priority_set_direct); 185 LOAD_GNUTLS_FN (library, gnutls_priority_set_direct);
@@ -244,7 +239,6 @@ init_gnutls_functions (void)
244#define fn_gnutls_global_set_audit_log_function gnutls_global_set_audit_log_function 239#define fn_gnutls_global_set_audit_log_function gnutls_global_set_audit_log_function
245#endif 240#endif
246#define fn_gnutls_global_set_log_level gnutls_global_set_log_level 241#define fn_gnutls_global_set_log_level gnutls_global_set_log_level
247#define fn_gnutls_global_set_mem_functions gnutls_global_set_mem_functions
248#define fn_gnutls_handshake gnutls_handshake 242#define fn_gnutls_handshake gnutls_handshake
249#define fn_gnutls_init gnutls_init 243#define fn_gnutls_init gnutls_init
250#define fn_gnutls_priority_set_direct gnutls_priority_set_direct 244#define fn_gnutls_priority_set_direct gnutls_priority_set_direct
@@ -264,6 +258,17 @@ init_gnutls_functions (void)
264#endif /* !WINDOWSNT */ 258#endif /* !WINDOWSNT */
265 259
266 260
261/* Report memory exhaustion if ERR is an out-of-memory indication. */
262static void
263check_memory_full (int err)
264{
265 /* When GnuTLS exhausts memory, it doesn't say how much memory it
266 asked for, so tell the Emacs allocator that GnuTLS asked for no
267 bytes. This isn't accurate, but it's good enough. */
268 if (err == GNUTLS_E_MEMORY_ERROR)
269 memory_full (0);
270}
271
267#ifdef HAVE_GNUTLS3 272#ifdef HAVE_GNUTLS3
268/* Function to log a simple audit message. */ 273/* Function to log a simple audit message. */
269static void 274static void
@@ -360,7 +365,7 @@ emacs_gnutls_handshake (struct Lisp_Process *proc)
360 } 365 }
361 else 366 else
362 { 367 {
363 fn_gnutls_alert_send_appropriate (state, ret); 368 check_memory_full (fn_gnutls_alert_send_appropriate (state, ret));
364 } 369 }
365 return ret; 370 return ret;
366} 371}
@@ -477,6 +482,8 @@ emacs_gnutls_handle_error (gnutls_session_t session, int err)
477 if (err >= 0) 482 if (err >= 0)
478 return 1; 483 return 1;
479 484
485 check_memory_full (err);
486
480 max_log_level = global_gnutls_log_level; 487 max_log_level = global_gnutls_log_level;
481 488
482 /* TODO: use gnutls-error-fatalp and gnutls-error-string. */ 489 /* TODO: use gnutls-error-fatalp and gnutls-error-string. */
@@ -542,6 +549,7 @@ gnutls_make_error (int err)
542 return Qgnutls_e_invalid_session; 549 return Qgnutls_e_invalid_session;
543 } 550 }
544 551
552 check_memory_full (err);
545 return make_number (err); 553 return make_number (err);
546} 554}
547 555
@@ -682,11 +690,8 @@ emacs_gnutls_global_init (void)
682 int ret = GNUTLS_E_SUCCESS; 690 int ret = GNUTLS_E_SUCCESS;
683 691
684 if (!gnutls_global_initialized) 692 if (!gnutls_global_initialized)
685 { 693 ret = fn_gnutls_global_init ();
686 fn_gnutls_global_set_mem_functions (xmalloc, xmalloc, NULL, 694
687 xrealloc, xfree);
688 ret = fn_gnutls_global_init ();
689 }
690 gnutls_global_initialized = 1; 695 gnutls_global_initialized = 1;
691 696
692 return gnutls_make_error (ret); 697 return gnutls_make_error (ret);
@@ -854,7 +859,8 @@ one trustfile (usually a CA bundle). */)
854 unsigned int gnutls_verify_flags = GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT; 859 unsigned int gnutls_verify_flags = GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
855 860
856 GNUTLS_LOG (2, max_log_level, "allocating x509 credentials"); 861 GNUTLS_LOG (2, max_log_level, "allocating x509 credentials");
857 fn_gnutls_certificate_allocate_credentials (&x509_cred); 862 check_memory_full ((fn_gnutls_certificate_allocate_credentials
863 (&x509_cred)));
858 XPROCESS (proc)->gnutls_x509_cred = x509_cred; 864 XPROCESS (proc)->gnutls_x509_cred = x509_cred;
859 865
860 verify_flags = Fplist_get (proplist, QCgnutls_bootprop_verify_flags); 866 verify_flags = Fplist_get (proplist, QCgnutls_bootprop_verify_flags);
@@ -873,7 +879,8 @@ one trustfile (usually a CA bundle). */)
873 else /* Qgnutls_anon: */ 879 else /* Qgnutls_anon: */
874 { 880 {
875 GNUTLS_LOG (2, max_log_level, "allocating anon credentials"); 881 GNUTLS_LOG (2, max_log_level, "allocating anon credentials");
876 fn_gnutls_anon_allocate_client_credentials (&anon_cred); 882 check_memory_full ((fn_gnutls_anon_allocate_client_credentials
883 (&anon_cred)));
877 XPROCESS (proc)->gnutls_anon_cred = anon_cred; 884 XPROCESS (proc)->gnutls_anon_cred = anon_cred;
878 } 885 }
879 886
@@ -1105,7 +1112,10 @@ one trustfile (usually a CA bundle). */)
1105 return gnutls_make_error (ret); 1112 return gnutls_make_error (ret);
1106 } 1113 }
1107 1114
1108 if (!fn_gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname)) 1115 int err
1116 = fn_gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname);
1117 check_memory_full (err);
1118 if (!err)
1109 { 1119 {
1110 if (verify_error_all 1120 if (verify_error_all
1111 || !NILP (Fmember (QCgnutls_bootprop_hostname, verify_error))) 1121 || !NILP (Fmember (QCgnutls_bootprop_hostname, verify_error)))