Security of binary_to_term ?

Tony Rogvall tony@REDACTED
Sun Jul 8 01:23:30 CEST 2001


Lon Willett wrote:

> This stuff looks like it's down my alley, so I'll add my $0.02.
>
> Pascal Brisset <pascal.brisset@REDACTED> writes:
> >  > An aside note: If you get the data over TCP, why should it be
> >  > invalid. TCP ensures the data is non corrupted.... or maybe you
> >  > are worrying over rogue nodes ???
> >
> > Well this is what security is about, isn't it ? :) Actually I stumbled
> > on one of those pathological cases, and I was wondering whether it was
> > just a bug or whether additional checks were required anyway.
> >
> > $ erl
> > Erlang (BEAM) emulator version 5.0.2.4 [source]
> >
> > Eshell V5.0.2.4  (abort with ^G)
> > 1> binary_to_term(<<131,111,255,0,0,0>>).
> > zsh: 30198 segmentation fault  ./bin/erl
>
> Ugh!  Crashing the emulator is a bad sign.
>

Yes! extremely bad.

>
> I wouldn't worry overmuch about the crash per se, since all an
> attacker could use that for would be a denial-of-service attack (DOS).
> IMO, preventing DOS attacks is probably impossible (although one
> shouldn't make them _too_ easy).

This must be fixed of course (and will, right björn?)

>
>
> What is a concern is that the segfault indicates that there might be a
> buffer overflow problem, and this possibly would allow an attacker to
> execute arbitrary code on your machine.
>
> Even if you fix "binary_to_term" so that it is safe, I would advise
> caution anyway.  While it (term_to_binary+binary_to_term) is a
> convenient and easy way to define a data format, it is just too
> powerful.  An attacker could provide all kinds of funny data (pids,
> refs, funs, very large ints, etc), so even when the binary is validly
> formatted, you still need to be very sure that the contents of the
> resulting erlang term are fully validated (or are only used in "safe"
> ways).  This required validation is very easy to overlook, especially
> when the contents of the term are broken down and passed around to
> different modules, some of which may not have been written to handle
> maliciously formatted data (e.g. consider perl's "taint" mechanism,
> meant to help deal with this same problem).
>
> Despite its dangers, I would be interested in what exactly the
> problems with binary_to_term are.  So if anyone has the time to look
> at it (or already knows), I'd appreciate seeing the results.
>

This bug is kind of fun, the case is covered (in thought at least, but not
in action).
When the binary is converted into a term a function decode_size2 gets
called to calculate
the number of words needed on the heap. The <<131,111,255,0,0,0>> is
interpreted as a big integer number
(the 111) the length (in bytes) should be LEN=(2^24)*255 (a really big
number) but there is none.
The code then check, if when adding LEN to the current pointer the current
pointer exceeds the end of buffer pointer. The answer is NO it has wrapped
around the address space.
The SKIP and CHKSIZE (external.c) macros need to be reworked to cover this
case!

one way could be to store the  initial pointer and test that the resulting
pointer is between
the initial and the end pointer.

something like this:

#define SKIP(sz) do { \
    char* start= *ext; \
    *ext += (sz); \
    if (((*ext) > endp) || ((*ext) < start)) { return *okp = 0; } \
 } while(0)

/Tony





More information about the erlang-questions mailing list