[erlang-bugs] a crypto function call crashes VM

SUZUKI Tetsuya <>
Fri Aug 26 12:33:56 CEST 2011


Hi,

BEAM crashes when the following message digest functions using
contexts in crypto module receive some binary as context.
(Environment: Erlang R14B03, Mac OS X 10.6.8 (i386, MacBook Air).

* md4_update/2
* md4_final/2
* md5_update/2
* md5_final/2
* sha_update/2
* sha_final/2
* hmac_update/2
* hmac_final/2

Conditions of the binary I tried are:

* The same length as context generated by
  context initialization functions (*_init/0 or hmac_init/2).
  For example in my environment, context length of
  md5_init/0 is 92 and sha_init/0 is 96.

* The content is reversed binary (context) generated by
  context initialization functions.

An example:

$ erl
Erlang R14B03 (erts-5.8.4) [source] [64-bit] [smp:2:2] [rq:2]
[async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.8.4  (abort with ^G)
1> C1 = crypto:sha_init().
<<1,35,69,103,137,171,205,239,254,220,186,152,118,84,50,
  16,240,225,210,195,0,0,0,0,0,0,0,0,114,...>>
2> C2 = list_to_binary(lists:reverse(binary_to_list(C1))).
<<0,0,0,0,213,8,1,216,13,25,10,215,13,17,10,64,23,213,13,
  35,59,35,213,13,48,130,19,217,13,...>>
3> crypto:sha_update(C2, "hello").
Segmentation fault

If length of context is different from one generated by
context initialization functions, BEAM does not crash:

1> C1 = crypto:sha_init().
<<1,35,69,103,137,171,205,239,254,220,186,152,118,84,50,
  16,240,225,210,195,0,0,0,0,0,0,0,0,19,...>>
2> C2 = list_to_binary(lists:reverse(binary_to_list(C1))).
<<0,0,0,0,3,3,67,240,80,5,125,67,99,77,45,71,72,1,72,77,
  61,3,67,64,242,67,71,77,43,...>>
3> C3 = list_to_binary(binary_to_list(C2) ++ "abc").
<<0,0,0,0,3,3,67,240,80,5,125,67,99,77,45,71,72,1,72,77,
  61,3,67,64,242,67,71,77,43,...>>
4> crypto:sha_update(C3, "hello").
** exception error: bad argument
     in function  crypto:sha_update/2
        called as
crypto:sha_update(<<0,0,0,0,3,3,67,240,80,5,125,67,99,77,45,71,
                                      72,1,72,77,61,3,67,64,242,67,71,77,...>>,
                                    "hello")


I think NIF implementation of the functions cause the crash
in otp_src_R14B03/lib/crypto/c_src/crypto.c.

For MD5, in static md5_init(), line 442:

  MD5_Init((MD5_CTX *) enif_make_new_binary(env, MD5_CTX_LEN, &ret));

In static md5_update(), line 450-451:

  MD5_CTX* new_ctx;
  ErlNifBinary ctx_bin, data_bin;
  ERL_NIF_TERM ret;
  if (!enif_inspect_binary(env, argv[0], &ctx_bin) /* here */
      || ctx_bin.size != MD5_CTX_LEN               /* here */
  ...

The md5_update() implementation uses a binary of first argument
as struct MD5_CTX with only checking length of the binary and MD5_CTX.
However, it is not ensured that the binary is
byte representation of struct MD5_CTX.
Other digest functions (MD4, SHA1, HMAC) have the same problem.

If the functions communicate with BEAM using resource objects
include MD5_CTX data, BEAM may not crash.

---
SUZUKI Tetsuya


More information about the erlang-bugs mailing list