From f258c60f9fac3d781342ae4a3983e2a80da9b47e Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 20 Jul 2024 08:52:55 -0700 Subject: [PATCH] SAFE_ALLOCA fixes * src/comp.c (declare_imported_func, emit_simple_limple_call) (declare_lex_function, compile_function): * src/emacs-module.c (funcall_module): * src/fns.c (Fstring_distance): * src/font.c (font_sort_entities): * src/haikumenu.c (digest_menu_items, haiku_menu_show): * src/pgtkselect.c (Fpgtk_register_dnd_targets): * src/xfns.c (Fx_begin_drag): * src/xmenu.c (x_menu_show): * src/xterm.c (x_dnd_compute_toplevels, handle_one_xevent) (x_term_init): Prefer SAFE_NALLOCA to doing size multiplication by hand, to catch unlikely integer overflows. * src/comp.c (emit_simple_limple_call): Fix bug where SAFE_FREE was called too early, leading to unlikely use of freed storage. * src/xterm.c (handle_one_xevent): Remove side effects from SAFE_ALLOCA args, as the args are evaluated twice. (cherry picked from commit 101ec1430128a0b1d9e7d54cbd9c0add8f446f25) --- src/comp.c | 19 +++++++++++-------- src/emacs-module.c | 10 +++++++++- src/fns.c | 3 ++- src/font.c | 2 +- src/haikumenu.c | 17 +++++++---------- src/pgtkselect.c | 2 +- src/xfns.c | 2 +- src/xmenu.c | 6 ++---- src/xterm.c | 38 ++++++++++++++------------------------ 9 files changed, 48 insertions(+), 51 deletions(-) diff --git a/src/comp.c b/src/comp.c index 41aa2c4c9b0..08c272bed70 100644 --- a/src/comp.c +++ b/src/comp.c @@ -1009,7 +1009,7 @@ declare_imported_func (Lisp_Object subr_sym, gcc_jit_type *ret_type, } else if (!types) { - types = SAFE_ALLOCA (nargs * sizeof (* types)); + SAFE_NALLOCA (types, 1, nargs); for (ptrdiff_t i = 0; i < nargs; i++) types[i] = comp.lisp_obj_type; } @@ -2096,16 +2096,17 @@ static gcc_jit_rvalue * emit_simple_limple_call (Lisp_Object args, gcc_jit_type *ret_type, bool direct) { USE_SAFE_ALLOCA; - int i = 0; Lisp_Object callee = FIRST (args); args = XCDR (args); - ptrdiff_t nargs = list_length (args); - gcc_jit_rvalue **gcc_args = SAFE_ALLOCA (nargs * sizeof (*gcc_args)); + ptrdiff_t i = 0, nargs = list_length (args); + gcc_jit_rvalue **gcc_args; + SAFE_NALLOCA (gcc_args, 1, nargs); FOR_EACH_TAIL (args) gcc_args[i++] = emit_mvar_rval (XCAR (args)); + gcc_jit_rvalue *res = emit_call (callee, ret_type, nargs, gcc_args, direct); SAFE_FREE (); - return emit_call (callee, ret_type, nargs, gcc_args, direct); + return res; } static gcc_jit_rvalue * @@ -4213,11 +4214,13 @@ declare_lex_function (Lisp_Object func) { EMACS_INT max_args = XFIXNUM (CALL1I (comp-args-max, args)); eassert (max_args < INT_MAX); - gcc_jit_type **type = SAFE_ALLOCA (max_args * sizeof (*type)); + gcc_jit_type **type; + SAFE_NALLOCA (type, 1, max_args); for (ptrdiff_t i = 0; i < max_args; i++) type[i] = comp.lisp_obj_type; - gcc_jit_param **params = SAFE_ALLOCA (max_args * sizeof (*params)); + gcc_jit_param **params; + SAFE_NALLOCA (params, 1, max_args); for (int i = 0; i < max_args; ++i) params[i] = gcc_jit_context_new_param (comp.ctxt, NULL, @@ -4293,7 +4296,7 @@ compile_function (Lisp_Object func) comp.func_relocs_ptr_type, "freloc"); - comp.frame = SAFE_ALLOCA (comp.frame_size * sizeof (*comp.frame)); + SAFE_NALLOCA (comp.frame, 1, comp.frame_size); if (comp.func_has_non_local || !comp.func_speed) { /* FIXME: See bug#42360. */ diff --git a/src/emacs-module.c b/src/emacs-module.c index 08db39b0b0d..05aa0baef74 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c @@ -1266,7 +1266,15 @@ funcall_module (Lisp_Object function, ptrdiff_t nargs, Lisp_Object *arglist) record_unwind_protect_module (SPECPDL_MODULE_ENVIRONMENT, env); USE_SAFE_ALLOCA; - emacs_value *args = nargs > 0 ? SAFE_ALLOCA (nargs * sizeof *args) : NULL; + emacs_value *args; + /* FIXME: Is this (nargs <= 0) test needed? Either omit it and call + SAFE_NALLOCA unconditionally, or fix this comment to explain why + the test is needed. */ + if (nargs <= 0) + args = NULL; + else + SAFE_NALLOCA (args, 1, nargs); + for (ptrdiff_t i = 0; i < nargs; ++i) { args[i] = lisp_to_value (env, arglist[i]); diff --git a/src/fns.c b/src/fns.c index 7c14d904a1a..dbda523d285 100644 --- a/src/fns.c +++ b/src/fns.c @@ -292,7 +292,8 @@ Letter-case is significant, but text properties are ignored. */) ptrdiff_t x, y, lastdiag, olddiag; USE_SAFE_ALLOCA; - ptrdiff_t *column = SAFE_ALLOCA ((len1 + 1) * sizeof (ptrdiff_t)); + ptrdiff_t *column; + SAFE_NALLOCA (column, 1, len1 + 1); for (y = 0; y <= len1; y++) column[y] = y; diff --git a/src/font.c b/src/font.c index 0a0ac5f8030..246fe1c4426 100644 --- a/src/font.c +++ b/src/font.c @@ -2230,7 +2230,7 @@ font_sort_entities (Lisp_Object list, Lisp_Object prefer, maxlen = ASIZE (vec); } - data = SAFE_ALLOCA (maxlen * sizeof *data); + SAFE_NALLOCA (data, 1, maxlen); best_score = 0xFFFFFFFF; best_entity = Qnil; diff --git a/src/haikumenu.c b/src/haikumenu.c index 2e00b1803ae..f159d0e5638 100644 --- a/src/haikumenu.c +++ b/src/haikumenu.c @@ -38,8 +38,6 @@ digest_menu_items (void *first_menu, int start, int menu_items_used, bool is_menu_bar) { void **menus, **panes; - ssize_t menu_len; - ssize_t pane_len; int i, menu_depth; void *menu, *window, *view; Lisp_Object pane_name, prefix; @@ -48,18 +46,18 @@ digest_menu_items (void *first_menu, int start, int menu_items_used, USE_SAFE_ALLOCA; - menu_len = (menu_items_used + 1 - start) * sizeof *menus; - pane_len = (menu_items_used + 1 - start) * sizeof *panes; + int menu_len = menu_items_used - start + 1; + int pane_len = menu_items_used - start + 1; menu = first_menu; i = start; menu_depth = 0; - menus = SAFE_ALLOCA (menu_len); - panes = SAFE_ALLOCA (pane_len); - memset (menus, 0, menu_len); - memset (panes, 0, pane_len); + SAFE_NALLOCA (menus, 1, menu_len); + SAFE_NALLOCA (panes, 1, pane_len); + memset (menus, 0, menu_len * sizeof *menus); menus[0] = first_menu; + memset (panes, 0, pane_len * sizeof *panes); window = NULL; view = NULL; @@ -393,8 +391,7 @@ haiku_menu_show (struct frame *f, int x, int y, int menuflags, view = FRAME_HAIKU_VIEW (f); i = 0; submenu_depth = 0; - subprefix_stack - = SAFE_ALLOCA (menu_items_used * sizeof (Lisp_Object)); + SAFE_NALLOCA (subprefix_stack, 1, menu_items_used); eassert (FRAME_HAIKU_P (f)); diff --git a/src/pgtkselect.c b/src/pgtkselect.c index 271411b87ca..c9f117126b2 100644 --- a/src/pgtkselect.c +++ b/src/pgtkselect.c @@ -1808,7 +1808,7 @@ targets) that can be dropped on top of FRAME. */) CHECK_LIST (targets); length = list_length (targets); n = 0; - entries = SAFE_ALLOCA (sizeof *entries * length); + SAFE_NALLOCA (entries, 1, length); memset (entries, 0, sizeof *entries * length); tem = targets; diff --git a/src/xfns.c b/src/xfns.c index 917b82ff8da..3187bcfa2cf 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -7361,7 +7361,7 @@ that mouse buttons are being held down, such as immediately after a else signal_error ("Invalid drag-and-drop action", action); - target_atoms = SAFE_ALLOCA (ntargets * sizeof *target_atoms); + SAFE_NALLOCA (target_atoms, 1, ntargets); /* Catch errors since interning lots of targets can potentially generate a BadAlloc error. */ diff --git a/src/xmenu.c b/src/xmenu.c index 6dd7b3f37a0..0a41c47d527 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -1902,10 +1902,8 @@ x_menu_show (struct frame *f, int x, int y, int menuflags, USE_SAFE_ALLOCA; - submenu_stack = SAFE_ALLOCA (menu_items_used - * sizeof *submenu_stack); - subprefix_stack = SAFE_ALLOCA (menu_items_used - * sizeof *subprefix_stack); + SAFE_NALLOCA (submenu_stack, 1, menu_items_used); + SAFE_NALLOCA (subprefix_stack, 1, menu_items_used); specpdl_count = SPECPDL_INDEX (); diff --git a/src/xterm.c b/src/xterm.c index 5e200203f64..29f94dd196d 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -3099,27 +3099,19 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo) #ifdef USE_XCB USE_SAFE_ALLOCA; - window_attribute_cookies - = SAFE_ALLOCA (sizeof *window_attribute_cookies * nitems); - translate_coordinate_cookies - = SAFE_ALLOCA (sizeof *translate_coordinate_cookies * nitems); - get_property_cookies - = SAFE_ALLOCA (sizeof *get_property_cookies * nitems); - xm_property_cookies - = SAFE_ALLOCA (sizeof *xm_property_cookies * nitems); - extent_property_cookies - = SAFE_ALLOCA (sizeof *extent_property_cookies * nitems); - get_geometry_cookies - = SAFE_ALLOCA (sizeof *get_geometry_cookies * nitems); + SAFE_NALLOCA (window_attribute_cookies, 1, nitems); + SAFE_NALLOCA (translate_coordinate_cookies, 1, nitems); + SAFE_NALLOCA (get_property_cookies, 1, nitems); + SAFE_NALLOCA (xm_property_cookies, 1, nitems); + SAFE_NALLOCA (extent_property_cookies, 1, nitems); + SAFE_NALLOCA (get_geometry_cookies, 1, nitems); #ifdef HAVE_XCB_SHAPE - bounding_rect_cookies - = SAFE_ALLOCA (sizeof *bounding_rect_cookies * nitems); + SAFE_NALLOCA (bounding_rect_cookies, 1, nitems); #endif #ifdef HAVE_XCB_SHAPE_INPUT_RECTS - input_rect_cookies - = SAFE_ALLOCA (sizeof *input_rect_cookies * nitems); + SAFE_NALLOCA (input_rect_cookies, 1, nitems); #endif for (i = 0; i < nitems; ++i) @@ -20410,8 +20402,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (overflow) { - copy_bufptr = SAFE_ALLOCA ((copy_bufsiz += overflow) - * sizeof *copy_bufptr); + copy_bufsiz += overflow; + copy_bufptr = SAFE_ALLOCA (copy_bufsiz); overflow = 0; /* Use the original keysym derived from the @@ -24325,9 +24317,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, &overflow); if (overflow) { - copy_bufptr - = SAFE_ALLOCA ((copy_bufsiz += overflow) - * sizeof *copy_bufptr); + copy_bufsiz += overflow; + copy_bufptr = SAFE_ALLOCA (copy_bufsiz); overflow = 0; /* Use the original keysym derived from @@ -24668,7 +24659,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, any_changed = false; #endif /* !USE_X_TOOLKIT && (!USE_GTK || HAVE_GTK3) */ hev = (XIHierarchyEvent *) xi_event; - disabled = SAFE_ALLOCA (sizeof *disabled * hev->num_info); + SAFE_NALLOCA (disabled, 1, hev->num_info); n_disabled = 0; for (i = 0; i < hev->num_info; ++i) @@ -31690,8 +31681,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) } #ifdef USE_XCB - selection_cookies = SAFE_ALLOCA (sizeof *selection_cookies - * num_fast_selections); + SAFE_NALLOCA (selection_cookies, 1, num_fast_selections); #endif /* Now, ask for the current owners of all those selections. */ -- 2.39.2