usb: cdnsp: Replace snprintf() with the safer scnprintf() variant
There is a general misunderstanding amongst engineers that {v}snprintf() returns the length of the data *actually* encoded into the destination array. However, as per the C99 standard {v}snprintf() really returns the length of the data that *would have been* written if there were enough space for it. This misunderstanding has led to buffer-overruns in the past. It's generally considered safer to use the {v}scnprintf() variants in their place (or even sprintf() in simple cases). So let's do that. The uses in this file all seem to assume that data *has been* written! Link: https://lwn.net/Articles/69419/ Link: https://github.com/KSPP/linux/issues/105 Cc: Pawel Laszczak <pawell@cadence.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: linux-usb@vger.kernel.org Signed-off-by: Lee Jones <lee@kernel.org> Link: https://lore.kernel.org/r/20231130105459.3208986-3-lee@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
36d8aef52d
commit
b385ef088c
@ -187,7 +187,7 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0,
|
||||
|
||||
switch (type) {
|
||||
case TRB_LINK:
|
||||
ret = snprintf(str, size,
|
||||
ret = scnprintf(str, size,
|
||||
"LINK %08x%08x intr %ld type '%s' flags %c:%c:%c:%c",
|
||||
field1, field0, GET_INTR_TARGET(field2),
|
||||
cdnsp_trb_type_string(type),
|
||||
@ -200,7 +200,7 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0,
|
||||
case TRB_COMPLETION:
|
||||
case TRB_PORT_STATUS:
|
||||
case TRB_HC_EVENT:
|
||||
ret = snprintf(str, size,
|
||||
ret = scnprintf(str, size,
|
||||
"ep%d%s(%d) type '%s' TRB %08x%08x status '%s'"
|
||||
" len %ld slot %ld flags %c:%c",
|
||||
ep_num, ep_id % 2 ? "out" : "in",
|
||||
@ -212,12 +212,12 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0,
|
||||
field3 & TRB_CYCLE ? 'C' : 'c');
|
||||
break;
|
||||
case TRB_MFINDEX_WRAP:
|
||||
ret = snprintf(str, size, "%s: flags %c",
|
||||
ret = scnprintf(str, size, "%s: flags %c",
|
||||
cdnsp_trb_type_string(type),
|
||||
field3 & TRB_CYCLE ? 'C' : 'c');
|
||||
break;
|
||||
case TRB_SETUP:
|
||||
ret = snprintf(str, size,
|
||||
ret = scnprintf(str, size,
|
||||
"type '%s' bRequestType %02x bRequest %02x "
|
||||
"wValue %02x%02x wIndex %02x%02x wLength %d "
|
||||
"length %ld TD size %ld intr %ld Setup ID %ld "
|
||||
@ -239,7 +239,7 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0,
|
||||
field3 & TRB_CYCLE ? 'C' : 'c');
|
||||
break;
|
||||
case TRB_DATA:
|
||||
ret = snprintf(str, size,
|
||||
ret = scnprintf(str, size,
|
||||
"type '%s' Buffer %08x%08x length %ld TD size %ld "
|
||||
"intr %ld flags %c:%c:%c:%c:%c:%c:%c",
|
||||
cdnsp_trb_type_string(type),
|
||||
@ -255,7 +255,7 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0,
|
||||
field3 & TRB_CYCLE ? 'C' : 'c');
|
||||
break;
|
||||
case TRB_STATUS:
|
||||
ret = snprintf(str, size,
|
||||
ret = scnprintf(str, size,
|
||||
"Buffer %08x%08x length %ld TD size %ld intr"
|
||||
"%ld type '%s' flags %c:%c:%c:%c",
|
||||
field1, field0, TRB_LEN(field2),
|
||||
@ -271,7 +271,7 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0,
|
||||
case TRB_ISOC:
|
||||
case TRB_EVENT_DATA:
|
||||
case TRB_TR_NOOP:
|
||||
ret = snprintf(str, size,
|
||||
ret = scnprintf(str, size,
|
||||
"type '%s' Buffer %08x%08x length %ld "
|
||||
"TD size %ld intr %ld "
|
||||
"flags %c:%c:%c:%c:%c:%c:%c:%c:%c",
|
||||
@ -291,18 +291,18 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0,
|
||||
break;
|
||||
case TRB_CMD_NOOP:
|
||||
case TRB_ENABLE_SLOT:
|
||||
ret = snprintf(str, size, "%s: flags %c",
|
||||
ret = scnprintf(str, size, "%s: flags %c",
|
||||
cdnsp_trb_type_string(type),
|
||||
field3 & TRB_CYCLE ? 'C' : 'c');
|
||||
break;
|
||||
case TRB_DISABLE_SLOT:
|
||||
ret = snprintf(str, size, "%s: slot %ld flags %c",
|
||||
ret = scnprintf(str, size, "%s: slot %ld flags %c",
|
||||
cdnsp_trb_type_string(type),
|
||||
TRB_TO_SLOT_ID(field3),
|
||||
field3 & TRB_CYCLE ? 'C' : 'c');
|
||||
break;
|
||||
case TRB_ADDR_DEV:
|
||||
ret = snprintf(str, size,
|
||||
ret = scnprintf(str, size,
|
||||
"%s: ctx %08x%08x slot %ld flags %c:%c",
|
||||
cdnsp_trb_type_string(type), field1, field0,
|
||||
TRB_TO_SLOT_ID(field3),
|
||||
@ -310,7 +310,7 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0,
|
||||
field3 & TRB_CYCLE ? 'C' : 'c');
|
||||
break;
|
||||
case TRB_CONFIG_EP:
|
||||
ret = snprintf(str, size,
|
||||
ret = scnprintf(str, size,
|
||||
"%s: ctx %08x%08x slot %ld flags %c:%c",
|
||||
cdnsp_trb_type_string(type), field1, field0,
|
||||
TRB_TO_SLOT_ID(field3),
|
||||
@ -318,7 +318,7 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0,
|
||||
field3 & TRB_CYCLE ? 'C' : 'c');
|
||||
break;
|
||||
case TRB_EVAL_CONTEXT:
|
||||
ret = snprintf(str, size,
|
||||
ret = scnprintf(str, size,
|
||||
"%s: ctx %08x%08x slot %ld flags %c",
|
||||
cdnsp_trb_type_string(type), field1, field0,
|
||||
TRB_TO_SLOT_ID(field3),
|
||||
@ -326,7 +326,7 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0,
|
||||
break;
|
||||
case TRB_RESET_EP:
|
||||
case TRB_HALT_ENDPOINT:
|
||||
ret = snprintf(str, size,
|
||||
ret = scnprintf(str, size,
|
||||
"%s: ep%d%s(%d) ctx %08x%08x slot %ld flags %c",
|
||||
cdnsp_trb_type_string(type),
|
||||
ep_num, ep_id % 2 ? "out" : "in",
|
||||
@ -335,7 +335,7 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0,
|
||||
field3 & TRB_CYCLE ? 'C' : 'c');
|
||||
break;
|
||||
case TRB_STOP_RING:
|
||||
ret = snprintf(str, size,
|
||||
ret = scnprintf(str, size,
|
||||
"%s: ep%d%s(%d) slot %ld sp %d flags %c",
|
||||
cdnsp_trb_type_string(type),
|
||||
ep_num, ep_id % 2 ? "out" : "in",
|
||||
@ -345,7 +345,7 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0,
|
||||
field3 & TRB_CYCLE ? 'C' : 'c');
|
||||
break;
|
||||
case TRB_SET_DEQ:
|
||||
ret = snprintf(str, size,
|
||||
ret = scnprintf(str, size,
|
||||
"%s: ep%d%s(%d) deq %08x%08x stream %ld slot %ld flags %c",
|
||||
cdnsp_trb_type_string(type),
|
||||
ep_num, ep_id % 2 ? "out" : "in",
|
||||
@ -355,7 +355,7 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0,
|
||||
field3 & TRB_CYCLE ? 'C' : 'c');
|
||||
break;
|
||||
case TRB_RESET_DEV:
|
||||
ret = snprintf(str, size, "%s: slot %ld flags %c",
|
||||
ret = scnprintf(str, size, "%s: slot %ld flags %c",
|
||||
cdnsp_trb_type_string(type),
|
||||
TRB_TO_SLOT_ID(field3),
|
||||
field3 & TRB_CYCLE ? 'C' : 'c');
|
||||
@ -363,7 +363,7 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0,
|
||||
case TRB_ENDPOINT_NRDY:
|
||||
temp = TRB_TO_HOST_STREAM(field2);
|
||||
|
||||
ret = snprintf(str, size,
|
||||
ret = scnprintf(str, size,
|
||||
"%s: ep%d%s(%d) H_SID %x%s%s D_SID %lx flags %c:%c",
|
||||
cdnsp_trb_type_string(type),
|
||||
ep_num, ep_id % 2 ? "out" : "in",
|
||||
@ -375,14 +375,14 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0,
|
||||
field3 & TRB_CYCLE ? 'C' : 'c');
|
||||
break;
|
||||
default:
|
||||
ret = snprintf(str, size,
|
||||
ret = scnprintf(str, size,
|
||||
"type '%s' -> raw %08x %08x %08x %08x",
|
||||
cdnsp_trb_type_string(type),
|
||||
field0, field1, field2, field3);
|
||||
}
|
||||
|
||||
if (ret >= size)
|
||||
pr_info("CDNSP: buffer overflowed.\n");
|
||||
if (ret == size - 1)
|
||||
pr_info("CDNSP: buffer may be truncated.\n");
|
||||
|
||||
return str;
|
||||
}
|
||||
@ -465,7 +465,7 @@ static inline const char *cdnsp_decode_portsc(char *str, size_t size,
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = snprintf(str, size, "%s %s %s Link:%s PortSpeed:%d ",
|
||||
ret = scnprintf(str, size, "%s %s %s Link:%s PortSpeed:%d ",
|
||||
portsc & PORT_POWER ? "Powered" : "Powered-off",
|
||||
portsc & PORT_CONNECT ? "Connected" : "Not-connected",
|
||||
portsc & PORT_PED ? "Enabled" : "Disabled",
|
||||
@ -473,24 +473,24 @@ static inline const char *cdnsp_decode_portsc(char *str, size_t size,
|
||||
DEV_PORT_SPEED(portsc));
|
||||
|
||||
if (portsc & PORT_RESET)
|
||||
ret += snprintf(str + ret, size - ret, "In-Reset ");
|
||||
ret += scnprintf(str + ret, size - ret, "In-Reset ");
|
||||
|
||||
ret += snprintf(str + ret, size - ret, "Change: ");
|
||||
ret += scnprintf(str + ret, size - ret, "Change: ");
|
||||
if (portsc & PORT_CSC)
|
||||
ret += snprintf(str + ret, size - ret, "CSC ");
|
||||
ret += scnprintf(str + ret, size - ret, "CSC ");
|
||||
if (portsc & PORT_WRC)
|
||||
ret += snprintf(str + ret, size - ret, "WRC ");
|
||||
ret += scnprintf(str + ret, size - ret, "WRC ");
|
||||
if (portsc & PORT_RC)
|
||||
ret += snprintf(str + ret, size - ret, "PRC ");
|
||||
ret += scnprintf(str + ret, size - ret, "PRC ");
|
||||
if (portsc & PORT_PLC)
|
||||
ret += snprintf(str + ret, size - ret, "PLC ");
|
||||
ret += scnprintf(str + ret, size - ret, "PLC ");
|
||||
if (portsc & PORT_CEC)
|
||||
ret += snprintf(str + ret, size - ret, "CEC ");
|
||||
ret += snprintf(str + ret, size - ret, "Wake: ");
|
||||
ret += scnprintf(str + ret, size - ret, "CEC ");
|
||||
ret += scnprintf(str + ret, size - ret, "Wake: ");
|
||||
if (portsc & PORT_WKCONN_E)
|
||||
ret += snprintf(str + ret, size - ret, "WCE ");
|
||||
ret += scnprintf(str + ret, size - ret, "WCE ");
|
||||
if (portsc & PORT_WKDISC_E)
|
||||
ret += snprintf(str + ret, size - ret, "WDE ");
|
||||
ret += scnprintf(str + ret, size - ret, "WDE ");
|
||||
|
||||
return str;
|
||||
}
|
||||
@ -562,20 +562,20 @@ static inline const char *cdnsp_decode_ep_context(char *str, size_t size,
|
||||
|
||||
avg = EP_AVG_TRB_LENGTH(tx_info);
|
||||
|
||||
ret = snprintf(str, size, "State %s mult %d max P. Streams %d %s",
|
||||
ret = scnprintf(str, size, "State %s mult %d max P. Streams %d %s",
|
||||
cdnsp_ep_state_string(ep_state), mult,
|
||||
max_pstr, lsa ? "LSA " : "");
|
||||
|
||||
ret += snprintf(str + ret, size - ret,
|
||||
ret += scnprintf(str + ret, size - ret,
|
||||
"interval %d us max ESIT payload %d CErr %d ",
|
||||
(1 << interval) * 125, esit, cerr);
|
||||
|
||||
ret += snprintf(str + ret, size - ret,
|
||||
ret += scnprintf(str + ret, size - ret,
|
||||
"Type %s %sburst %d maxp %d deq %016llx ",
|
||||
cdnsp_ep_type_string(ep_type), hid ? "HID" : "",
|
||||
burst, maxp, deq);
|
||||
|
||||
ret += snprintf(str + ret, size - ret, "avg trb len %d", avg);
|
||||
ret += scnprintf(str + ret, size - ret, "avg trb len %d", avg);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
Reference in New Issue
Block a user