aboutsummaryrefslogtreecommitdiffstats
path: root/src/fns.c
diff options
context:
space:
mode:
authorPaul Eggert2017-07-14 16:18:37 -0700
committerPaul Eggert2017-07-14 16:36:18 -0700
commit05b8b866993b957f5fd575846cf8ea3035e60f7e (patch)
tree7d25217ee1f4c409cb217c52a6bd152dda675b8a /src/fns.c
parent8b64a80a56c0e15d3313a45022ae60b33dbb4bff (diff)
downloademacs-05b8b866993b957f5fd575846cf8ea3035e60f7e.tar.gz
emacs-05b8b866993b957f5fd575846cf8ea3035e60f7e.zip
GnuTLS integer-overflow and style fixes
This tweaks the recently-added GnuTLS improvements so that they avoid some integer-overflow problems and follow typical Emacs style a bit better. * configure.ac (HAVE_GNUTLS3_HMAC, HAVE_GNUTLS3_AEAD) (HAVE_GNUTLS3_CIPHER): Use AC_CACHE_CHECK so that the configure-time results are displayed. * src/fns.c (extract_data_from_object): Return char *, not char const *, since one gnutls caller wants a non-const pointer. Use CONSP rather than !NILP when testing for conses. Use CAR_SAFE instead of rolling our own code. Prefer signed types to unsigned when either will do. Report problems for lengths out of range, instead of silently mishandling them. * src/gnutls.c (emacs_gnutls_strerror): New function, to simplify callers. All callers of gnutls_sterror changed. (Fgnutls_boot): Check for integers out of range rather than silently truncating them. (gnutls_symmetric_aead): Check for integer overflow in size calculations. (gnutls_symmetric_aead, Fgnutls_macs, Fgnutls_digests): Prefer signed to unsigned integers where either will do. (gnutls_symmetric_aead, gnutls_symmetric): Work even if ptrdiff_t is wider than ‘long’. (gnutls_symmetric, Fgnutls_hash_mac, Fgnutls_hash_digest): Check for integer overflow in algorithm selection.
Diffstat (limited to 'src/fns.c')
-rw-r--r--src/fns.c49
1 files changed, 22 insertions, 27 deletions
diff --git a/src/fns.c b/src/fns.c
index b678a482bbc..fb1296bc6f0 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -46,10 +46,6 @@ static void sort_vector_copy (Lisp_Object, ptrdiff_t,
46enum equal_kind { EQUAL_NO_QUIT, EQUAL_PLAIN, EQUAL_INCLUDING_PROPERTIES }; 46enum equal_kind { EQUAL_NO_QUIT, EQUAL_PLAIN, EQUAL_INCLUDING_PROPERTIES };
47static bool internal_equal (Lisp_Object, Lisp_Object, 47static bool internal_equal (Lisp_Object, Lisp_Object,
48 enum equal_kind, int, Lisp_Object); 48 enum equal_kind, int, Lisp_Object);
49static Lisp_Object
50secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start,
51 Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror,
52 Lisp_Object binary);
53 49
54DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0, 50DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0,
55 doc: /* Return the argument unchanged. */ 51 doc: /* Return the argument unchanged. */
@@ -4767,29 +4763,24 @@ DEFUN ("secure-hash-algorithms", Fsecure_hash_algorithms,
4767(BUFFER-OR-STRING-OR-SYMBOL START END CODING-SYSTEM NOERROR) which behave as 4763(BUFFER-OR-STRING-OR-SYMBOL START END CODING-SYSTEM NOERROR) which behave as
4768specified with `secure-hash' and in Info node 4764specified with `secure-hash' and in Info node
4769`(elisp)Format of GnuTLS Cryptography Inputs'. */ 4765`(elisp)Format of GnuTLS Cryptography Inputs'. */
4770const char* 4766char *
4771extract_data_from_object (Lisp_Object spec, 4767extract_data_from_object (Lisp_Object spec,
4772 ptrdiff_t *start_byte, 4768 ptrdiff_t *start_byte,
4773 ptrdiff_t *end_byte) 4769 ptrdiff_t *end_byte)
4774{ 4770{
4775 ptrdiff_t size, start_char = 0, end_char = 0; 4771 Lisp_Object object = XCAR (spec);
4776 register EMACS_INT b, e;
4777 register struct buffer *bp;
4778 EMACS_INT temp;
4779 4772
4780 Lisp_Object object = XCAR (spec); 4773 if (CONSP (spec)) spec = XCDR (spec);
4774 Lisp_Object start = CAR_SAFE (spec);
4781 4775
4782 if (! NILP (spec)) spec = XCDR (spec); 4776 if (CONSP (spec)) spec = XCDR (spec);
4783 Lisp_Object start = (CONSP (spec)) ? XCAR (spec) : Qnil; 4777 Lisp_Object end = CAR_SAFE (spec);
4784 4778
4785 if (! NILP (spec)) spec = XCDR (spec); 4779 if (CONSP (spec)) spec = XCDR (spec);
4786 Lisp_Object end = (CONSP (spec)) ? XCAR (spec) : Qnil; 4780 Lisp_Object coding_system = CAR_SAFE (spec);
4787 4781
4788 if (! NILP (spec)) spec = XCDR (spec); 4782 if (CONSP (spec)) spec = XCDR (spec);
4789 Lisp_Object coding_system = (CONSP (spec)) ? XCAR (spec) : Qnil; 4783 Lisp_Object noerror = CAR_SAFE (spec);
4790
4791 if (! NILP (spec)) spec = XCDR (spec);
4792 Lisp_Object noerror = (CONSP (spec)) ? XCAR (spec) : Qnil;
4793 4784
4794 if (STRINGP (object)) 4785 if (STRINGP (object))
4795 { 4786 {
@@ -4817,7 +4808,7 @@ extract_data_from_object (Lisp_Object spec,
4817 if (STRING_MULTIBYTE (object)) 4808 if (STRING_MULTIBYTE (object))
4818 object = code_convert_string (object, coding_system, Qnil, 1, 0, 1); 4809 object = code_convert_string (object, coding_system, Qnil, 1, 0, 1);
4819 4810
4820 size = SCHARS (object); 4811 ptrdiff_t size = SCHARS (object), start_char, end_char;
4821 validate_subarray (object, start, end, size, &start_char, &end_char); 4812 validate_subarray (object, start, end, size, &start_char, &end_char);
4822 4813
4823 *start_byte = !start_char ? 0 : string_char_to_byte (object, start_char); 4814 *start_byte = !start_char ? 0 : string_char_to_byte (object, start_char);
@@ -4828,12 +4819,13 @@ extract_data_from_object (Lisp_Object spec,
4828 else if (BUFFERP (object)) 4819 else if (BUFFERP (object))
4829 { 4820 {
4830 struct buffer *prev = current_buffer; 4821 struct buffer *prev = current_buffer;
4822 EMACS_INT b, e;
4831 4823
4832 record_unwind_current_buffer (); 4824 record_unwind_current_buffer ();
4833 4825
4834 CHECK_BUFFER (object); 4826 CHECK_BUFFER (object);
4835 4827
4836 bp = XBUFFER (object); 4828 struct buffer *bp = XBUFFER (object);
4837 set_buffer_internal (bp); 4829 set_buffer_internal (bp);
4838 4830
4839 if (NILP (start)) 4831 if (NILP (start))
@@ -4853,7 +4845,11 @@ extract_data_from_object (Lisp_Object spec,
4853 } 4845 }
4854 4846
4855 if (b > e) 4847 if (b > e)
4856 temp = b, b = e, e = temp; 4848 {
4849 EMACS_INT temp = b;
4850 b = e;
4851 e = temp;
4852 }
4857 4853
4858 if (!(BEGV <= b && e <= ZV)) 4854 if (!(BEGV <= b && e <= ZV))
4859 args_out_of_range (start, end); 4855 args_out_of_range (start, end);
@@ -4932,14 +4928,13 @@ extract_data_from_object (Lisp_Object spec,
4932 else if (EQ (object, Qiv_auto)) 4928 else if (EQ (object, Qiv_auto))
4933 { 4929 {
4934#ifdef HAVE_GNUTLS3 4930#ifdef HAVE_GNUTLS3
4935 // Format: (iv-auto REQUIRED-LENGTH) 4931 /* Format: (iv-auto REQUIRED-LENGTH). */
4936 4932
4937 if (! INTEGERP (start)) 4933 if (! NATNUMP (start))
4938 error ("Without a length, iv-auto can't be used. See manual."); 4934 error ("Without a length, iv-auto can't be used. See manual.");
4939 else 4935 else
4940 { 4936 {
4941 /* Make sure the value of "start" doesn't change. */ 4937 EMACS_INT start_hold = XFASTINT (start);
4942 size_t start_hold = XUINT (start);
4943 object = make_uninit_string (start_hold); 4938 object = make_uninit_string (start_hold);
4944 gnutls_rnd (GNUTLS_RND_NONCE, SSDATA (object), start_hold); 4939 gnutls_rnd (GNUTLS_RND_NONCE, SSDATA (object), start_hold);
4945 4940
@@ -4971,7 +4966,7 @@ secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start,
4971 4966
4972 Lisp_Object spec = list5 (object, start, end, coding_system, noerror); 4967 Lisp_Object spec = list5 (object, start, end, coding_system, noerror);
4973 4968
4974 const char* input = extract_data_from_object (spec, &start_byte, &end_byte); 4969 const char *input = extract_data_from_object (spec, &start_byte, &end_byte);
4975 4970
4976 if (input == NULL) 4971 if (input == NULL)
4977 error ("secure_hash: failed to extract data from object, aborting!"); 4972 error ("secure_hash: failed to extract data from object, aborting!");