fix native code crash when calling unloaded module with on_load function

Mikael Pettersson mikpe@REDACTED
Wed Jun 30 14:31:04 CEST 2010


As reported in erlang-bugs, the following sequence of events crashes the VM:

1. Module M1 is loaded and in native mode.
2. Module M2 is not loaded, in emulated mode, and has an on_load function.
3. M1 calls some function in M2. This works.
4. M1 again calls some function in M2. This segfaults.

The reason for the crash is that when the beam loader fixes up export
entries after a successful on_load function call, it erroneously clears
the ->code[3] field in that module's export entries.  This is redundant
(no code in beam relies on ->code[3] being NULL), inconsistent with
modules without on_load functions (there ->code[3] remains a valid beam
instruction after the module is loaded), and breaks native code which needs
the old ->address value in an export entry to remain valid after a module
load step (before the load ->address points to ->code[3], after the load
->address points to the real code but uses of the old ->address value
remain so ->code[3] must remain valid).

Thus the fix for the crash is to simply not clear ->code[3].
This patch fixes R14A and should also fix R13B04.

(There does exist a performance bug in this area, but it is unrelated
to the on_load feature so will be fixed separately.)

/Mikael Pettersson, HiPE

--- otp_src_R14A/erts/emulator/beam/beam_bif_load.c.~1~	2010-06-11 17:30:16.000000000 +0200
+++ otp_src_R14A/erts/emulator/beam/beam_bif_load.c	2010-06-30 13:17:03.000000000 +0200
@@ -337,7 +337,6 @@ BIF_RETTYPE finish_after_on_load_2(BIF_A
 		ep->code[0] == BIF_ARG_1 &&
 		ep->code[4] != 0) {
 		ep->address = (void *) ep->code[4];
-		ep->code[3] = 0;
 		ep->code[4] = 0;
 	    }
 	}


More information about the erlang-patches mailing list