summaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/g_ffs.c
diff options
context:
space:
mode:
authorMichal Nazarewicz <m.nazarewicz@samsung.com>2010-06-14 10:43:34 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2010-06-30 08:16:05 -0700
commitf588c0db39ca35f69f815dabe5682759daa25098 (patch)
tree6dc88e41bb71c04cc8d6a1f21affd7e827edd075 /drivers/usb/gadget/g_ffs.c
parentb23097b793081358a6d943263c91bae4c955c4e3 (diff)
USB: gadget: g_fs: possible invalid pointer reference bug fixed
During __gfs_do_config() some invalid pointers may be left in usb_configuration::interfaces array from previous calls to the __gfs_do_config() for the same configuration. This will always happen if an user space function which has a fewer then the last user space function registers itself. Composite's set_config() function that a pointer after the last interface in usb_configuration::interface is NULL unless the array is full. This patch makes the __gfs_do_config() make sure that if the usb_configuration::interface is not full then a pointer after the last interface is NULL. Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget/g_ffs.c')
-rw-r--r--drivers/usb/gadget/g_ffs.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
index 4b0e4a040d6..d1af253a910 100644
--- a/drivers/usb/gadget/g_ffs.c
+++ b/drivers/usb/gadget/g_ffs.c
@@ -392,6 +392,17 @@ static int __gfs_do_config(struct usb_configuration *c,
if (unlikely(ret < 0))
return ret;
+ /* After previous do_configs there may be some invalid
+ * pointers in c->interface array. This happens every time
+ * a user space function with fewer interfaces than a user
+ * space function that was run before the new one is run. The
+ * compasit's set_config() assumes that if there is no more
+ * then MAX_CONFIG_INTERFACES interfaces in a configuration
+ * then there is a NULL pointer after the last interface in
+ * c->interface array. We need to make sure this is true. */
+ if (c->next_interface_id < ARRAY_SIZE(c->interface))
+ c->interface[c->next_interface_id] = NULL;
+
return 0;
}