dbus/dbus dbus-marshal-header.c, 1.12, 1.13 dbus-marshal-validate.c, 1.19, 1.20 dbus-marshal-validate.h, 1.11, 1.12 dbus-message.c, 1.169, 1.170

John Palmieri johnp at freedesktop.org
Wed Jun 15 08:15:35 PDT 2005


Update of /cvs/dbus/dbus/dbus
In directory gabe:/tmp/cvs-serv3883/dbus

Modified Files:
	dbus-marshal-header.c dbus-marshal-validate.c 
	dbus-marshal-validate.h dbus-message.c 
Log Message:
	* dbus/dbus-marshal-validate.h: Added a new validation
        error code DBUS_VALIDITY_UNKNOWN_OOM_ERROR = -4 for
        out of memory errors when validating signitures

        * dbus/dbus-marshal-header.c: use DBUS_VALIDITY_UNKNOWN_OOM_ERROR
        in places where we previously used DBUS_VALID and a FALSE return
        value to indicate OOM

        * dbus/dbus-marshal-validate.c (_dbus_validate_signature_with_reason):
        Use a stack to track the number of elements inside containers.  The
        stack values are then used to validate that dict entries have only two
        elements within them.
        (validate_body_helper): check the reason for failure when validating
        varients

        * dbus/dbus-message.c (load_message): use
        DBUS_VALIDITY_UNKNOWN_OOM_ERROR in places where we previously used
        DBUS_VALID and a FALSE return value to indicate OOM

        * doc/TODO: remove "- validate dict entry number of fields" as this
        patch fixes it



Index: dbus-marshal-header.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-marshal-header.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- dbus-marshal-header.c	25 May 2005 16:03:53 -0000	1.12
+++ dbus-marshal-header.c	15 Jun 2005 15:15:32 -0000	1.13
@@ -926,9 +926,10 @@
  * Creates a message header from potentially-untrusted data. The
  * return value is #TRUE if there was enough memory and the data was
  * valid. If it returns #TRUE, the header will be created. If it
- * returns #FALSE and *validity == #DBUS_VALID, then there wasn't
- * enough memory.  If it returns #FALSE and *validity != #DBUS_VALID
- * then the data was invalid.
+ * returns #FALSE and *validity == #DBUS_VALIDITY_UNKNOWN_OOM_ERROR, 
+ * then there wasn't enough memory.  If it returns #FALSE 
+ * and *validity != #DBUS_VALIDITY_UNKNOWN_OOM_ERROR then the data was 
+ * invalid.
  *
  * The byte_order, fields_array_len, and body_len args should be from
  * _dbus_header_have_message_untrusted(). Validation performed in
@@ -977,7 +978,7 @@
   if (!_dbus_string_copy_len (str, start, header_len, &header->data, 0))
     {
       _dbus_verbose ("Failed to copy buffer into new header\n");
-      *validity = DBUS_VALID;
+      *validity = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
       return FALSE;
     }
 

Index: dbus-marshal-validate.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-marshal-validate.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- dbus-marshal-validate.c	24 Feb 2005 16:03:56 -0000	1.19
+++ dbus-marshal-validate.c	15 Jun 2005 15:15:32 -0000	1.20
@@ -61,6 +61,19 @@
   int struct_depth;
   int array_depth;
   int dict_entry_depth;
+  DBusValidity result;
+
+  int element_count;
+  DBusList *element_count_stack;
+
+  result = DBUS_VALID;
+  element_count_stack = NULL;
+
+  if (!_dbus_list_append (&element_count_stack, _DBUS_INT_TO_POINTER (0)))
+    {
+      result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
+      goto out;
+    }
 
   _dbus_assert (type_str != NULL);
   _dbus_assert (type_pos < _DBUS_INT32_MAX - len);
@@ -68,9 +81,13 @@
   _dbus_assert (type_pos >= 0);
 
   if (len > DBUS_MAXIMUM_SIGNATURE_LENGTH)
