aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorPaul Eggert2014-09-07 00:04:01 -0700
committerPaul Eggert2014-09-07 00:04:01 -0700
commitb3bf18b3b87ac8f00857b8bfc3f2c74cf0e2fb7d (patch)
treecf138164e4f8887394f52cb22da594d1713da316 /src/process.c
parent930fb80f9e2815e599eb1de699668d42e305fa21 (diff)
downloademacs-b3bf18b3b87ac8f00857b8bfc3f2c74cf0e2fb7d.tar.gz
emacs-b3bf18b3b87ac8f00857b8bfc3f2c74cf0e2fb7d.zip
Use SAFE_ALLOCA etc. to avoid unbounded stack allocation.
This follows up on the recent thread in emacs-devel on alloca; see: http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00042.html This patch also cleans up alloca-related glitches noted while examining the code looking for unbounded alloca. * alloc.c (listn): * callproc.c (init_callproc): Rewrite to avoid need for alloca. * buffer.c (mouse_face_overlay_overlaps) (report_overlay_modification): * buffer.h (GET_OVERLAYS_AT): * coding.c (make_subsidiaries): * doc.c (Fsnarf_documentation): * editfns.c (Fuser_full_name): * fileio.c (Ffile_name_directory, Fexpand_file_name) (search_embedded_absfilename, Fsubstitute_in_file_name): * fns.c (Fmake_hash_table): * font.c (font_vconcat_entity_vectors, font_update_drivers): * fontset.c (fontset_pattern_regexp, Ffontset_info): * frame.c (Fmake_terminal_frame, x_set_frame_parameters) (xrdb_get_resource, x_get_resource_string): * ftfont.c (ftfont_get_charset, ftfont_check_otf, ftfont_drive_otf): * ftxfont.c (ftxfont_draw): * image.c (xbm_load, xpm_load, jpeg_load_body): * keyboard.c (echo_add_key, menu_bar_items, tool_bar_items): * keymap.c (Fdescribe_buffer_bindings, describe_map): * lread.c (openp): * menu.c (digest_single_submenu, find_and_call_menu_selection) (find_and_return_menu_selection): * print.c (PRINTFINISH): * process.c (Fformat_network_address): * scroll.c (do_scrolling, do_direct_scrolling, scrolling_1): * search.c (search_buffer, Fmatch_data, Fregexp_quote): * sound.c (wav_play, au_play): * syntax.c (skip_chars): * term.c (tty_menu_activate, tty_menu_show): * textprop.c (get_char_property_and_overlay): * window.c (Fset_window_configuration): * xdisp.c (safe__call, next_overlay_change, vmessage) (compute_overhangs_and_x, draw_glyphs, note_mouse_highlight): * xfaces.c (face_at_buffer_position): * xmenu.c (x_menu_show): Use SAFE_ALLOCA etc. instead of plain alloca, since the allocation size isn't bounded. * callint.c (Fcall_interactively): Redo memory_full check so that it can be done at compile-time on some platforms. * coding.c (MAX_LOOKUP_MAX): New constant. (get_translation_table): Use it. * callproc.c (call_process): Use SAFE_NALLOCA instead of SAFE_ALLOCA, to catch integer overflows on size calculation. (exec_failed) [!DOS_NT]: New function. (child_setup) [!DOS_NT]: Use it. * editfns.c (Ftranspose_regions): Hoist USE_SAFE_ALLOC + SAFE_FREE out of 'if'. * editfns.c (check_translation): Allocate larger buffers on the heap. * eval.c (internal_lisp_condition_case): Check for MAX_ALLOCA overflow. * fns.c (sort_vector): Use SAFE_ALLOCA_LISP rather than Fmake_vector. (Fbase64_encode_region, Fbase64_decode_region): Avoid unnecessary calls to SAFE_FREE before 'error'. * buffer.c (mouse_face_overlay_overlaps): * editfns.c (Fget_pos_property, check_translation): * eval.c (Ffuncall): * font.c (font_unparse_xlfd, font_find_for_lface): * ftfont.c (ftfont_drive_otf): * keyboard.c (echo_add_key, read_decoded_event_from_main_queue) (menu_bar_items, tool_bar_items): * sound.c (Fplay_sound_internal): * xdisp.c (load_overlay_strings, dump_glyph_row): Use an ordinary auto buffer rather than alloca, since the allocation size is fixed and small. * ftfont.c: Include <c-strcase.h>. (matching_prefix): New function. (get_adstyle_property): Use it, to avoid need for alloca. * keyboard.c (echo_add_key): * keymap.c (describe_map): Use ptrdiff_t, not int. * keyboard.c (echo_add_key): Prefer sizeof to strlen. * keymap.c (Fdescribe_buffer_bindings): Use SBYTES, not SCHARS, when counting bytes. * lisp.h (xlispstrdupa): Remove, replacing with ... (SAFE_ALLOCA_STRING): ... new macro with different API. This fixes a portability problem, namely, alloca result passed to another function. All uses changed. (SAFE_ALLOCA, SAFE_ALLOCA_LISP): Check for MAX_ALLOCA, not MAX_ALLOCA - 1. * regex.c (REGEX_USE_SAFE_ALLOCA, REGEX_SAFE_FREE) (REGEX_ALLOCATE): New macros. (REGEX_REALLOCATE, REGEX_ALLOCATE_STACK, REGEX_REALLOCATE_STACK) (REGEX_FREE_STACK, FREE_VARIABLES, re_match_2_internal): Use them. * xdisp.c (message3): Use SAFE_ALLOCA_STRING rather than doing it by hand. (decode_mode_spec_coding): Store directly into buf rather than into an alloca temporary and copying the temporary to the buf. Fixes: debbugs:18410
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/src/process.c b/src/process.c
index 0d6994bdab1..ef9f295fd89 100644
--- a/src/process.c
+++ b/src/process.c
@@ -1386,9 +1386,10 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1386 (ptrdiff_t nargs, Lisp_Object *args) 1386 (ptrdiff_t nargs, Lisp_Object *args)
1387{ 1387{
1388 Lisp_Object buffer, name, program, proc, current_dir, tem; 1388 Lisp_Object buffer, name, program, proc, current_dir, tem;
1389 register unsigned char **new_argv; 1389 unsigned char **new_argv;
1390 ptrdiff_t i; 1390 ptrdiff_t i;
1391 ptrdiff_t count = SPECPDL_INDEX (); 1391 ptrdiff_t count = SPECPDL_INDEX ();
1392 USE_SAFE_ALLOCA;
1392 1393
1393 buffer = args[1]; 1394 buffer = args[1];
1394 if (!NILP (buffer)) 1395 if (!NILP (buffer))
@@ -1464,7 +1465,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1464 val = Vcoding_system_for_read; 1465 val = Vcoding_system_for_read;
1465 if (NILP (val)) 1466 if (NILP (val))
1466 { 1467 {
1467 args2 = alloca ((nargs + 1) * sizeof *args2); 1468 SAFE_ALLOCA_LISP (args2, nargs + 1);
1468 args2[0] = Qstart_process; 1469 args2[0] = Qstart_process;
1469 for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; 1470 for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
1470 GCPRO2 (proc, current_dir); 1471 GCPRO2 (proc, current_dir);
@@ -1483,7 +1484,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1483 { 1484 {
1484 if (EQ (coding_systems, Qt)) 1485 if (EQ (coding_systems, Qt))
1485 { 1486 {
1486 args2 = alloca ((nargs + 1) * sizeof *args2); 1487 SAFE_ALLOCA_LISP (args2, nargs + 1);
1487 args2[0] = Qstart_process; 1488 args2[0] = Qstart_process;
1488 for (i = 0; i < nargs; i++) args2[i + 1] = args[i]; 1489 for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
1489 GCPRO2 (proc, current_dir); 1490 GCPRO2 (proc, current_dir);
@@ -1578,7 +1579,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1578 1579
1579 /* Now that everything is encoded we can collect the strings into 1580 /* Now that everything is encoded we can collect the strings into
1580 NEW_ARGV. */ 1581 NEW_ARGV. */
1581 new_argv = alloca ((nargs - 1) * sizeof *new_argv); 1582 SAFE_NALLOCA (new_argv, 1, nargs - 1);
1582 new_argv[nargs - 2] = 0; 1583 new_argv[nargs - 2] = 0;
1583 1584
1584 for (i = nargs - 2; i-- != 0; ) 1585 for (i = nargs - 2; i-- != 0; )
@@ -1592,6 +1593,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
1592 else 1593 else
1593 create_pty (proc); 1594 create_pty (proc);
1594 1595
1596 SAFE_FREE ();
1595 return unbind_to (count, proc); 1597 return unbind_to (count, proc);
1596} 1598}
1597 1599
@@ -2071,8 +2073,10 @@ get_lisp_to_sockaddr_size (Lisp_Object address, int *familyp)
2071 && VECTORP (XCDR (address))) 2073 && VECTORP (XCDR (address)))
2072 { 2074 {
2073 struct sockaddr *sa; 2075 struct sockaddr *sa;
2074 *familyp = XINT (XCAR (address));
2075 p = XVECTOR (XCDR (address)); 2076 p = XVECTOR (XCDR (address));
2077 if (MAX_ALLOCA - sizeof sa->sa_family < p->header.size)
2078 return 0;
2079 *familyp = XINT (XCAR (address));
2076 return p->header.size + sizeof (sa->sa_family); 2080 return p->header.size + sizeof (sa->sa_family);
2077 } 2081 }
2078 return 0; 2082 return 0;
@@ -4973,18 +4977,17 @@ read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars,
4973 for decoding. */ 4977 for decoding. */
4974 4978
4975static int 4979static int
4976read_process_output (Lisp_Object proc, register int channel) 4980read_process_output (Lisp_Object proc, int channel)
4977{ 4981{
4978 register ssize_t nbytes; 4982 ssize_t nbytes;
4979 char *chars; 4983 struct Lisp_Process *p = XPROCESS (proc);
4980 register struct Lisp_Process *p = XPROCESS (proc);
4981 struct coding_system *coding = proc_decode_coding_system[channel]; 4984 struct coding_system *coding = proc_decode_coding_system[channel];
4982 int carryover = p->decoding_carryover; 4985 int carryover = p->decoding_carryover;
4983 int readmax = 4096; 4986 enum { readmax = 4096 };
4984 ptrdiff_t count = SPECPDL_INDEX (); 4987 ptrdiff_t count = SPECPDL_INDEX ();
4985 Lisp_Object odeactivate; 4988 Lisp_Object odeactivate;
4989 char chars[sizeof coding->carryover + readmax];
4986 4990
4987 chars = alloca (carryover + readmax);
4988 if (carryover) 4991 if (carryover)
4989 /* See the comment above. */ 4992 /* See the comment above. */
4990 memcpy (chars, SDATA (p->decoding_buf), carryover); 4993 memcpy (chars, SDATA (p->decoding_buf), carryover);
@@ -6837,7 +6840,7 @@ add_timer_wait_descriptor (int fd)
6837{ 6840{
6838 FD_SET (fd, &input_wait_mask); 6841 FD_SET (fd, &input_wait_mask);
6839 FD_SET (fd, &non_keyboard_wait_mask); 6842 FD_SET (fd, &non_keyboard_wait_mask);
6840 FD_SET (fd, &non_process_wait_mask); 6843 FD_SET (fd, &non_process_wait_mask);
6841 fd_callback_info[fd].func = timerfd_callback; 6844 fd_callback_info[fd].func = timerfd_callback;
6842 fd_callback_info[fd].data = NULL; 6845 fd_callback_info[fd].data = NULL;
6843 fd_callback_info[fd].condition |= FOR_READ; 6846 fd_callback_info[fd].condition |= FOR_READ;