xhci: fix even more unsafe memory usage in xhci tracing
authorMathias Nyman <mathias.nyman@linux.intel.com>
Fri, 20 Aug 2021 12:34:59 +0000 (15:34 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 12 Sep 2021 06:58:28 +0000 (08:58 +0200)
commit 4843b4b5ec64b875a5e334f280508f1f75e7d3e4 upstream.

Removes static char buffer usage in the following decode functions:
xhci_decode_ctrl_ctx()
xhci_decode_slot_context()
xhci_decode_usbsts()
xhci_decode_doorbell()
xhci_decode_ep_context()

Caller must provide a buffer to use.
In tracing use __get_str() as recommended to pass buffer.

Minor changes are needed in other xhci code as these functions are also
used elsewhere

Cc: <stable@vger.kernel.org>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20210820123503.2605901-3-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/xhci-debugfs.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci-trace.h
drivers/usb/host/xhci.h

index 2c0fda5..d2c10ce 100644 (file)
@@ -260,11 +260,13 @@ static int xhci_slot_context_show(struct seq_file *s, void *unused)
        struct xhci_slot_ctx    *slot_ctx;
        struct xhci_slot_priv   *priv = s->private;
        struct xhci_virt_device *dev = priv->dev;
+       char                    str[XHCI_MSG_MAX];
 
        xhci = hcd_to_xhci(bus_to_hcd(dev->udev->bus));
        slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx);
        seq_printf(s, "%pad: %s\n", &dev->out_ctx->dma,
-                  xhci_decode_slot_context(le32_to_cpu(slot_ctx->dev_info),
+                  xhci_decode_slot_context(str,
+                                           le32_to_cpu(slot_ctx->dev_info),
                                            le32_to_cpu(slot_ctx->dev_info2),
                                            le32_to_cpu(slot_ctx->tt_info),
                                            le32_to_cpu(slot_ctx->dev_state)));
@@ -280,6 +282,7 @@ static int xhci_endpoint_context_show(struct seq_file *s, void *unused)
        struct xhci_ep_ctx      *ep_ctx;
        struct xhci_slot_priv   *priv = s->private;
        struct xhci_virt_device *dev = priv->dev;
+       char                    str[XHCI_MSG_MAX];
 
        xhci = hcd_to_xhci(bus_to_hcd(dev->udev->bus));
 
@@ -287,7 +290,8 @@ static int xhci_endpoint_context_show(struct seq_file *s, void *unused)
                ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index);
                dma = dev->out_ctx->dma + (ep_index + 1) * CTX_SIZE(xhci->hcc_params);
                seq_printf(s, "%pad: %s\n", &dma,
-                          xhci_decode_ep_context(le32_to_cpu(ep_ctx->ep_info),
+                          xhci_decode_ep_context(str,
+                                                 le32_to_cpu(ep_ctx->ep_info),
                                                  le32_to_cpu(ep_ctx->ep_info2),
                                                  le64_to_cpu(ep_ctx->deq),
                                                  le32_to_cpu(ep_ctx->tx_info)));
index 53059ee..dc2068e 100644 (file)
@@ -1005,6 +1005,7 @@ void xhci_stop_endpoint_command_watchdog(struct timer_list *t)
        struct xhci_hcd *xhci = ep->xhci;
        unsigned long flags;
        u32 usbsts;
+       char str[XHCI_MSG_MAX];
 
        spin_lock_irqsave(&xhci->lock, flags);
 
@@ -1018,7 +1019,7 @@ void xhci_stop_endpoint_command_watchdog(struct timer_list *t)
        usbsts = readl(&xhci->op_regs->status);
 
        xhci_warn(xhci, "xHCI host not responding to stop endpoint command.\n");
-       xhci_warn(xhci, "USBSTS:%s\n", xhci_decode_usbsts(usbsts));
+       xhci_warn(xhci, "USBSTS:%s\n", xhci_decode_usbsts(str, usbsts));
 
        ep->ep_state &= ~EP_STOP_CMD_PENDING;
 
index 627abd2..365cadf 100644 (file)
@@ -323,6 +323,7 @@ DECLARE_EVENT_CLASS(xhci_log_ep_ctx,
                __field(u32, info2)
                __field(u64, deq)
                __field(u32, tx_info)
+               __dynamic_array(char, str, XHCI_MSG_MAX)
        ),
        TP_fast_assign(
                __entry->info = le32_to_cpu(ctx->ep_info);
@@ -330,8 +331,8 @@ DECLARE_EVENT_CLASS(xhci_log_ep_ctx,
                __entry->deq = le64_to_cpu(ctx->deq);
                __entry->tx_info = le32_to_cpu(ctx->tx_info);
        ),
-       TP_printk("%s", xhci_decode_ep_context(__entry->info,
-               __entry->info2, __entry->deq, __entry->tx_info)
+       TP_printk("%s", xhci_decode_ep_context(__get_str(str),
+               __entry->info, __entry->info2, __entry->deq, __entry->tx_info)
        )
 );
 
@@ -368,6 +369,7 @@ DECLARE_EVENT_CLASS(xhci_log_slot_ctx,
                __field(u32, info2)
                __field(u32, tt_info)
                __field(u32, state)
+               __dynamic_array(char, str, XHCI_MSG_MAX)
        ),
        TP_fast_assign(
                __entry->info = le32_to_cpu(ctx->dev_info);
@@ -375,9 +377,9 @@ DECLARE_EVENT_CLASS(xhci_log_slot_ctx,
                __entry->tt_info = le64_to_cpu(ctx->tt_info);
                __entry->state = le32_to_cpu(ctx->dev_state);
        ),
-       TP_printk("%s", xhci_decode_slot_context(__entry->info,
-                       __entry->info2, __entry->tt_info,
-                       __entry->state)
+       TP_printk("%s", xhci_decode_slot_context(__get_str(str),
+                       __entry->info, __entry->info2,
+                       __entry->tt_info, __entry->state)
        )
 );
 
@@ -432,12 +434,13 @@ DECLARE_EVENT_CLASS(xhci_log_ctrl_ctx,
        TP_STRUCT__entry(
                __field(u32, drop)
                __field(u32, add)
+               __dynamic_array(char, str, XHCI_MSG_MAX)
        ),
        TP_fast_assign(
                __entry->drop = le32_to_cpu(ctrl_ctx->drop_flags);
                __entry->add = le32_to_cpu(ctrl_ctx->add_flags);
        ),
-       TP_printk("%s", xhci_decode_ctrl_ctx(__entry->drop, __entry->add)
+       TP_printk("%s", xhci_decode_ctrl_ctx(__get_str(str), __entry->drop, __entry->add)
        )
 );
 
@@ -555,13 +558,14 @@ DECLARE_EVENT_CLASS(xhci_log_doorbell,
        TP_STRUCT__entry(
                __field(u32, slot)
                __field(u32, doorbell)
+               __dynamic_array(char, str, XHCI_MSG_MAX)
        ),
        TP_fast_assign(
                __entry->slot = slot;
                __entry->doorbell = doorbell;
        ),
        TP_printk("Ring doorbell for %s",
-               xhci_decode_doorbell(__entry->slot, __entry->doorbell)
+                 xhci_decode_doorbell(__get_str(str), __entry->slot, __entry->doorbell)
        )
 );
 
index c1865a1..8ff91fd 100644 (file)
@@ -2443,10 +2443,9 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
        return str;
 }
 
-static inline const char *xhci_decode_ctrl_ctx(unsigned long drop,
-                                              unsigned long add)
+static inline const char *xhci_decode_ctrl_ctx(char *str,
+               unsigned long drop, unsigned long add)
 {
-       static char     str[1024];
        unsigned int    bit;
        int             ret = 0;
 
@@ -2472,10 +2471,9 @@ static inline const char *xhci_decode_ctrl_ctx(unsigned long drop,
        return str;
 }
 
-static inline const char *xhci_decode_slot_context(u32 info, u32 info2,
-               u32 tt_info, u32 state)
+static inline const char *xhci_decode_slot_context(char *str,
+               u32 info, u32 info2, u32 tt_info, u32 state)
 {
-       static char str[1024];
        u32 speed;
        u32 hub;
        u32 mtt;
@@ -2605,9 +2603,8 @@ static inline const char *xhci_decode_portsc(u32 portsc)
        return str;
 }
 
-static inline const char *xhci_decode_usbsts(u32 usbsts)
+static inline const char *xhci_decode_usbsts(char *str, u32 usbsts)
 {
-       static char str[256];
        int ret = 0;
 
        if (usbsts == ~(u32)0)
@@ -2634,9 +2631,8 @@ static inline const char *xhci_decode_usbsts(u32 usbsts)
        return str;
 }
 
-static inline const char *xhci_decode_doorbell(u32 slot, u32 doorbell)
+static inline const char *xhci_decode_doorbell(char *str, u32 slot, u32 doorbell)
 {
-       static char str[256];
        u8 ep;
        u16 stream;
        int ret;
@@ -2703,10 +2699,9 @@ static inline const char *xhci_ep_type_string(u8 type)
        }
 }
 
-static inline const char *xhci_decode_ep_context(u32 info, u32 info2, u64 deq,
-               u32 tx_info)
+static inline const char *xhci_decode_ep_context(char *str, u32 info,
+               u32 info2, u64 deq, u32 tx_info)
 {
-       static char str[1024];
        int ret;
 
        u32 esit;