-    return DBUS_INVALID_SIGNATURE_TOO_LONG;
+    {
+      result = DBUS_INVALID_SIGNATURE_TOO_LONG;
+      goto out;
+    }
 
   p = _dbus_string_get_const_data_len (type_str, type_pos, 0);
+
   end = _dbus_string_get_const_data_len (type_str, type_pos + len, 0);
   struct_depth = 0;
   array_depth = 0;
@@ -99,85 +116,179 @@
         case DBUS_TYPE_ARRAY:
           array_depth += 1;
           if (array_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH)
-            return DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION;
+            {
+              result = DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION;
+              goto out;
+            }
           break;
 
         case DBUS_STRUCT_BEGIN_CHAR:
           struct_depth += 1;
 
           if (struct_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH)
-            return DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION;
+            {
+              result = DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION;
+              goto out;
+            }
+          
+          if (!_dbus_list_append (&element_count_stack, 
+                             _DBUS_INT_TO_POINTER (0)))
+            {
+              result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
+              goto out;
+            }
+
           break;
 
         case DBUS_STRUCT_END_CHAR:
           if (struct_depth == 0)
-            return DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED;
+            {
+              result = DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED;
+              goto out;
+            }
 
           if (last == DBUS_STRUCT_BEGIN_CHAR)
-            return DBUS_INVALID_STRUCT_HAS_NO_FIELDS;
+            {
+              result = DBUS_INVALID_STRUCT_HAS_NO_FIELDS;
+              goto out;
+            }
+
+          _dbus_list_pop_last (&element_count_stack);
 
           struct_depth -= 1;
           break;
 
         case DBUS_DICT_ENTRY_BEGIN_CHAR:
           if (last != DBUS_TYPE_ARRAY)
-            return DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY;
-          
+            {
+              result = DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY;
+              goto out;
+            }
+            
           dict_entry_depth += 1;
 
           if (dict_entry_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH)
-            return DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION;
+            {
+              result = DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION;
+              goto out;
+            }
+
+          if (!_dbus_list_append (&element_count_stack, 
+                             _DBUS_INT_TO_POINTER (0)))
+            {
+              result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
+              goto out;
+            }
+
           break;
 
         case DBUS_DICT_ENTRY_END_CHAR:
           if (dict_entry_depth == 0)
-            return DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED;
-          
-          if (last == DBUS_DICT_ENTRY_BEGIN_CHAR)
-            return DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS;
-
+            {
+              result = DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED;
+              goto out;
+            }
+            
           dict_entry_depth -= 1;
+
+          element_count = 
+            _DBUS_POINTER_TO_INT (_dbus_list_pop_last (&element_count_stack));
+
+          if (element_count != 2)
+            {
+              if (element_count == 0)
+                result = DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS;
+              else if (element_count == 1)
+                result = DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD;
+              else
+                result = DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS;
+              
+              goto out;
+            }
           break;
           
         case DBUS_TYPE_STRUCT:     /* doesn't appear in signatures */
         case DBUS_TYPE_DICT_ENTRY: /* ditto */
         default:
-          return DBUS_INVALID_UNKNOWN_TYPECODE;
+          result = DBUS_INVALID_UNKNOWN_TYPECODE;
+	  goto out;
         }
 
+      if (*p != DBUS_TYPE_ARRAY && 
+          *p != DBUS_DICT_ENTRY_BEGIN_CHAR && 
+	  *p != DBUS_STRUCT_BEGIN_CHAR) 
+        {
+          element_count = 
+            _DBUS_POINTER_TO_INT (_dbus_list_pop_last (&element_count_stack));
+
+          ++element_count;
+
+          if (!_dbus_list_append (&element_count_stack, 
+                             _DBUS_INT_TO_POINTER (element_count)))
+            {
+              result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
+              goto out;
+            }
+        }
+      
       if (array_depth > 0)
         {
-          if (*p == DBUS_TYPE_ARRAY)
-            ;
-          else if (*p == DBUS_STRUCT_END_CHAR ||
-                   *p == DBUS_DICT_ENTRY_END_CHAR)
-            return DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE;
+          if (*p == DBUS_TYPE_ARRAY && p != end)
+            {
+	       const char *p1;
+	       p1 = p + 1;
+               if (*p1 == DBUS_STRUCT_END_CHAR ||
+                   *p1 == DBUS_DICT_ENTRY_END_CHAR)
+                 {
+                   result = DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE;
+                   goto out;
+                 }
+            }
           else
-            array_depth = 0;
+	    {
+              array_depth = 0;
+	    }
         }
 
       if (last == DBUS_DICT_ENTRY_BEGIN_CHAR &&
           !dbus_type_is_basic (*p))
