diff options
author | Björn Gustavsson <[email protected]> | 2017-11-10 14:43:13 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2017-11-13 11:48:59 +0100 |
commit | 6c2b0ff5eb6009efdfdb3fa7b4ee794804e01bf0 (patch) | |
tree | 5d35af75961b751a626ad0b00d4afe2c15b12a4c /erts | |
parent | 1f8177e950715b3444dadfb1624875afe228195b (diff) | |
download | otp-6c2b0ff5eb6009efdfdb3fa7b4ee794804e01bf0.tar.gz otp-6c2b0ff5eb6009efdfdb3fa7b4ee794804e01bf0.tar.bz2 otp-6c2b0ff5eb6009efdfdb3fa7b4ee794804e01bf0.zip |
Refuse to load "literals" that can be confused with registers
The 's' operand overloads the tags for pids and ports to represent
X and Y registers, respectively. At load time, refuse to load the
module if the "literal" term is not a pid or port, as it would be
interpreted as a register.
This does not happen with normally compiled code, but it can happen
if the compiler (or beam_asm) is abused like in the following example:
make_bad() ->
Pid = self(),
Forms = [{attribute, 0, module, bad_s_operand},
{attribute, 0, export, [{test, 0}]},
{function, 0, test, 0,
[{clause, 0, [], [],
[{call,0,{atom,0,tuple_size},[{integer, 0, Pid}]}]}]}],
{ok, Module, Bin} = compile:forms(Forms, [no_copt,no_postopt,report_errors]),
code:load_binary(Module, "bad_s_operand.erl", Bin).
With this commit applied, the following message will be printed
when make_bad() is run:
=ERROR REPORT==== 10-Nov-2017::14:47:59 ===
Loading of bad_s_operand.erl failed: badfile
=ERROR REPORT==== 10-Nov-2017::14:47:59 ===
beam/beam_load.c(2396): Error loading function bad_s_operand:test/0: op bif1_body: bsd:
the term '<0.60.0>' would be confused with a register
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/beam/beam_load.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index 7331c331a6..4fcfea527c 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -2384,8 +2384,18 @@ load_code(LoaderState* stp) code[ci++] = NIL; break; case TAG_q: - new_literal_patch(stp, ci); - code[ci++] = tmp_op->a[arg].val; + { + BeamInstr val = tmp_op->a[arg].val; + Eterm term = stp->literals[val].term; + new_literal_patch(stp, ci); + code[ci++] = val; + switch (loader_tag(term)) { + case LOADER_X_REG: + case LOADER_Y_REG: + LoadError1(stp, "the term '%T' would be confused " + "with a register", term); + } + } break; default: LoadError1(stp, "bad tag %d for general source", |