Skip to content

Commit 01dc7f7

Browse files
lag-linarogregkh
authored andcommitted
usb: cdns2: 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. Link: https://lwn.net/Articles/69419/ Link: KSPP/linux#105 Cc: Pawel Laszczak <[email protected]> Signed-off-by: Lee Jones <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent d32dcb0 commit 01dc7f7

File tree

1 file changed

+69
-69
lines changed

1 file changed

+69
-69
lines changed

drivers/usb/gadget/udc/cdns2/cdns2-debug.h

Lines changed: 69 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -16,34 +16,34 @@ static inline const char *cdns2_decode_usb_irq(char *str, size_t size,
1616
{
1717
int ret;
1818

19-
ret = snprintf(str, size, "usbirq: 0x%02x - ", usb_irq);
19+
ret = scnprintf(str, size, "usbirq: 0x%02x - ", usb_irq);
2020

2121
if (usb_irq & USBIRQ_SOF)
22-
ret += snprintf(str + ret, size - ret, "SOF ");
22+
ret += scnprintf(str + ret, size - ret, "SOF ");
2323
if (usb_irq & USBIRQ_SUTOK)
24-
ret += snprintf(str + ret, size - ret, "SUTOK ");
24+
ret += scnprintf(str + ret, size - ret, "SUTOK ");
2525
if (usb_irq & USBIRQ_SUDAV)
26-
ret += snprintf(str + ret, size - ret, "SETUP ");
26+
ret += scnprintf(str + ret, size - ret, "SETUP ");
2727
if (usb_irq & USBIRQ_SUSPEND)
28-
ret += snprintf(str + ret, size - ret, "Suspend ");
28+
ret += scnprintf(str + ret, size - ret, "Suspend ");
2929
if (usb_irq & USBIRQ_URESET)
30-
ret += snprintf(str + ret, size - ret, "Reset ");
30+
ret += scnprintf(str + ret, size - ret, "Reset ");
3131
if (usb_irq & USBIRQ_HSPEED)
32-
ret += snprintf(str + ret, size - ret, "HS ");
32+
ret += scnprintf(str + ret, size - ret, "HS ");
3333
if (usb_irq & USBIRQ_LPM)
34-
ret += snprintf(str + ret, size - ret, "LPM ");
34+
ret += scnprintf(str + ret, size - ret, "LPM ");
3535

36-
ret += snprintf(str + ret, size - ret, ", EXT: 0x%02x - ", ext_irq);
36+
ret += scnprintf(str + ret, size - ret, ", EXT: 0x%02x - ", ext_irq);
3737

3838
if (ext_irq & EXTIRQ_WAKEUP)
39-
ret += snprintf(str + ret, size - ret, "Wakeup ");
39+
ret += scnprintf(str + ret, size - ret, "Wakeup ");
4040
if (ext_irq & EXTIRQ_VBUSFAULT_FALL)
41-
ret += snprintf(str + ret, size - ret, "VBUS_FALL ");
41+
ret += scnprintf(str + ret, size - ret, "VBUS_FALL ");
4242
if (ext_irq & EXTIRQ_VBUSFAULT_RISE)
43-
ret += snprintf(str + ret, size - ret, "VBUS_RISE ");
43+
ret += scnprintf(str + ret, size - ret, "VBUS_RISE ");
4444

45-
if (ret >= size)
46-
pr_info("CDNS2: buffer overflowed.\n");
45+
if (ret == size - 1)
46+
pr_info("CDNS2: buffer may be truncated.\n");
4747

4848
return str;
4949
}
@@ -54,28 +54,28 @@ static inline const char *cdns2_decode_dma_irq(char *str, size_t size,
5454
{
5555
int ret;
5656

57-
ret = snprintf(str, size, "ISTS: %08x, %s: %08x ",
58-
ep_ists, ep_name, ep_sts);
57+
ret = scnprintf(str, size, "ISTS: %08x, %s: %08x ",
58+
ep_ists, ep_name, ep_sts);
5959

6060
if (ep_sts & DMA_EP_STS_IOC)
61-
ret += snprintf(str + ret, size - ret, "IOC ");
61+
ret += scnprintf(str + ret, size - ret, "IOC ");
6262
if (ep_sts & DMA_EP_STS_ISP)
63-
ret += snprintf(str + ret, size - ret, "ISP ");
63+
ret += scnprintf(str + ret, size - ret, "ISP ");
6464
if (ep_sts & DMA_EP_STS_DESCMIS)
65-
ret += snprintf(str + ret, size - ret, "DESCMIS ");
65+
ret += scnprintf(str + ret, size - ret, "DESCMIS ");
6666
if (ep_sts & DMA_EP_STS_TRBERR)
67-
ret += snprintf(str + ret, size - ret, "TRBERR ");
67+
ret += scnprintf(str + ret, size - ret, "TRBERR ");
6868
if (ep_sts & DMA_EP_STS_OUTSMM)
69-
ret += snprintf(str + ret, size - ret, "OUTSMM ");
69+
ret += scnprintf(str + ret, size - ret, "OUTSMM ");
7070
if (ep_sts & DMA_EP_STS_ISOERR)
71-
ret += snprintf(str + ret, size - ret, "ISOERR ");
71+
ret += scnprintf(str + ret, size - ret, "ISOERR ");
7272
if (ep_sts & DMA_EP_STS_DBUSY)
73-
ret += snprintf(str + ret, size - ret, "DBUSY ");
73+
ret += scnprintf(str + ret, size - ret, "DBUSY ");
7474
if (DMA_EP_STS_CCS(ep_sts))
75-
ret += snprintf(str + ret, size - ret, "CCS ");
75+
ret += scnprintf(str + ret, size - ret, "CCS ");
7676

77-
if (ret >= size)
78-
pr_info("CDNS2: buffer overflowed.\n");
77+
if (ret == size - 1)
78+
pr_info("CDNS2: buffer may be truncated.\n");
7979

8080
return str;
8181
}
@@ -105,43 +105,43 @@ static inline const char *cdns2_raw_ring(struct cdns2_endpoint *pep,
105105
int ret;
106106
int i;
107107

108-
ret = snprintf(str, size, "\n\t\tTR for %s:", pep->name);
108+
ret = scnprintf(str, size, "\n\t\tTR for %s:", pep->name);
109109

110110
trb = &trbs[ring->dequeue];
111111
dma = cdns2_trb_virt_to_dma(pep, trb);
112-
ret += snprintf(str + ret, size - ret,
113-
"\n\t\tRing deq index: %d, trb: V=%p, P=0x%pad\n",
114-
ring->dequeue, trb, &dma);
112+
ret += scnprintf(str + ret, size - ret,
113+
"\n\t\tRing deq index: %d, trb: V=%p, P=0x%pad\n",
114+
ring->dequeue, trb, &dma);
115115

116116
trb = &trbs[ring->enqueue];
117117
dma = cdns2_trb_virt_to_dma(pep, trb);
118-
ret += snprintf(str + ret, size - ret,
119-
"\t\tRing enq index: %d, trb: V=%p, P=0x%pad\n",
120-
ring->enqueue, trb, &dma);
118+
ret += scnprintf(str + ret, size - ret,
119+
"\t\tRing enq index: %d, trb: V=%p, P=0x%pad\n",
120+
ring->enqueue, trb, &dma);
121121

122-
ret += snprintf(str + ret, size - ret,
123-
"\t\tfree trbs: %d, CCS=%d, PCS=%d\n",
124-
ring->free_trbs, ring->ccs, ring->pcs);
122+
ret += scnprintf(str + ret, size - ret,
123+
"\t\tfree trbs: %d, CCS=%d, PCS=%d\n",
124+
ring->free_trbs, ring->ccs, ring->pcs);
125125

126126
if (TRBS_PER_SEGMENT > 40) {
127-
ret += snprintf(str + ret, size - ret,
128-
"\t\tTransfer ring %d too big\n", TRBS_PER_SEGMENT);
127+
ret += scnprintf(str + ret, size - ret,
128+
"\t\tTransfer ring %d too big\n", TRBS_PER_SEGMENT);
129129
return str;
130130
}
131131

132132
dma = ring->dma;
133133
for (i = 0; i < TRBS_PER_SEGMENT; ++i) {
134134
trb = &trbs[i];
135-
ret += snprintf(str + ret, size - ret,
136-
"\t\t@%pad %08x %08x %08x\n", &dma,
137-
le32_to_cpu(trb->buffer),
138-
le32_to_cpu(trb->length),
139-
le32_to_cpu(trb->control));
135+
ret += scnprintf(str + ret, size - ret,
136+
"\t\t@%pad %08x %08x %08x\n", &dma,
137+
le32_to_cpu(trb->buffer),
138+
le32_to_cpu(trb->length),
139+
le32_to_cpu(trb->control));
140140
dma += sizeof(*trb);
141141
}
142142

143-
if (ret >= size)
144-
pr_info("CDNS2: buffer overflowed.\n");
143+
if (ret == size - 1)
144+
pr_info("CDNS2: buffer may be truncated.\n");
145145

146146
return str;
147147
}
@@ -166,36 +166,36 @@ static inline const char *cdns2_decode_trb(char *str, size_t size, u32 flags,
166166

167167
switch (type) {
168168
case TRB_LINK:
169-
ret = snprintf(str, size,
170-
"LINK %08x type '%s' flags %c:%c:%c%c:%c",
171-
buffer, cdns2_trb_type_string(type),
172-
flags & TRB_CYCLE ? 'C' : 'c',
173-
flags & TRB_TOGGLE ? 'T' : 't',
174-
flags & TRB_CHAIN ? 'C' : 'c',
175-
flags & TRB_CHAIN ? 'H' : 'h',
176-
flags & TRB_IOC ? 'I' : 'i');
169+
ret = scnprintf(str, size,
170+
"LINK %08x type '%s' flags %c:%c:%c%c:%c",
171+
buffer, cdns2_trb_type_string(type),
172+
flags & TRB_CYCLE ? 'C' : 'c',
173+
flags & TRB_TOGGLE ? 'T' : 't',
174+
flags & TRB_CHAIN ? 'C' : 'c',
175+
flags & TRB_CHAIN ? 'H' : 'h',
176+
flags & TRB_IOC ? 'I' : 'i');
177177
break;
178178
case TRB_NORMAL:
179-
ret = snprintf(str, size,
180-
"type: '%s', Buffer: %08x, length: %ld, burst len: %ld, "
181-
"flags %c:%c:%c%c:%c",
182-
cdns2_trb_type_string(type),
183-
buffer, TRB_LEN(length),
184-
TRB_FIELD_TO_BURST(length),
185-
flags & TRB_CYCLE ? 'C' : 'c',
186-
flags & TRB_ISP ? 'I' : 'i',
187-
flags & TRB_CHAIN ? 'C' : 'c',
188-
flags & TRB_CHAIN ? 'H' : 'h',
189-
flags & TRB_IOC ? 'I' : 'i');
179+
ret = scnprintf(str, size,
180+
"type: '%s', Buffer: %08x, length: %ld, burst len: %ld, "
181+
"flags %c:%c:%c%c:%c",
182+
cdns2_trb_type_string(type),
183+
buffer, TRB_LEN(length),
184+
TRB_FIELD_TO_BURST(length),
185+
flags & TRB_CYCLE ? 'C' : 'c',
186+
flags & TRB_ISP ? 'I' : 'i',
187+
flags & TRB_CHAIN ? 'C' : 'c',
188+
flags & TRB_CHAIN ? 'H' : 'h',
189+
flags & TRB_IOC ? 'I' : 'i');
190190
break;
191191
default:
192-
ret = snprintf(str, size, "type '%s' -> raw %08x %08x %08x",
193-
cdns2_trb_type_string(type),
194-
buffer, length, flags);
192+
ret = scnprintf(str, size, "type '%s' -> raw %08x %08x %08x",
193+
cdns2_trb_type_string(type),
194+
buffer, length, flags);
195195
}
196196

197-
if (ret >= size)
198-
pr_info("CDNS2: buffer overflowed.\n");
197+
if (ret == size - 1)
198+
pr_info("CDNS2: buffer may be truncated.\n");
199199

200200
return str;
201201
}

0 commit comments

Comments
 (0)