diff options
| author | Eli Zaretskii | 2019-08-27 18:47:24 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2019-08-27 18:47:24 +0300 |
| commit | 6769b649286fbf0f29cb20590eb17011b435d429 (patch) | |
| tree | db1a68248d672c901c098143e8b0ee95e2370cee /src | |
| parent | e4d17d8cb479ffeeb7dfb7320a1432722ac8df75 (diff) | |
| download | emacs-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.c | 24 |
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, | |||
| 140 | DEF_DLL_FN (int, gnutls_dh_get_prime_bits, (gnutls_session_t)); | 140 | DEF_DLL_FN (int, gnutls_dh_get_prime_bits, (gnutls_session_t)); |
| 141 | DEF_DLL_FN (int, gnutls_error_is_fatal, (int)); | 141 | DEF_DLL_FN (int, gnutls_error_is_fatal, (int)); |
| 142 | DEF_DLL_FN (int, gnutls_global_init, (void)); | 142 | DEF_DLL_FN (int, gnutls_global_init, (void)); |
| 143 | DEF_DLL_FN (void, gnutls_free, (void *)); | ||
| 144 | DEF_DLL_FN (void, gnutls_global_set_log_function, (gnutls_log_func)); | 143 | DEF_DLL_FN (void, gnutls_global_set_log_function, (gnutls_log_func)); |
| 145 | # ifdef HAVE_GNUTLS3 | 144 | # ifdef HAVE_GNUTLS3 |
| 146 | DEF_DLL_FN (void, gnutls_global_set_audit_log_function, (gnutls_audit_log_func)); | 145 | DEF_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 | ||
| 293 | static gnutls_free_function *gnutls_free_func; | ||
| 294 | 294 | ||
| 295 | static bool | 295 | static bool |
| 296 | init_gnutls_functions (void) | 296 | init_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 | ||