Commit cbf286e8 authored by Mathias Nyman's avatar Mathias Nyman Committed by Greg Kroah-Hartman

xhci: fix unsafe memory usage in xhci tracing

Removes static char buffer usage in the following decode functions:
	xhci_decode_trb()
	xhci_decode_ptortsc()

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

Minor chanes are needed in xhci debugfs code as these functions are also
used there. Changes include moving XHCI_MSG_MAX definititon from
xhci-trace.h to xhci.h

Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20210820123503.2605901-2-mathias.nyman@linux.intel.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d7428bc2
...@@ -198,12 +198,13 @@ static void xhci_ring_dump_segment(struct seq_file *s, ...@@ -198,12 +198,13 @@ static void xhci_ring_dump_segment(struct seq_file *s,
int i; int i;
dma_addr_t dma; dma_addr_t dma;
union xhci_trb *trb; union xhci_trb *trb;
char str[XHCI_MSG_MAX];
for (i = 0; i < TRBS_PER_SEGMENT; i++) { for (i = 0; i < TRBS_PER_SEGMENT; i++) {
trb = &seg->trbs[i]; trb = &seg->trbs[i];
dma = seg->dma + i * sizeof(*trb); dma = seg->dma + i * sizeof(*trb);
seq_printf(s, "%pad: %s\n", &dma, seq_printf(s, "%pad: %s\n", &dma,
xhci_decode_trb(le32_to_cpu(trb->generic.field[0]), xhci_decode_trb(str, XHCI_MSG_MAX, le32_to_cpu(trb->generic.field[0]),
le32_to_cpu(trb->generic.field[1]), le32_to_cpu(trb->generic.field[1]),
le32_to_cpu(trb->generic.field[2]), le32_to_cpu(trb->generic.field[2]),
le32_to_cpu(trb->generic.field[3]))); le32_to_cpu(trb->generic.field[3])));
...@@ -341,9 +342,10 @@ static int xhci_portsc_show(struct seq_file *s, void *unused) ...@@ -341,9 +342,10 @@ static int xhci_portsc_show(struct seq_file *s, void *unused)
{ {
struct xhci_port *port = s->private; struct xhci_port *port = s->private;
u32 portsc; u32 portsc;
char str[XHCI_MSG_MAX];
portsc = readl(port->addr); portsc = readl(port->addr);
seq_printf(s, "%s\n", xhci_decode_portsc(portsc)); seq_printf(s, "%s\n", xhci_decode_portsc(str, portsc));
return 0; return 0;
} }
......
...@@ -25,8 +25,6 @@ ...@@ -25,8 +25,6 @@
#include "xhci.h" #include "xhci.h"
#include "xhci-dbgcap.h" #include "xhci-dbgcap.h"
#define XHCI_MSG_MAX 500
DECLARE_EVENT_CLASS(xhci_log_msg, DECLARE_EVENT_CLASS(xhci_log_msg,
TP_PROTO(struct va_format *vaf), TP_PROTO(struct va_format *vaf),
TP_ARGS(vaf), TP_ARGS(vaf),
...@@ -122,6 +120,7 @@ DECLARE_EVENT_CLASS(xhci_log_trb, ...@@ -122,6 +120,7 @@ DECLARE_EVENT_CLASS(xhci_log_trb,
__field(u32, field1) __field(u32, field1)
__field(u32, field2) __field(u32, field2)
__field(u32, field3) __field(u32, field3)
__dynamic_array(char, str, XHCI_MSG_MAX)
), ),
TP_fast_assign( TP_fast_assign(
__entry->type = ring->type; __entry->type = ring->type;
...@@ -131,7 +130,7 @@ DECLARE_EVENT_CLASS(xhci_log_trb, ...@@ -131,7 +130,7 @@ DECLARE_EVENT_CLASS(xhci_log_trb,
__entry->field3 = le32_to_cpu(trb->field[3]); __entry->field3 = le32_to_cpu(trb->field[3]);
), ),
TP_printk("%s: %s", xhci_ring_type_string(__entry->type), TP_printk("%s: %s", xhci_ring_type_string(__entry->type),
xhci_decode_trb(__entry->field0, __entry->field1, xhci_decode_trb(__get_str(str), XHCI_MSG_MAX, __entry->field0, __entry->field1,
__entry->field2, __entry->field3) __entry->field2, __entry->field3)
) )
); );
...@@ -523,6 +522,7 @@ DECLARE_EVENT_CLASS(xhci_log_portsc, ...@@ -523,6 +522,7 @@ DECLARE_EVENT_CLASS(xhci_log_portsc,
TP_STRUCT__entry( TP_STRUCT__entry(
__field(u32, portnum) __field(u32, portnum)
__field(u32, portsc) __field(u32, portsc)
__dynamic_array(char, str, XHCI_MSG_MAX)
), ),
TP_fast_assign( TP_fast_assign(
__entry->portnum = portnum; __entry->portnum = portnum;
...@@ -530,7 +530,7 @@ DECLARE_EVENT_CLASS(xhci_log_portsc, ...@@ -530,7 +530,7 @@ DECLARE_EVENT_CLASS(xhci_log_portsc,
), ),
TP_printk("port-%d: %s", TP_printk("port-%d: %s",
__entry->portnum, __entry->portnum,
xhci_decode_portsc(__entry->portsc) xhci_decode_portsc(__get_str(str), __entry->portsc)
) )
); );
......
...@@ -22,6 +22,9 @@ ...@@ -22,6 +22,9 @@
#include "xhci-ext-caps.h" #include "xhci-ext-caps.h"
#include "pci-quirks.h" #include "pci-quirks.h"
/* max buffer size for trace and debug messages */
#define XHCI_MSG_MAX 500
/* xHCI PCI Configuration Registers */ /* xHCI PCI Configuration Registers */
#define XHCI_SBRN_OFFSET (0x60) #define XHCI_SBRN_OFFSET (0x60)
...@@ -2235,15 +2238,14 @@ static inline char *xhci_slot_state_string(u32 state) ...@@ -2235,15 +2238,14 @@ static inline char *xhci_slot_state_string(u32 state)
} }
} }
static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, static inline const char *xhci_decode_trb(char *str, size_t size,
u32 field3) u32 field0, u32 field1, u32 field2, u32 field3)
{ {
static char str[256];
int type = TRB_FIELD_TO_TYPE(field3); int type = TRB_FIELD_TO_TYPE(field3);
switch (type) { switch (type) {
case TRB_LINK: case TRB_LINK:
sprintf(str, snprintf(str, size,
"LINK %08x%08x intr %d type '%s' flags %c:%c:%c:%c", "LINK %08x%08x intr %d type '%s' flags %c:%c:%c:%c",
field1, field0, GET_INTR_TARGET(field2), field1, field0, GET_INTR_TARGET(field2),
xhci_trb_type_string(type), xhci_trb_type_string(type),
...@@ -2260,7 +2262,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, ...@@ -2260,7 +2262,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
case TRB_HC_EVENT: case TRB_HC_EVENT:
case TRB_DEV_NOTE: case TRB_DEV_NOTE:
case TRB_MFINDEX_WRAP: case TRB_MFINDEX_WRAP:
sprintf(str, snprintf(str, size,
"TRB %08x%08x status '%s' len %d slot %d ep %d type '%s' flags %c:%c", "TRB %08x%08x status '%s' len %d slot %d ep %d type '%s' flags %c:%c",
field1, field0, field1, field0,
xhci_trb_comp_code_string(GET_COMP_CODE(field2)), xhci_trb_comp_code_string(GET_COMP_CODE(field2)),
...@@ -2273,7 +2275,8 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, ...@@ -2273,7 +2275,8 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
break; break;
case TRB_SETUP: case TRB_SETUP:
sprintf(str, "bRequestType %02x bRequest %02x wValue %02x%02x wIndex %02x%02x wLength %d length %d TD size %d intr %d type '%s' flags %c:%c:%c", snprintf(str, size,
"bRequestType %02x bRequest %02x wValue %02x%02x wIndex %02x%02x wLength %d length %d TD size %d intr %d type '%s' flags %c:%c:%c",
field0 & 0xff, field0 & 0xff,
(field0 & 0xff00) >> 8, (field0 & 0xff00) >> 8,
(field0 & 0xff000000) >> 24, (field0 & 0xff000000) >> 24,
...@@ -2290,7 +2293,8 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, ...@@ -2290,7 +2293,8 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
field3 & TRB_CYCLE ? 'C' : 'c'); field3 & TRB_CYCLE ? 'C' : 'c');
break; break;
case TRB_DATA: case TRB_DATA:
sprintf(str, "Buffer %08x%08x length %d TD size %d intr %d type '%s' flags %c:%c:%c:%c:%c:%c:%c", snprintf(str, size,
"Buffer %08x%08x length %d TD size %d intr %d type '%s' flags %c:%c:%c:%c:%c:%c:%c",
field1, field0, TRB_LEN(field2), GET_TD_SIZE(field2), field1, field0, TRB_LEN(field2), GET_TD_SIZE(field2),
GET_INTR_TARGET(field2), GET_INTR_TARGET(field2),
xhci_trb_type_string(type), xhci_trb_type_string(type),
...@@ -2303,7 +2307,8 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, ...@@ -2303,7 +2307,8 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
field3 & TRB_CYCLE ? 'C' : 'c'); field3 & TRB_CYCLE ? 'C' : 'c');
break; break;
case TRB_STATUS: case TRB_STATUS:
sprintf(str, "Buffer %08x%08x length %d TD size %d intr %d type '%s' flags %c:%c:%c:%c", snprintf(str, size,
"Buffer %08x%08x length %d TD size %d intr %d type '%s' flags %c:%c:%c:%c",
field1, field0, TRB_LEN(field2), GET_TD_SIZE(field2), field1, field0, TRB_LEN(field2), GET_TD_SIZE(field2),
GET_INTR_TARGET(field2), GET_INTR_TARGET(field2),
xhci_trb_type_string(type), xhci_trb_type_string(type),
...@@ -2316,7 +2321,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, ...@@ -2316,7 +2321,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
case TRB_ISOC: case TRB_ISOC:
case TRB_EVENT_DATA: case TRB_EVENT_DATA:
case TRB_TR_NOOP: case TRB_TR_NOOP:
sprintf(str, snprintf(str, size,
"Buffer %08x%08x length %d TD size %d intr %d type '%s' flags %c:%c:%c:%c:%c:%c:%c:%c", "Buffer %08x%08x length %d TD size %d intr %d type '%s' flags %c:%c:%c:%c:%c:%c:%c:%c",
field1, field0, TRB_LEN(field2), GET_TD_SIZE(field2), field1, field0, TRB_LEN(field2), GET_TD_SIZE(field2),
GET_INTR_TARGET(field2), GET_INTR_TARGET(field2),
...@@ -2333,21 +2338,21 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, ...@@ -2333,21 +2338,21 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
case TRB_CMD_NOOP: case TRB_CMD_NOOP:
case TRB_ENABLE_SLOT: case TRB_ENABLE_SLOT:
sprintf(str, snprintf(str, size,
"%s: flags %c", "%s: flags %c",
xhci_trb_type_string(type), xhci_trb_type_string(type),
field3 & TRB_CYCLE ? 'C' : 'c'); field3 & TRB_CYCLE ? 'C' : 'c');
break; break;
case TRB_DISABLE_SLOT: case TRB_DISABLE_SLOT:
case TRB_NEG_BANDWIDTH: case TRB_NEG_BANDWIDTH:
sprintf(str, snprintf(str, size,
"%s: slot %d flags %c", "%s: slot %d flags %c",
xhci_trb_type_string(type), xhci_trb_type_string(type),
TRB_TO_SLOT_ID(field3), TRB_TO_SLOT_ID(field3),
field3 & TRB_CYCLE ? 'C' : 'c'); field3 & TRB_CYCLE ? 'C' : 'c');
break; break;
case TRB_ADDR_DEV: case TRB_ADDR_DEV:
sprintf(str, snprintf(str, size,
"%s: ctx %08x%08x slot %d flags %c:%c", "%s: ctx %08x%08x slot %d flags %c:%c",
xhci_trb_type_string(type), xhci_trb_type_string(type),
field1, field0, field1, field0,
...@@ -2356,7 +2361,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, ...@@ -2356,7 +2361,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
field3 & TRB_CYCLE ? 'C' : 'c'); field3 & TRB_CYCLE ? 'C' : 'c');
break; break;
case TRB_CONFIG_EP: case TRB_CONFIG_EP:
sprintf(str, snprintf(str, size,
"%s: ctx %08x%08x slot %d flags %c:%c", "%s: ctx %08x%08x slot %d flags %c:%c",
xhci_trb_type_string(type), xhci_trb_type_string(type),
field1, field0, field1, field0,
...@@ -2365,7 +2370,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, ...@@ -2365,7 +2370,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
field3 & TRB_CYCLE ? 'C' : 'c'); field3 & TRB_CYCLE ? 'C' : 'c');
break; break;
case TRB_EVAL_CONTEXT: case TRB_EVAL_CONTEXT:
sprintf(str, snprintf(str, size,
"%s: ctx %08x%08x slot %d flags %c", "%s: ctx %08x%08x slot %d flags %c",
xhci_trb_type_string(type), xhci_trb_type_string(type),
field1, field0, field1, field0,
...@@ -2373,7 +2378,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, ...@@ -2373,7 +2378,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
field3 & TRB_CYCLE ? 'C' : 'c'); field3 & TRB_CYCLE ? 'C' : 'c');
break; break;
case TRB_RESET_EP: case TRB_RESET_EP:
sprintf(str, snprintf(str, size,
"%s: ctx %08x%08x slot %d ep %d flags %c:%c", "%s: ctx %08x%08x slot %d ep %d flags %c:%c",
xhci_trb_type_string(type), xhci_trb_type_string(type),
field1, field0, field1, field0,
...@@ -2394,7 +2399,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, ...@@ -2394,7 +2399,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
field3 & TRB_CYCLE ? 'C' : 'c'); field3 & TRB_CYCLE ? 'C' : 'c');
break; break;
case TRB_SET_DEQ: case TRB_SET_DEQ:
sprintf(str, snprintf(str, size,
"%s: deq %08x%08x stream %d slot %d ep %d flags %c", "%s: deq %08x%08x stream %d slot %d ep %d flags %c",
xhci_trb_type_string(type), xhci_trb_type_string(type),
field1, field0, field1, field0,
...@@ -2405,14 +2410,14 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, ...@@ -2405,14 +2410,14 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
field3 & TRB_CYCLE ? 'C' : 'c'); field3 & TRB_CYCLE ? 'C' : 'c');
break; break;
case TRB_RESET_DEV: case TRB_RESET_DEV:
sprintf(str, snprintf(str, size,
"%s: slot %d flags %c", "%s: slot %d flags %c",
xhci_trb_type_string(type), xhci_trb_type_string(type),
TRB_TO_SLOT_ID(field3), TRB_TO_SLOT_ID(field3),
field3 & TRB_CYCLE ? 'C' : 'c'); field3 & TRB_CYCLE ? 'C' : 'c');
break; break;
case TRB_FORCE_EVENT: case TRB_FORCE_EVENT:
sprintf(str, snprintf(str, size,
"%s: event %08x%08x vf intr %d vf id %d flags %c", "%s: event %08x%08x vf intr %d vf id %d flags %c",
xhci_trb_type_string(type), xhci_trb_type_string(type),
field1, field0, field1, field0,
...@@ -2421,14 +2426,14 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, ...@@ -2421,14 +2426,14 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
field3 & TRB_CYCLE ? 'C' : 'c'); field3 & TRB_CYCLE ? 'C' : 'c');
break; break;
case TRB_SET_LT: case TRB_SET_LT:
sprintf(str, snprintf(str, size,
"%s: belt %d flags %c", "%s: belt %d flags %c",
xhci_trb_type_string(type), xhci_trb_type_string(type),
TRB_TO_BELT(field3), TRB_TO_BELT(field3),
field3 & TRB_CYCLE ? 'C' : 'c'); field3 & TRB_CYCLE ? 'C' : 'c');
break; break;
case TRB_GET_BW: case TRB_GET_BW:
sprintf(str, snprintf(str, size,
"%s: ctx %08x%08x slot %d speed %d flags %c", "%s: ctx %08x%08x slot %d speed %d flags %c",
xhci_trb_type_string(type), xhci_trb_type_string(type),
field1, field0, field1, field0,
...@@ -2437,7 +2442,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, ...@@ -2437,7 +2442,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
field3 & TRB_CYCLE ? 'C' : 'c'); field3 & TRB_CYCLE ? 'C' : 'c');
break; break;
case TRB_FORCE_HEADER: case TRB_FORCE_HEADER:
sprintf(str, snprintf(str, size,
"%s: info %08x%08x%08x pkt type %d roothub port %d flags %c", "%s: info %08x%08x%08x pkt type %d roothub port %d flags %c",
xhci_trb_type_string(type), xhci_trb_type_string(type),
field2, field1, field0 & 0xffffffe0, field2, field1, field0 & 0xffffffe0,
...@@ -2446,7 +2451,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2, ...@@ -2446,7 +2451,7 @@ static inline const char *xhci_decode_trb(u32 field0, u32 field1, u32 field2,
field3 & TRB_CYCLE ? 'C' : 'c'); field3 & TRB_CYCLE ? 'C' : 'c');
break; break;
default: default:
sprintf(str, snprintf(str, size,
"type '%s' -> raw %08x %08x %08x %08x", "type '%s' -> raw %08x %08x %08x %08x",
xhci_trb_type_string(type), xhci_trb_type_string(type),
field0, field1, field2, field3); field0, field1, field2, field3);
...@@ -2571,9 +2576,8 @@ static inline const char *xhci_portsc_link_state_string(u32 portsc) ...@@ -2571,9 +2576,8 @@ static inline const char *xhci_portsc_link_state_string(u32 portsc)
return "Unknown"; return "Unknown";
} }
static inline const char *xhci_decode_portsc(u32 portsc) static inline const char *xhci_decode_portsc(char *str, u32 portsc)
{ {
static char str[256];
int ret; int ret;
ret = sprintf(str, "%s %s %s Link:%s PortSpeed:%d ", ret = sprintf(str, "%s %s %s Link:%s PortSpeed:%d ",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment