[PATCH 1/2] ei: buffer overflow when decoding atoms

Michael Santos michael.santos@REDACTED
Mon Jan 24 00:16:10 CET 2011


---
 lib/erl_interface/src/decode/decode_atom.c  |    2 ++
 lib/erl_interface/src/decode/decode_pid.c   |    2 ++
 lib/erl_interface/src/decode/decode_port.c  |    2 ++
 lib/erl_interface/src/decode/decode_ref.c   |    3 +++
 lib/erl_interface/src/misc/ei_decode_term.c |    5 +++++
 5 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/lib/erl_interface/src/decode/decode_atom.c b/lib/erl_interface/src/decode/decode_atom.c
index b247bd4..ef28838 100644
--- a/lib/erl_interface/src/decode/decode_atom.c
+++ b/lib/erl_interface/src/decode/decode_atom.c
@@ -31,6 +31,8 @@ int ei_decode_atom(const char *buf, int *index, char *p)
 
   len = get16be(s);
 
+  if (len > MAXATOMLEN) return -1;
+
   if (p) {
     memmove(p,s,len); 
     p[len] = (char)0;
diff --git a/lib/erl_interface/src/decode/decode_pid.c b/lib/erl_interface/src/decode/decode_pid.c
index 5f2aec3..48a0c68 100644
--- a/lib/erl_interface/src/decode/decode_pid.c
+++ b/lib/erl_interface/src/decode/decode_pid.c
@@ -33,6 +33,8 @@ int ei_decode_pid(const char *buf, int *index, erlang_pid *p)
   if (get8(s) != ERL_ATOM_EXT) return -1;
 
   len = get16be(s);
+
+  if (len > MAXATOMLEN) return -1;
   
   if (p) {
     memmove(p->node, s, len);
diff --git a/lib/erl_interface/src/decode/decode_port.c b/lib/erl_interface/src/decode/decode_port.c
index 7fb7d8d..296ebae 100644
--- a/lib/erl_interface/src/decode/decode_port.c
+++ b/lib/erl_interface/src/decode/decode_port.c
@@ -34,6 +34,8 @@ int ei_decode_port(const char *buf, int *index, erlang_port *p)
 
   len = get16be(s);
 
+  if (len > MAXATOMLEN) return -1;
+
   if (p) {
     memmove(p->node, s, len);
     p->node[len] = (char)0;
diff --git a/lib/erl_interface/src/decode/decode_ref.c b/lib/erl_interface/src/decode/decode_ref.c
index 6fc2cd6..691b51f 100644
--- a/lib/erl_interface/src/decode/decode_ref.c
+++ b/lib/erl_interface/src/decode/decode_ref.c
@@ -35,6 +35,8 @@ int ei_decode_ref(const char *buf, int *index, erlang_ref *p)
 
       len = get16be(s);
 
+      if (len > MAXATOMLEN) return -1;
+
       if (p) {
 	  memmove(p->node, s, len);
 	  p->node[len] = (char)0;
@@ -62,6 +64,7 @@ int ei_decode_ref(const char *buf, int *index, erlang_ref *p)
       /* then the nodename */
       if (get8(s) != ERL_ATOM_EXT) return -1;
       len = get16be(s);
+      if (len > MAXATOMLEN) return -1;
 
       if (p) {
 	  memmove(p->node, s, len);
diff --git a/lib/erl_interface/src/misc/ei_decode_term.c b/lib/erl_interface/src/misc/ei_decode_term.c
index 75c5dc9..9b238c1 100644
--- a/lib/erl_interface/src/misc/ei_decode_term.c
+++ b/lib/erl_interface/src/misc/ei_decode_term.c
@@ -49,6 +49,7 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
         return ei_decode_double(buf, index, &term->value.d_val);
     case ERL_ATOM_EXT:
 	len = get16be(s);
+	if (len > MAXATOMLEN) return -1;
 	memcpy(term->value.atom_name, s, len); 
 	term->value.atom_name[len] = '\0';
 	s += len;
@@ -57,6 +58,7 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
 	/* first the nodename */
 	if (get8(s) != ERL_ATOM_EXT) return -1;
 	len = get16be(s);
+	if (len > MAXATOMLEN) return -1;
 	memcpy(term->value.ref.node, s, len);
 	term->value.ref.node[len] = '\0';
 	s += len;
@@ -71,6 +73,7 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
 	/* then the nodename */
 	if (get8(s) != ERL_ATOM_EXT) return -1;
 	len = get16be(s);
+	if (len > MAXATOMLEN) return -1;
 	memcpy(term->value.ref.node, s, len);
 	term->value.ref.node[len] = '\0';
 	s += len;
@@ -87,6 +90,7 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
     case ERL_PORT_EXT:
 	if (get8(s) != ERL_ATOM_EXT) return -1;
 	len = get16be(s);
+	if (len > MAXATOMLEN) return -1;
 	memcpy(term->value.port.node, s, len);
 	term->value.port.node[len] = '\0';
 	term->value.port.id = get32be(s) & 0x0fffffff; /* 28 bits */;
@@ -96,6 +100,7 @@ int ei_decode_ei_term(const char* buf, int* index, ei_term* term)
 	if (get8(s) != ERL_ATOM_EXT) return -1;
 	/* name first */
 	len = get16be(s); 
+	if (len > MAXATOMLEN) return -1;
 	memcpy(term->value.pid.node, s, len);
 	term->value.pid.node[len] = '\0';
 	s += len;
-- 
1.7.0.4



More information about the erlang-patches mailing list