From 19b3b2c2aeb7e1e787a65936ada0dabc229620ea Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 24 Mar 2015 17:08:13 +0530 Subject: [PATCH] greybus: manifest: descriptor size should be >= header size 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 Reviewed-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/manifest.c | 51 +++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/drivers/staging/greybus/manifest.c b/drivers/staging/greybus/manifest.c index 8b61b3486a3d..545a3bd4e751 100644 --- a/drivers/staging/greybus/manifest.c +++ b/drivers/staging/greybus/manifest.c @@ -13,6 +13,27 @@ #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; -- 2.11.0