-        return DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE;
-      
+        {
+          result = DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE;
+          goto out;
+        }
+        
       last = *p;
       ++p;
     }
 
-  if (array_depth > 0)
-    return DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE;
 
+  if (array_depth > 0)
+    {
+      result = DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE;
+      goto out;
+    }
+    
   if (struct_depth > 0)
-    return DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED;
-
+    {
+       result = DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED;
+       goto out;
+    }
+    
   if (dict_entry_depth > 0)
-    return DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED;
-
+    {
+      result =  DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED;
+      goto out;
+    }
+    
   _dbus_assert (last != DBUS_TYPE_ARRAY);
   _dbus_assert (last != DBUS_STRUCT_BEGIN_CHAR);
   _dbus_assert (last != DBUS_DICT_ENTRY_BEGIN_CHAR);
-  
-  return DBUS_VALID;
+
+  result = DBUS_VALID;
+
+out:
+  _dbus_list_clear (&element_count_stack);
+  return result;
 }
 
 static DBusValidity
@@ -387,6 +498,7 @@
             DBusValidity validity;
             int contained_alignment;
             int contained_type;
+            DBusValidity reason;
 
             claimed_len = *p;
             ++p;
@@ -396,9 +508,15 @@
               return DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS;
 
             _dbus_string_init_const_len (&sig, p, claimed_len);
-            if (!_dbus_validate_signature (&sig, 0,
-                                           _dbus_string_get_length (&sig)))
-              return DBUS_INVALID_VARIANT_SIGNATURE_BAD;
+            reason = _dbus_validate_signature_with_reason (&sig, 0,
+                                           _dbus_string_get_length (&sig));
+            if (!(reason == DBUS_VALID))
+              {
+                if (reason == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
+                  return reason;
+                else 
+                  return DBUS_INVALID_VARIANT_SIGNATURE_BAD;
+              }
 
             p += claimed_len;
             

Index: dbus-marshal-validate.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-marshal-validate.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- dbus-marshal-validate.h	11 Feb 2005 01:13:45 -0000	1.11
+++ dbus-marshal-validate.h	15 Jun 2005 15:15:32 -0000	1.12
@@ -48,7 +48,8 @@
  */
 typedef enum
 {
-#define _DBUS_NEGATIVE_VALIDITY_COUNT 3
+#define _DBUS_NEGATIVE_VALIDITY_COUNT 4
+  DBUS_VALIDITY_UNKNOWN_OOM_ERROR = -4,
   DBUS_INVALID_FOR_UNKNOWN_REASON = -3,
   DBUS_VALID_BUT_INCOMPLETE = -2,
   DBUS_VALIDITY_UNKNOWN = -1,

Index: dbus-message.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-message.c,v
retrieving revision 1.169
retrieving revision 1.170
diff -u -d -r1.169 -r1.170
--- dbus-message.c	11 May 2005 18:07:22 -0000	1.169
+++ dbus-message.c	15 Jun 2005 15:15:32 -0000	1.170
@@ -3205,7 +3205,12 @@
                           _dbus_string_get_length (&loader->data)))
     {
       _dbus_verbose ("Failed to load header for new message code %d\n", validity);
-      if (validity == DBUS_VALID)
+
+      /* assert here so we can catch any code that still uses DBUS_VALID to indicate
+         oom errors.  They should use DBUS_VALIDITY_UNKNOWN_OOM_ERROR instead */
+      _dbus_assert (validity != DBUS_VALID);
+
+      if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
         oom = TRUE;
       else
         {



More information about the dbus-commit mailing list