OSDN Git Service

greybus: manifest: descriptor size should be >= header size
authorViresh Kumar <viresh.kumar@linaro.org>
Tue, 24 Mar 2015 11:38:13 +0000 (17:08 +0530)
committerGreg Kroah-Hartman <greg@kroah.com>
Tue, 24 Mar 2015 19:59:03 +0000 (20:59 +0100)
We are calculating descriptors expected size differently based on the type of
descriptor, that's fine but at few places we aren't taking size of the header
into account. And that looks wrong.

Lets make sure it is atleast as big as descriptor's header.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
drivers/staging/greybus/manifest.c

index 8b61b34..545a3bd 100644 (file)
 
 #include "greybus.h"
 
+static const char *get_descriptor_type_string(u8 type)
+{
+       switch(type) {
+       case GREYBUS_TYPE_INVALID:
+               return "invalid";
+       case GREYBUS_TYPE_MODULE:
+               return "module";
+       case GREYBUS_TYPE_STRING:
+               return "string";
+       case GREYBUS_TYPE_INTERFACE:
+               return "interface";
+       case GREYBUS_TYPE_CPORT:
+               return "cport";
+       case GREYBUS_TYPE_CLASS:
+               return "class";
+       default:
+               WARN_ON(1);
+               return "unknown";
+       }
+}
+
 /*
  * We scan the manifest once to identify where all the descriptors
  * are.  The result is a list of these manifest_desc structures.  We
@@ -72,32 +93,21 @@ static int identify_descriptor(struct gb_interface *intf,
                return -EINVAL;
        }
 
+       /* Descriptor needs to at least have a header */
+       expected_size = sizeof(*desc_header);
+
        switch (desc_header->type) {
        case GREYBUS_TYPE_MODULE:
-               if (desc_size < sizeof(struct greybus_descriptor_module)) {
-                       pr_err("module descriptor too small (%u)\n",
-                               desc_size);
-                       return -EINVAL;
-               }
+               expected_size += sizeof(struct greybus_descriptor_module);
                break;
        case GREYBUS_TYPE_STRING:
-               expected_size = sizeof(*desc_header);
                expected_size += sizeof(struct greybus_descriptor_string);
-               expected_size += (size_t)desc->string.length;
-               if (desc_size < expected_size) {
-                       pr_err("string descriptor too small (%u)\n",
-                               desc_size);
-                       return -EINVAL;
-               }
+               expected_size += desc->string.length;
                break;
        case GREYBUS_TYPE_INTERFACE:
                break;
        case GREYBUS_TYPE_CPORT:
-               if (desc_size < sizeof(struct greybus_descriptor_cport)) {
-                       pr_err("cport descriptor too small (%u)\n",
-                               desc_size);
-                       return -EINVAL;
-               }
+               expected_size += sizeof(struct greybus_descriptor_cport);
                break;
        case GREYBUS_TYPE_CLASS:
                pr_warn("class descriptor found (ignoring)\n");
@@ -108,6 +118,13 @@ static int identify_descriptor(struct gb_interface *intf,
                return -EINVAL;
        }
 
+       if (desc_size < expected_size) {
+               pr_err("%s descriptor too small (%u < %zu)\n",
+                      get_descriptor_type_string(desc_header->type),
+                      desc_size, expected_size);
+               return -EINVAL;
+       }
+
        descriptor = kzalloc(sizeof(*descriptor), GFP_KERNEL);
        if (!descriptor)
                return -ENOMEM;