OSDN Git Service

usb: pd: avoid out-of-bounds access when reading PDOs
authorJack Pham <jackp@codeaurora.org>
Mon, 23 Oct 2017 16:47:49 +0000 (09:47 -0700)
committerJack Pham <jackp@codeaurora.org>
Thu, 18 Jan 2018 02:04:52 +0000 (18:04 -0800)
Most often a source will send fewer than the maximum number
of PDOs (7). Since the rx_msg buffer is now allocated up to
the size of the actual data, honor the rx_msg->data_len when
copying to pd->received_pdos rather than always 28 bytes.
This fixes out-of-bounds read access as reported by KASAN.

Change-Id: I5f98f7ccba027c1ab436ccf6fc822e2a319bafa1
Signed-off-by: Jack Pham <jackp@codeaurora.org>
drivers/usb/pd/policy_engine.c

index 7225bfd..aef8de0 100644 (file)
@@ -2253,8 +2253,11 @@ static void usbpd_sm(struct work_struct *w)
                                        &val);
 
                        /* save the PDOs so userspace can further evaluate */
-                       memcpy(&pd->received_pdos, rx_msg->payload,
+                       memset(&pd->received_pdos, 0,
                                        sizeof(pd->received_pdos));
+                       memcpy(&pd->received_pdos, rx_msg->payload,
+                                       min_t(size_t, rx_msg->data_len,
+                                               sizeof(pd->received_pdos)));
                        pd->src_cap_id++;
 
                        usbpd_set_state(pd, PE_SNK_EVALUATE_CAPABILITY);
@@ -2365,8 +2368,11 @@ static void usbpd_sm(struct work_struct *w)
        case PE_SNK_READY:
                if (IS_DATA(rx_msg, MSG_SOURCE_CAPABILITIES)) {
                        /* save the PDOs so userspace can further evaluate */
-                       memcpy(&pd->received_pdos, rx_msg->payload,
+                       memset(&pd->received_pdos, 0,
                                        sizeof(pd->received_pdos));
+                       memcpy(&pd->received_pdos, rx_msg->payload,
+                                       min_t(size_t, rx_msg->data_len,
+                                               sizeof(pd->received_pdos)));
                        pd->src_cap_id++;
 
                        usbpd_set_state(pd, PE_SNK_EVALUATE_CAPABILITY);