drivers:misc:ti-st: protect against bad packets
authorGigi Joseph <[email protected]>
Fri, 9 Jan 2015 03:49:03 +0000 (03:49 +0000)
committerGreg Kroah-Hartman <[email protected]>
Mon, 12 Jan 2015 13:04:11 +0000 (05:04 -0800)
We encounter situations where we got bad packet type from the
UART (probably due to platform problem or UART driver issues)
which caused us out of boundary array access,
which eventually led to kernel panic.

Signed-off-by: Amir Ayun <[email protected]>
Signed-off-by: Pavan Savoy <[email protected]>
Signed-off-by: Leonid Iziumtsev <[email protected]>
Signed-off-by: Gigi Joseph <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
drivers/misc/ti-st/st_core.c

index 54be83d3efdd682e8025577c5464f2c3807739c0..c8c6a363069cc189b799bcf376fcf6991cc05e6e 100644 (file)
@@ -343,12 +343,26 @@ void st_int_recv(void *disc_data,
                        /* Unknow packet? */
                default:
                        type = *ptr;
-                       if (st_gdata->list[type] == NULL) {
-                               pr_err("chip/interface misbehavior dropping"
-                                       " frame starting with 0x%02x", type);
-                               goto done;
 
+                       /* Default case means non-HCILL packets,
+                        * possibilities are packets for:
+                        * (a) valid protocol -  Supported Protocols within
+                        *     the ST_MAX_CHANNELS.
+                        * (b) registered protocol - Checked by
+                        *     "st_gdata->list[type] == NULL)" are supported
+                        *     protocols only.
+                        *  Rules out any invalid protocol and
+                        *  unregistered protocols with channel ID < 16.
+                        */
+
+                       if ((type >= ST_MAX_CHANNELS) ||
+                                       (st_gdata->list[type] == NULL)) {
+                               pr_err("chip/interface misbehavior: "
+                                               "dropping frame starting "
+                                               "with 0x%02x\n", type);
+                               goto done;
                        }
+
                        st_gdata->rx_skb = alloc_skb(
                                        st_gdata->list[type]->max_frame_size,
                                        GFP_ATOMIC);
@@ -893,5 +907,3 @@ void st_core_exit(struct st_data_s *st_gdata)
                kfree(st_gdata);
        }
 }
-
-