enif_make_badarg crashes is_binary

Steve Vinoski vinoski@REDACTED
Tue Feb 22 06:54:46 CET 2011


I was recently writing a nif and had one C function returning an
ERL_NIF_TERM that was then being passed to a second C function. The
second one checked the passed term using
enif_inspect_iolist_as_binary(), and it crashed. I debugged it and
it's apparently caused by the fact that the ERL_NIF_TERM being passed
was returned from enif_make_badarg(), so it was a 0. It caused this
error on my Macbook Pro:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0xfffffffe

The reason for that invalid address is the is_binary(x) macro at the
beginning of enif_inspect_iolist_as_binary(). It expands to

    if (((!(((((term)))) & (0x3 -0x2))) && (((*((Eterm*) (((((term)))
- 0x2)))) & (0x3F -(0x3 << 2))) == (0x0|(0x8 << 2))))) {

The first test, which I believe comes from _unchecked_is_boxed(x),
passes because it's testing !0 which of course is 1, then the second
test which I believe is _unchecked_boxed_val(x) fails with the invalid
address error because the code more or less dereferences a null
pointer.

I think the fix is to make macros like is_binary(x) first check the
term using is_value(x).

--steve


More information about the erlang-bugs mailing list