aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2014-12-28 00:07:00 -0800
committerPaul Eggert2014-12-28 00:07:00 -0800
commit1505643bb70ce66e86d6c72902fe7e9199e93606 (patch)
tree0287f1d5f6ff9f6e25184fc843dddb7fe5125257 /src
parent9bb10cbdc59486c2131cea9b5399e9cbdc0418ab (diff)
parentb54f5721bfb6bf21cac5402cf34a8130e11bfb70 (diff)
downloademacs-1505643bb70ce66e86d6c72902fe7e9199e93606.tar.gz
emacs-1505643bb70ce66e86d6c72902fe7e9199e93606.zip
Merge from origin/emacs-24
b54f572 Port memory-full checking to GnuTLS 3.3 Conflicts: src/ChangeLog src/gnutls.c
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog17
-rw-r--r--src/gnutls.c65
2 files changed, 65 insertions, 17 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index d78e7a54a06..bdd1882c06a 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,20 @@
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, gnutls_certificate_details, Fgnutls_peer_status)
15 (Fgnutls_boot): Use it.
16 (emacs_gnutls_global_init): Avoid gnutls_global_set_mem_functions.
17
12014-12-27 Paul Eggert <eggert@cs.ucla.edu> 182014-12-27 Paul Eggert <eggert@cs.ucla.edu>
2 19
3 Fix parse_settings to match internal documentation 20 Fix parse_settings to match internal documentation
diff --git a/src/gnutls.c b/src/gnutls.c
index 14205ca0d3a..d28dbd07357 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -129,10 +129,6 @@ DEF_GNUTLS_FN (void, gnutls_global_set_log_function, (gnutls_log_func));
129DEF_GNUTLS_FN (void, gnutls_global_set_audit_log_function, (gnutls_audit_log_func)); 129DEF_GNUTLS_FN (void, gnutls_global_set_audit_log_function, (gnutls_audit_log_func));
130#endif 130#endif
131DEF_GNUTLS_FN (void, gnutls_global_set_log_level, (int)); 131DEF_GNUTLS_FN (void, gnutls_global_set_log_level, (int));
132DEF_GNUTLS_FN (void, gnutls_global_set_mem_functions,
133 (gnutls_alloc_function, gnutls_alloc_function,
134 gnutls_is_secure_function, gnutls_realloc_function,
135 gnutls_free_function));
136DEF_GNUTLS_FN (int, gnutls_handshake, (gnutls_session_t)); 132DEF_GNUTLS_FN (int, gnutls_handshake, (gnutls_session_t));
137DEF_GNUTLS_FN (int, gnutls_init, (gnutls_session_t *, unsigned int)); 133DEF_GNUTLS_FN (int, gnutls_init, (gnutls_session_t *, unsigned int));
138DEF_GNUTLS_FN (int, gnutls_priority_set_direct, 134DEF_GNUTLS_FN (int, gnutls_priority_set_direct,
@@ -251,7 +247,6 @@ init_gnutls_functions (void)
251 LOAD_GNUTLS_FN (library, gnutls_global_set_audit_log_function); 247 LOAD_GNUTLS_FN (library, gnutls_global_set_audit_log_function);
252#endif 248#endif
253 LOAD_GNUTLS_FN (library, gnutls_global_set_log_level); 249 LOAD_GNUTLS_FN (library, gnutls_global_set_log_level);
254 LOAD_GNUTLS_FN (library, gnutls_global_set_mem_functions);
255 LOAD_GNUTLS_FN (library, gnutls_handshake); 250 LOAD_GNUTLS_FN (library, gnutls_handshake);
256 LOAD_GNUTLS_FN (library, gnutls_init); 251 LOAD_GNUTLS_FN (library, gnutls_init);
257 LOAD_GNUTLS_FN (library, gnutls_priority_set_direct); 252 LOAD_GNUTLS_FN (library, gnutls_priority_set_direct);
@@ -344,7 +339,6 @@ init_gnutls_functions (void)
344#endif 339#endif
345#define fn_gnutls_global_set_log_function gnutls_global_set_log_function 340#define fn_gnutls_global_set_log_function gnutls_global_set_log_function
346#define fn_gnutls_global_set_log_level gnutls_global_set_log_level 341#define fn_gnutls_global_set_log_level gnutls_global_set_log_level
347#define fn_gnutls_global_set_mem_functions gnutls_global_set_mem_functions
348#define fn_gnutls_handshake gnutls_handshake 342#define fn_gnutls_handshake gnutls_handshake
349#define fn_gnutls_init gnutls_init 343#define fn_gnutls_init gnutls_init
350#define fn_gnutls_kx_get gnutls_kx_get 344#define fn_gnutls_kx_get gnutls_kx_get
@@ -384,6 +378,17 @@ init_gnutls_functions (void)
384#endif /* !WINDOWSNT */ 378#endif /* !WINDOWSNT */
385 379
386 380
381/* Report memory exhaustion if ERR is an out-of-memory indication. */
382static void
383check_memory_full (int err)
384{
385 /* When GnuTLS exhausts memory, it doesn't say how much memory it
386 asked for, so tell the Emacs allocator that GnuTLS asked for no
387 bytes. This isn't accurate, but it's good enough. */
388 if (err == GNUTLS_E_MEMORY_ERROR)
389 memory_full (0);
390}
391
387#ifdef HAVE_GNUTLS3 392#ifdef HAVE_GNUTLS3
388/* Log a simple audit message. */ 393/* Log a simple audit message. */
389static void 394static void
@@ -480,7 +485,7 @@ emacs_gnutls_handshake (struct Lisp_Process *proc)
480 } 485 }
481 else 486 else
482 { 487 {
483 fn_gnutls_alert_send_appropriate (state, ret); 488 check_memory_full (fn_gnutls_alert_send_appropriate (state, ret));
484 } 489 }
485 return ret; 490 return ret;
486} 491}
@@ -597,6 +602,8 @@ emacs_gnutls_handle_error (gnutls_session_t session, int err)
597 if (err >= 0) 602 if (err >= 0)
598 return 1; 603 return 1;
599 604
605 check_memory_full (err);
606
600 max_log_level = global_gnutls_log_level; 607 max_log_level = global_gnutls_log_level;
601 608
602 /* TODO: use gnutls-error-fatalp and gnutls-error-string. */ 609 /* TODO: use gnutls-error-fatalp and gnutls-error-string. */
@@ -662,6 +669,7 @@ gnutls_make_error (int err)
662 return Qgnutls_e_invalid_session; 669 return Qgnutls_e_invalid_session;
663 } 670 }
664 671
672 check_memory_full (err);
665 return make_number (err); 673 return make_number (err);
666} 674}
667 675
@@ -822,6 +830,7 @@ gnutls_certificate_details (gnutls_x509_crt_t cert)
822 /* Version. */ 830 /* Version. */
823 { 831 {
824 int version = fn_gnutls_x509_crt_get_version (cert); 832 int version = fn_gnutls_x509_crt_get_version (cert);
833 check_memory_full (version);
825 if (version >= GNUTLS_E_SUCCESS) 834 if (version >= GNUTLS_E_SUCCESS)
826 res = nconc2 (res, list2 (intern (":version"), 835 res = nconc2 (res, list2 (intern (":version"),
827 make_number (version))); 836 make_number (version)));
@@ -830,10 +839,12 @@ gnutls_certificate_details (gnutls_x509_crt_t cert)
830 /* Serial. */ 839 /* Serial. */
831 buf_size = 0; 840 buf_size = 0;
832 err = fn_gnutls_x509_crt_get_serial (cert, NULL, &buf_size); 841 err = fn_gnutls_x509_crt_get_serial (cert, NULL, &buf_size);
842 check_memory_full (err);
833 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER) 843 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
834 { 844 {
835 void *serial = xmalloc (buf_size); 845 void *serial = xmalloc (buf_size);
836 err = fn_gnutls_x509_crt_get_serial (cert, serial, &buf_size); 846 err = fn_gnutls_x509_crt_get_serial (cert, serial, &buf_size);
847 check_memory_full (err);
837 if (err >= GNUTLS_E_SUCCESS) 848 if (err >= GNUTLS_E_SUCCESS)
838 res = nconc2 (res, list2 (intern (":serial-number"), 849 res = nconc2 (res, list2 (intern (":serial-number"),
839 gnutls_hex_string (serial, buf_size, ""))); 850 gnutls_hex_string (serial, buf_size, "")));
@@ -843,10 +854,12 @@ gnutls_certificate_details (gnutls_x509_crt_t cert)
843 /* Issuer. */ 854 /* Issuer. */
844 buf_size = 0; 855 buf_size = 0;
845 err = fn_gnutls_x509_crt_get_issuer_dn (cert, NULL, &buf_size); 856 err = fn_gnutls_x509_crt_get_issuer_dn (cert, NULL, &buf_size);
857 check_memory_full (err);
846 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER) 858 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
847 { 859 {
848 char *dn = xmalloc (buf_size); 860 char *dn = xmalloc (buf_size);
849 err = fn_gnutls_x509_crt_get_issuer_dn (cert, dn, &buf_size); 861 err = fn_gnutls_x509_crt_get_issuer_dn (cert, dn, &buf_size);
862 check_memory_full (err);
850 if (err >= GNUTLS_E_SUCCESS) 863 if (err >= GNUTLS_E_SUCCESS)
851 res = nconc2 (res, list2 (intern (":issuer"), 864 res = nconc2 (res, list2 (intern (":issuer"),
852 make_string (dn, buf_size))); 865 make_string (dn, buf_size)));
@@ -872,10 +885,12 @@ gnutls_certificate_details (gnutls_x509_crt_t cert)
872 /* Subject. */ 885 /* Subject. */
873 buf_size = 0; 886 buf_size = 0;
874 err = fn_gnutls_x509_crt_get_dn (cert, NULL, &buf_size); 887 err = fn_gnutls_x509_crt_get_dn (cert, NULL, &buf_size);
888 check_memory_full (err);
875 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER) 889 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
876 { 890 {
877 char *dn = xmalloc (buf_size); 891 char *dn = xmalloc (buf_size);
878 err = fn_gnutls_x509_crt_get_dn (cert, dn, &buf_size); 892 err = fn_gnutls_x509_crt_get_dn (cert, dn, &buf_size);
893 check_memory_full (err);
879 if (err >= GNUTLS_E_SUCCESS) 894 if (err >= GNUTLS_E_SUCCESS)
880 res = nconc2 (res, list2 (intern (":subject"), 895 res = nconc2 (res, list2 (intern (":subject"),
881 make_string (dn, buf_size))); 896 make_string (dn, buf_size)));
@@ -889,6 +904,7 @@ gnutls_certificate_details (gnutls_x509_crt_t cert)
889 unsigned int bits; 904 unsigned int bits;
890 905
891 err = fn_gnutls_x509_crt_get_pk_algorithm (cert, &bits); 906 err = fn_gnutls_x509_crt_get_pk_algorithm (cert, &bits);
907 check_memory_full (err);
892 if (err >= GNUTLS_E_SUCCESS) 908 if (err >= GNUTLS_E_SUCCESS)
893 { 909 {
894 const char *name = fn_gnutls_pk_algorithm_get_name (err); 910 const char *name = fn_gnutls_pk_algorithm_get_name (err);
@@ -906,10 +922,12 @@ gnutls_certificate_details (gnutls_x509_crt_t cert)
906 /* Unique IDs. */ 922 /* Unique IDs. */
907 buf_size = 0; 923 buf_size = 0;
908 err = fn_gnutls_x509_crt_get_issuer_unique_id (cert, NULL, &buf_size); 924 err = fn_gnutls_x509_crt_get_issuer_unique_id (cert, NULL, &buf_size);
925 check_memory_full (err);
909 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER) 926 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
910 { 927 {
911 char *buf = xmalloc (buf_size); 928 char *buf = xmalloc (buf_size);
912 err = fn_gnutls_x509_crt_get_issuer_unique_id (cert, buf, &buf_size); 929 err = fn_gnutls_x509_crt_get_issuer_unique_id (cert, buf, &buf_size);
930 check_memory_full (err);
913 if (err >= GNUTLS_E_SUCCESS) 931 if (err >= GNUTLS_E_SUCCESS)
914 res = nconc2 (res, list2 (intern (":issuer-unique-id"), 932 res = nconc2 (res, list2 (intern (":issuer-unique-id"),
915 make_string (buf, buf_size))); 933 make_string (buf, buf_size)));
@@ -918,10 +936,12 @@ gnutls_certificate_details (gnutls_x509_crt_t cert)
918 936
919 buf_size = 0; 937 buf_size = 0;
920 err = fn_gnutls_x509_crt_get_subject_unique_id (cert, NULL, &buf_size); 938 err = fn_gnutls_x509_crt_get_subject_unique_id (cert, NULL, &buf_size);
939 check_memory_full (err);
921 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER) 940 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
922 { 941 {
923 char *buf = xmalloc (buf_size); 942 char *buf = xmalloc (buf_size);
924 err = fn_gnutls_x509_crt_get_subject_unique_id (cert, buf, &buf_size); 943 err = fn_gnutls_x509_crt_get_subject_unique_id (cert, buf, &buf_size);
944 check_memory_full (err);
925 if (err >= GNUTLS_E_SUCCESS) 945 if (err >= GNUTLS_E_SUCCESS)
926 res = nconc2 (res, list2 (intern (":subject-unique-id"), 946 res = nconc2 (res, list2 (intern (":subject-unique-id"),
927 make_string (buf, buf_size))); 947 make_string (buf, buf_size)));
@@ -931,6 +951,7 @@ gnutls_certificate_details (gnutls_x509_crt_t cert)
931 951
932 /* Signature. */ 952 /* Signature. */
933 err = fn_gnutls_x509_crt_get_signature_algorithm (cert); 953 err = fn_gnutls_x509_crt_get_signature_algorithm (cert);
954 check_memory_full (err);
934 if (err >= GNUTLS_E_SUCCESS) 955 if (err >= GNUTLS_E_SUCCESS)
935 { 956 {
936 const char *name = fn_gnutls_sign_get_name (err); 957 const char *name = fn_gnutls_sign_get_name (err);
@@ -942,10 +963,12 @@ gnutls_certificate_details (gnutls_x509_crt_t cert)
942 /* Public key ID. */ 963 /* Public key ID. */
943 buf_size = 0; 964 buf_size = 0;
944 err = fn_gnutls_x509_crt_get_key_id (cert, 0, NULL, &buf_size); 965 err = fn_gnutls_x509_crt_get_key_id (cert, 0, NULL, &buf_size);
966 check_memory_full (err);
945 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER) 967 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
946 { 968 {
947 void *buf = xmalloc (buf_size); 969 void *buf = xmalloc (buf_size);
948 err = fn_gnutls_x509_crt_get_key_id (cert, 0, buf, &buf_size); 970 err = fn_gnutls_x509_crt_get_key_id (cert, 0, buf, &buf_size);
971 check_memory_full (err);
949 if (err >= GNUTLS_E_SUCCESS) 972 if (err >= GNUTLS_E_SUCCESS)
950 res = nconc2 (res, list2 (intern (":public-key-id"), 973 res = nconc2 (res, list2 (intern (":public-key-id"),
951 gnutls_hex_string (buf, buf_size, "sha1:"))); 974 gnutls_hex_string (buf, buf_size, "sha1:")));
@@ -956,11 +979,13 @@ gnutls_certificate_details (gnutls_x509_crt_t cert)
956 buf_size = 0; 979 buf_size = 0;
957 err = fn_gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1, 980 err = fn_gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1,
958 NULL, &buf_size); 981 NULL, &buf_size);
982 check_memory_full (err);
959 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER) 983 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER)
960 { 984 {
961 void *buf = xmalloc (buf_size); 985 void *buf = xmalloc (buf_size);
962 err = fn_gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1, 986 err = fn_gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1,
963 buf, &buf_size); 987 buf, &buf_size);
988 check_memory_full (err);
964 if (err >= GNUTLS_E_SUCCESS) 989 if (err >= GNUTLS_E_SUCCESS)
965 res = nconc2 (res, list2 (intern (":certificate-id"), 990 res = nconc2 (res, list2 (intern (":certificate-id"),
966 gnutls_hex_string (buf, buf_size, "sha1:"))); 991 gnutls_hex_string (buf, buf_size, "sha1:")));
@@ -1062,6 +1087,7 @@ The return value is a property list with top-level keys :warnings and
1062 /* Diffie-Hellman prime bits. */ 1087 /* Diffie-Hellman prime bits. */
1063 { 1088 {
1064 int bits = fn_gnutls_dh_get_prime_bits (state); 1089 int bits = fn_gnutls_dh_get_prime_bits (state);
1090 check_memory_full (bits);
1065 if (bits > 0) 1091 if (bits > 0)
1066 result = nconc2 (result, list2 (intern (":diffie-hellman-prime-bits"), 1092 result = nconc2 (result, list2 (intern (":diffie-hellman-prime-bits"),
1067 make_number (bits))); 1093 make_number (bits)));
@@ -1104,11 +1130,8 @@ emacs_gnutls_global_init (void)
1104 int ret = GNUTLS_E_SUCCESS; 1130 int ret = GNUTLS_E_SUCCESS;
1105 1131
1106 if (!gnutls_global_initialized) 1132 if (!gnutls_global_initialized)
1107 { 1133 ret = fn_gnutls_global_init ();
1108 fn_gnutls_global_set_mem_functions (xmalloc, xmalloc, NULL, 1134
1109 xrealloc, xfree);
1110 ret = fn_gnutls_global_init ();
1111 }
1112 gnutls_global_initialized = 1; 1135 gnutls_global_initialized = 1;
1113 1136
1114 return gnutls_make_error (ret); 1137 return gnutls_make_error (ret);
@@ -1291,7 +1314,8 @@ one trustfile (usually a CA bundle). */)
1291 unsigned int gnutls_verify_flags = GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT; 1314 unsigned int gnutls_verify_flags = GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
1292 1315
1293 GNUTLS_LOG (2, max_log_level, "allocating x509 credentials"); 1316 GNUTLS_LOG (2, max_log_level, "allocating x509 credentials");
1294 fn_gnutls_certificate_allocate_credentials (&x509_cred); 1317 check_memory_full ((fn_gnutls_certificate_allocate_credentials
1318 (&x509_cred)));
1295 XPROCESS (proc)->gnutls_x509_cred = x509_cred; 1319 XPROCESS (proc)->gnutls_x509_cred = x509_cred;
1296 1320
1297 verify_flags = Fplist_get (proplist, QCgnutls_bootprop_verify_flags); 1321 verify_flags = Fplist_get (proplist, QCgnutls_bootprop_verify_flags);
@@ -1310,7 +1334,8 @@ one trustfile (usually a CA bundle). */)
1310 else /* Qgnutls_anon: */ 1334 else /* Qgnutls_anon: */
1311 { 1335 {
1312 GNUTLS_LOG (2, max_log_level, "allocating anon credentials"); 1336 GNUTLS_LOG (2, max_log_level, "allocating anon credentials");
1313 fn_gnutls_anon_allocate_client_credentials (&anon_cred); 1337 check_memory_full ((fn_gnutls_anon_allocate_client_credentials
1338 (&anon_cred)));
1314 XPROCESS (proc)->gnutls_anon_cred = anon_cred; 1339 XPROCESS (proc)->gnutls_anon_cred = anon_cred;
1315 } 1340 }
1316 1341
@@ -1326,8 +1351,11 @@ one trustfile (usually a CA bundle). */)
1326 (GNUTLS_VERSION_MINOR > 0 || GNUTLS_VERSION_PATCH >= 20) > 3 1351 (GNUTLS_VERSION_MINOR > 0 || GNUTLS_VERSION_PATCH >= 20) > 3
1327 ret = fn_gnutls_certificate_set_x509_system_trust (x509_cred); 1352 ret = fn_gnutls_certificate_set_x509_system_trust (x509_cred);
1328 if (ret < GNUTLS_E_SUCCESS) 1353 if (ret < GNUTLS_E_SUCCESS)
1329 GNUTLS_LOG2i (4, max_log_level, 1354 {
1330 "setting system trust failed with code ", ret); 1355 check_memory_full (ret);
1356 GNUTLS_LOG2i (4, max_log_level,
1357 "setting system trust failed with code ", ret);
1358 }
1331#endif 1359#endif
1332 1360
1333 for (tail = trustfiles; CONSP (tail); tail = XCDR (tail)) 1361 for (tail = trustfiles; CONSP (tail); tail = XCDR (tail))
@@ -1547,7 +1575,10 @@ one trustfile (usually a CA bundle). */)
1547 1575
1548 XPROCESS (proc)->gnutls_certificate = gnutls_verify_cert; 1576 XPROCESS (proc)->gnutls_certificate = gnutls_verify_cert;
1549 1577
1550 if (!fn_gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname)) 1578 int err
1579 = fn_gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname);
1580 check_memory_full (err);
1581 if (!err)
1551 { 1582 {
1552 XPROCESS (proc)->gnutls_extra_peer_verification |= 1583 XPROCESS (proc)->gnutls_extra_peer_verification |=
1553 CERTIFICATE_NOT_MATCHING; 1584 CERTIFICATE_NOT_MATCHING;