aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2019-08-27 18:47:24 +0300
committerEli Zaretskii2019-08-27 18:47:24 +0300
commit6769b649286fbf0f29cb20590eb17011b435d429 (patch)
treedb1a68248d672c901c098143e8b0ee95e2370cee /src
parente4d17d8cb479ffeeb7dfb7320a1432722ac8df75 (diff)
downloademacs-6769b649286fbf0f29cb20590eb17011b435d429.tar.gz
emacs-6769b649286fbf0f29cb20590eb17011b435d429.zip
Fix crashes on MS-Windows when using GnuTLS connections
* src/gnutls.c (init_gnutls_functions) [WINDOWSNT]: Define and load gnutls_free by an explicit call to GetProcAddress. (gnutls_free) [WINDOWSNT]: Define as a macro that dereferences a function pointer. (Bug#31946) (Fgnutls_format_certificate): Use make_string_from_bytes instead of going through an intermediate malloc'ed buffer.
Diffstat (limited to 'src')
-rw-r--r--src/gnutls.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/src/gnutls.c b/src/gnutls.c
index 67d1fb9552d..fb75eb930f1 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -140,7 +140,6 @@ DEF_DLL_FN (void, gnutls_dh_set_prime_bits,
140DEF_DLL_FN (int, gnutls_dh_get_prime_bits, (gnutls_session_t)); 140DEF_DLL_FN (int, gnutls_dh_get_prime_bits, (gnutls_session_t));
141DEF_DLL_FN (int, gnutls_error_is_fatal, (int)); 141DEF_DLL_FN (int, gnutls_error_is_fatal, (int));
142DEF_DLL_FN (int, gnutls_global_init, (void)); 142DEF_DLL_FN (int, gnutls_global_init, (void));
143DEF_DLL_FN (void, gnutls_free, (void *));
144DEF_DLL_FN (void, gnutls_global_set_log_function, (gnutls_log_func)); 143DEF_DLL_FN (void, gnutls_global_set_log_function, (gnutls_log_func));
145# ifdef HAVE_GNUTLS3 144# ifdef HAVE_GNUTLS3
146DEF_DLL_FN (void, gnutls_global_set_audit_log_function, (gnutls_audit_log_func)); 145DEF_DLL_FN (void, gnutls_global_set_audit_log_function, (gnutls_audit_log_func));
@@ -291,6 +290,7 @@ DEF_DLL_FN (const char *, gnutls_ext_get_name, (unsigned int));
291# endif 290# endif
292# endif /* HAVE_GNUTLS3 */ 291# endif /* HAVE_GNUTLS3 */
293 292
293static gnutls_free_function *gnutls_free_func;
294 294
295static bool 295static bool
296init_gnutls_functions (void) 296init_gnutls_functions (void)
@@ -327,7 +327,6 @@ init_gnutls_functions (void)
327 LOAD_DLL_FN (library, gnutls_dh_get_prime_bits); 327 LOAD_DLL_FN (library, gnutls_dh_get_prime_bits);
328 LOAD_DLL_FN (library, gnutls_error_is_fatal); 328 LOAD_DLL_FN (library, gnutls_error_is_fatal);
329 LOAD_DLL_FN (library, gnutls_global_init); 329 LOAD_DLL_FN (library, gnutls_global_init);
330 LOAD_DLL_FN (library, gnutls_free);
331 LOAD_DLL_FN (library, gnutls_global_set_log_function); 330 LOAD_DLL_FN (library, gnutls_global_set_log_function);
332# ifdef HAVE_GNUTLS3 331# ifdef HAVE_GNUTLS3
333 LOAD_DLL_FN (library, gnutls_global_set_audit_log_function); 332 LOAD_DLL_FN (library, gnutls_global_set_audit_log_function);
@@ -430,6 +429,13 @@ init_gnutls_functions (void)
430# endif 429# endif
431# endif /* HAVE_GNUTLS3 */ 430# endif /* HAVE_GNUTLS3 */
432 431
432 /* gnutls_free is a variable inside GnuTLS, whose value is the
433 "free" function. So it needs special handling. */
434 gnutls_free_func = (gnutls_free_function *) GetProcAddress (library,
435 "gnutls_free");
436 if (!gnutls_free_func)
437 return false;
438
433 max_log_level = clip_to_bounds (INT_MIN, global_gnutls_log_level, INT_MAX); 439 max_log_level = clip_to_bounds (INT_MIN, global_gnutls_log_level, INT_MAX);
434 { 440 {
435 Lisp_Object name = CAR_SAFE (Fget (Qgnutls, QCloaded_from)); 441 Lisp_Object name = CAR_SAFE (Fget (Qgnutls, QCloaded_from));
@@ -465,7 +471,6 @@ init_gnutls_functions (void)
465# define gnutls_global_init fn_gnutls_global_init 471# define gnutls_global_init fn_gnutls_global_init
466# define gnutls_global_set_audit_log_function fn_gnutls_global_set_audit_log_function 472# define gnutls_global_set_audit_log_function fn_gnutls_global_set_audit_log_function
467# define gnutls_global_set_log_function fn_gnutls_global_set_log_function 473# define gnutls_global_set_log_function fn_gnutls_global_set_log_function
468# define gnutls_free fn_gnutls_free
469# define gnutls_global_set_log_level fn_gnutls_global_set_log_level 474# define gnutls_global_set_log_level fn_gnutls_global_set_log_level
470# define gnutls_handshake fn_gnutls_handshake 475# define gnutls_handshake fn_gnutls_handshake
471# define gnutls_init fn_gnutls_init 476# define gnutls_init fn_gnutls_init
@@ -562,6 +567,11 @@ init_gnutls_functions (void)
562# endif 567# endif
563# endif /* HAVE_GNUTLS3 */ 568# endif /* HAVE_GNUTLS3 */
564 569
570/* gnutls_free is a data pointer to a variable which holds a pointer
571 to the function. We use #undef because MinGW64 defines gnutls_free
572 as a macro as well in the GnuTLS headers. */
573# undef gnutls_free
574# define gnutls_free (*gnutls_free_func)
565 575
566/* This wrapper is called from fns.c, which doesn't know about the 576/* This wrapper is called from fns.c, which doesn't know about the
567 LOAD_DLL_FN stuff above. */ 577 LOAD_DLL_FN stuff above. */
@@ -1612,16 +1622,10 @@ string representation. */)
1612 emacs_gnutls_strerror (err)); 1622 emacs_gnutls_strerror (err));
1613 } 1623 }
1614 1624
1615 char *out_buf = xmalloc ((out.size + 1) * sizeof (char)); 1625 Lisp_Object result = make_string_from_bytes (out.data, out.size, out.size);
1616 memset (out_buf, 0, (out.size + 1) * sizeof (char));
1617 memcpy (out_buf, out.data, out.size);
1618
1619 gnutls_free (out.data); 1626 gnutls_free (out.data);
1620 gnutls_x509_crt_deinit (crt); 1627 gnutls_x509_crt_deinit (crt);
1621 1628
1622 Lisp_Object result = build_string (out_buf);
1623 xfree (out_buf);
1624
1625 return result; 1629 return result;
1626} 1630}
1627 1631