aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2021-03-05 16:39:10 +0200
committerEli Zaretskii2021-03-05 16:41:41 +0200
commit552ef6d6c0733b864bcb14eeb6183d7e64df3b80 (patch)
tree79667bd927ef29a8268b8644a68b671214151b55 /src
parent260617ddc2e8e46a741e6843f97c7ffbc5222ed0 (diff)
downloademacs-552ef6d6c0733b864bcb14eeb6183d7e64df3b80.tar.gz
emacs-552ef6d6c0733b864bcb14eeb6183d7e64df3b80.zip
Fix some unsafe uses of SSDATA in comp.c
* src/comp.c (comp_hash_source_file) (Fcomp__compile_ctxt_to_file, Fnative_elisp_load): Encode file names before passing them to library APIs. (Fcomp__compile_ctxt_to_file): use emacs_fopen instead of fopen. (declare_lex_function): Avoid keeping a 'char *' pointer around while calling Lisp, which could trigger GC, which could relocate string data.
Diffstat (limited to 'src')
-rw-r--r--src/comp.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/src/comp.c b/src/comp.c
index 17dc4cbc132..94d3fa99a33 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -36,6 +36,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
36#include "dynlib.h" 36#include "dynlib.h"
37#include "buffer.h" 37#include "buffer.h"
38#include "blockinput.h" 38#include "blockinput.h"
39#include "coding.h"
39#include "md5.h" 40#include "md5.h"
40#include "sysstdio.h" 41#include "sysstdio.h"
41#include "zlib.h" 42#include "zlib.h"
@@ -693,7 +694,8 @@ comp_hash_source_file (Lisp_Object filename)
693 /* Can't use Finsert_file_contents + Fbuffer_hash as this is called 694 /* Can't use Finsert_file_contents + Fbuffer_hash as this is called
694 by Fcomp_el_to_eln_filename too early during bootstrap. */ 695 by Fcomp_el_to_eln_filename too early during bootstrap. */
695 bool is_gz = suffix_p (filename, ".gz"); 696 bool is_gz = suffix_p (filename, ".gz");
696 FILE *f = emacs_fopen (SSDATA (filename), is_gz ? "rb" : "r"); 697 Lisp_Object encoded_filename = ENCODE_FILE (filename);
698 FILE *f = emacs_fopen (SSDATA (encoded_filename), is_gz ? "rb" : "r");
697 699
698 if (!f) 700 if (!f)
699 report_file_error ("Opening source file", filename); 701 report_file_error ("Opening source file", filename);
@@ -3792,7 +3794,7 @@ static gcc_jit_function *
3792declare_lex_function (Lisp_Object func) 3794declare_lex_function (Lisp_Object func)
3793{ 3795{
3794 gcc_jit_function *res; 3796 gcc_jit_function *res;
3795 char *c_name = SSDATA (CALL1I (comp-func-c-name, func)); 3797 Lisp_Object c_name = CALL1I (comp-func-c-name, func);
3796 Lisp_Object args = CALL1I (comp-func-l-args, func); 3798 Lisp_Object args = CALL1I (comp-func-l-args, func);
3797 bool nargs = !NILP (CALL1I (comp-nargs-p, args)); 3799 bool nargs = !NILP (CALL1I (comp-nargs-p, args));
3798 USE_SAFE_ALLOCA; 3800 USE_SAFE_ALLOCA;
@@ -3814,7 +3816,7 @@ declare_lex_function (Lisp_Object func)
3814 res = gcc_jit_context_new_function (comp.ctxt, NULL, 3816 res = gcc_jit_context_new_function (comp.ctxt, NULL,
3815 GCC_JIT_FUNCTION_EXPORTED, 3817 GCC_JIT_FUNCTION_EXPORTED,
3816 comp.lisp_obj_type, 3818 comp.lisp_obj_type,
3817 c_name, 3819 SSDATA (c_name),
3818 max_args, 3820 max_args,
3819 params, 3821 params,
3820 0); 3822 0);
@@ -3835,7 +3837,8 @@ declare_lex_function (Lisp_Object func)
3835 NULL, 3837 NULL,
3836 GCC_JIT_FUNCTION_EXPORTED, 3838 GCC_JIT_FUNCTION_EXPORTED,
3837 comp.lisp_obj_type, 3839 comp.lisp_obj_type,
3838 c_name, ARRAYELTS (params), params, 0); 3840 SSDATA (c_name),
3841 ARRAYELTS (params), params, 0);
3839 } 3842 }
3840 SAFE_FREE (); 3843 SAFE_FREE ();
3841 return res; 3844 return res;
@@ -4332,6 +4335,10 @@ add_driver_options (void)
4332 if (!NILP (Fcomp_native_driver_options_effective_p ())) 4335 if (!NILP (Fcomp_native_driver_options_effective_p ()))
4333 FOR_EACH_TAIL (options) 4336 FOR_EACH_TAIL (options)
4334 gcc_jit_context_add_driver_option (comp.ctxt, 4337 gcc_jit_context_add_driver_option (comp.ctxt,
4338 /* FIXME: Need to encode
4339 this, but how? either
4340 ENCODE_FILE or
4341 ENCODE_SYSTEM. */
4335 SSDATA (XCAR (options))); 4342 SSDATA (XCAR (options)));
4336 return; 4343 return;
4337#endif 4344#endif
@@ -4353,6 +4360,7 @@ DEFUN ("comp--compile-ctxt-to-file", Fcomp__compile_ctxt_to_file,
4353 4360
4354 CHECK_STRING (filename); 4361 CHECK_STRING (filename);
4355 Lisp_Object base_name = Fsubstring (filename, Qnil, make_fixnum (-4)); 4362 Lisp_Object base_name = Fsubstring (filename, Qnil, make_fixnum (-4));
4363 Lisp_Object ebase_name = ENCODE_FILE (base_name);
4356 4364
4357 comp.func_relocs_local = NULL; 4365 comp.func_relocs_local = NULL;
4358 4366
@@ -4367,7 +4375,7 @@ DEFUN ("comp--compile-ctxt-to-file", Fcomp__compile_ctxt_to_file,
4367 1); 4375 1);
4368 if (comp.debug > 2) 4376 if (comp.debug > 2)
4369 { 4377 {
4370 logfile = fopen ("libgccjit.log", "w"); 4378 logfile = emacs_fopen ("libgccjit.log", "w");
4371 gcc_jit_context_set_logfile (comp.ctxt, 4379 gcc_jit_context_set_logfile (comp.ctxt,
4372 logfile, 4380 logfile,
4373 0, 0); 4381 0, 0);
@@ -4428,18 +4436,18 @@ DEFUN ("comp--compile-ctxt-to-file", Fcomp__compile_ctxt_to_file,
4428 4436
4429 if (comp.debug) 4437 if (comp.debug)
4430 gcc_jit_context_dump_to_file (comp.ctxt, 4438 gcc_jit_context_dump_to_file (comp.ctxt,
4431 format_string ("%s.c", SSDATA (base_name)), 4439 format_string ("%s.c", SSDATA (ebase_name)),
4432 1); 4440 1);
4433 if (!NILP (Fsymbol_value (Qcomp_libgccjit_reproducer))) 4441 if (!NILP (Fsymbol_value (Qcomp_libgccjit_reproducer)))
4434 gcc_jit_context_dump_reproducer_to_file ( 4442 gcc_jit_context_dump_reproducer_to_file (
4435 comp.ctxt, 4443 comp.ctxt,
4436 format_string ("%s_libgccjit_repro.c", SSDATA (base_name))); 4444 format_string ("%s_libgccjit_repro.c", SSDATA (ebase_name)));
4437 4445
4438 Lisp_Object tmp_file = 4446 Lisp_Object tmp_file =
4439 Fmake_temp_file_internal (base_name, Qnil, build_string (".eln.tmp"), Qnil); 4447 Fmake_temp_file_internal (base_name, Qnil, build_string (".eln.tmp"), Qnil);
4440 gcc_jit_context_compile_to_file (comp.ctxt, 4448 gcc_jit_context_compile_to_file (comp.ctxt,
4441 GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY, 4449 GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY,
4442 SSDATA (tmp_file)); 4450 SSDATA (ENCODE_FILE (tmp_file)));
4443 4451
4444 const char *err = gcc_jit_context_get_first_error (comp.ctxt); 4452 const char *err = gcc_jit_context_get_first_error (comp.ctxt);
4445 if (err) 4453 if (err)
@@ -5043,28 +5051,29 @@ LATE_LOAD has to be non-nil when loading for deferred compilation. */)
5043 xsignal2 (Qnative_lisp_load_failed, build_string ("file does not exists"), 5051 xsignal2 (Qnative_lisp_load_failed, build_string ("file does not exists"),
5044 filename); 5052 filename);
5045 struct Lisp_Native_Comp_Unit *comp_u = allocate_native_comp_unit (); 5053 struct Lisp_Native_Comp_Unit *comp_u = allocate_native_comp_unit ();
5054 Lisp_Object encoded_filename = ENCODE_FILE (filename);
5046 5055
5047 if (!NILP (Fgethash (filename, all_loaded_comp_units_h, Qnil)) 5056 if (!NILP (Fgethash (filename, all_loaded_comp_units_h, Qnil))
5048 && !file_in_eln_sys_dir (filename) 5057 && !file_in_eln_sys_dir (filename)
5049 && !NILP (Ffile_writable_p (filename))) 5058 && !NILP (Ffile_writable_p (filename)))
5050 { 5059 {
5051 /* If in this session there was ever a file loaded with this 5060 /* If in this session there was ever a file loaded with this
5052 name rename before loading it to make sure we always get a 5061 name, rename it before loading, to make sure we always get a
5053 new handle! */ 5062 new handle! */
5054 Lisp_Object tmp_filename = 5063 Lisp_Object tmp_filename =
5055 Fmake_temp_file_internal (filename, Qnil, build_string (".eln.tmp"), 5064 Fmake_temp_file_internal (filename, Qnil, build_string (".eln.tmp"),
5056 Qnil); 5065 Qnil);
5057 if (NILP (Ffile_writable_p (tmp_filename))) 5066 if (NILP (Ffile_writable_p (tmp_filename)))
5058 comp_u->handle = dynlib_open (SSDATA (filename)); 5067 comp_u->handle = dynlib_open (SSDATA (encoded_filename));
5059 else 5068 else
5060 { 5069 {
5061 Frename_file (filename, tmp_filename, Qt); 5070 Frename_file (filename, tmp_filename, Qt);
5062 comp_u->handle = dynlib_open (SSDATA (tmp_filename)); 5071 comp_u->handle = dynlib_open (SSDATA (ENCODE_FILE (tmp_filename)));
5063 Frename_file (tmp_filename, filename, Qnil); 5072 Frename_file (tmp_filename, filename, Qnil);
5064 } 5073 }
5065 } 5074 }
5066 else 5075 else
5067 comp_u->handle = dynlib_open (SSDATA (filename)); 5076 comp_u->handle = dynlib_open (SSDATA (encoded_filename));
5068 5077
5069 if (!comp_u->handle) 5078 if (!comp_u->handle)
5070 xsignal2 (Qnative_lisp_load_failed, filename, 5079 xsignal2 (Qnative_lisp_load_failed, filename,