* [RFC-PATCH-for-8.2?] disas/cris: Pass buffer size to format_dec() to avoid overflow warning
@ 2023-11-20 13:22 Philippe Mathieu-Daudé
2023-11-20 13:47 ` Akihiko Odaki
0 siblings, 1 reply; 2+ messages in thread
From: Philippe Mathieu-Daudé @ 2023-11-20 13:22 UTC (permalink / raw)
To: qemu-devel
Cc: Edgar E. Iglesias, Eric Blake, Philippe Mathieu-Daudé,
Akihiko Odaki
Propagate the buffer size to format_dec() and use snprintf().
This should silence this UBSan -Wformat-overflow warning:
In file included from /usr/include/stdio.h:906,
from include/qemu/osdep.h:114,
from ../disas/cris.c:21:
In function 'sprintf',
inlined from 'format_dec' at ../disas/cris.c:1737:3,
inlined from 'print_with_operands' at ../disas/cris.c:2477:12,
inlined from 'print_insn_cris_generic.constprop' at ../disas/cris.c:2690:8:
/usr/include/bits/stdio2.h:30:10: warning: null destination pointer [-Wformat-overflow=]
30 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
31 | __glibc_objsize (__s), __fmt,
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32 | __va_arg_pack ());
| ~~~~~~~~~~~~~~~~~
Reported-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
TODO: add compiler version
Surgical alternative to this patch from Akihiko:
https://lore.kernel.org/all/20231120112329.4149-1-akihiko.odaki@daynix.com/
---
disas/cris.c | 47 ++++++++++++++++++++++++++++++++---------------
1 file changed, 32 insertions(+), 15 deletions(-)
diff --git a/disas/cris.c b/disas/cris.c
index 0b0a3fb916..74a487c733 100644
--- a/disas/cris.c
+++ b/disas/cris.c
@@ -1731,10 +1731,10 @@ format_hex (unsigned long number,
unsigned (== 0). */
static char *
-format_dec (long number, char *outbuffer, int signedp)
+format_dec(long number, char *outbuffer, size_t outsize, int signedp)
{
last_immediate = number;
- sprintf (outbuffer, signedp ? "%ld" : "%lu", number);
+ snprintf(outbuffer, outsize, signedp ? "%ld" : "%lu", number);
return outbuffer + strlen (outbuffer);
}
@@ -1898,6 +1898,7 @@ print_with_operands (const struct cris_opcode *opcodep,
intermediate parts of the insn. */
char temp[sizeof (".d [$r13=$r12-2147483648],$r10") * 2];
char *tp = temp;
+ ptrdiff_t tp_avail;
static const char mode_char[] = "bwd?";
const char *s;
const char *cs;
@@ -2102,12 +2103,13 @@ print_with_operands (const struct cris_opcode *opcodep,
number = 42;
}
- if ((*cs == 'z' && (insn & 0x20))
- || (opcodep->match == BDAP_QUICK_OPCODE
- && (nbytes <= 2 || buffer[1 + nbytes] == 0)))
- tp = format_dec (number, tp, signedp);
- else
- {
+ if ((*cs == 'z' && (insn & 0x20))
+ || (opcodep->match == BDAP_QUICK_OPCODE
+ && (nbytes <= 2 || buffer[1 + nbytes] == 0))) {
+ tp_avail = temp - tp;
+ assert(tp_avail >= 0);
+ tp = format_dec(number, tp, tp_avail, signedp);
+ } else {
unsigned int highbyte = (number >> 24) & 0xff;
/* Either output this as an address or as a number. If it's
@@ -2241,7 +2243,9 @@ print_with_operands (const struct cris_opcode *opcodep,
with_reg_prefix);
if (number >= 0)
*tp++ = '+';
- tp = format_dec (number, tp, 1);
+ tp_avail = temp - tp;
+ assert(tp_avail >= 0);
+ tp = format_dec(number, tp, tp_avail, 1);
info->flags |= CRIS_DIS_FLAG_MEM_TARGET_IS_REG;
info->target = (prefix_insn >> 12) & 15;
@@ -2340,7 +2344,9 @@ print_with_operands (const struct cris_opcode *opcodep,
{
if (number >= 0)
*tp++ = '+';
- tp = format_dec (number, tp, 1);
+ tp_avail = temp - tp;
+ assert(tp_avail >= 0);
+ tp = format_dec(number, tp, tp_avail, 1);
}
}
else
@@ -2397,7 +2403,9 @@ print_with_operands (const struct cris_opcode *opcodep,
break;
case 'I':
- tp = format_dec (insn & 63, tp, 0);
+ tp_avail = temp - tp;
+ assert(tp_avail >= 0);
+ tp = format_dec(insn & 63, tp, tp_avail, 0);
break;
case 'b':
@@ -2426,11 +2434,15 @@ print_with_operands (const struct cris_opcode *opcodep,
break;
case 'c':
- tp = format_dec (insn & 31, tp, 0);
+ tp_avail = temp - tp;
+ assert(tp_avail >= 0);
+ tp = format_dec(insn & 31, tp, tp_avail, 0);
break;
case 'C':
- tp = format_dec (insn & 15, tp, 0);
+ tp_avail = temp - tp;
+ assert(tp_avail >= 0);
+ tp = format_dec(insn & 15, tp, tp_avail, 0);
break;
case 'o':
@@ -2463,7 +2475,9 @@ print_with_operands (const struct cris_opcode *opcodep,
if (number > 127)
number = number - 256;
- tp = format_dec (number, tp, 1);
+ tp_avail = temp - tp;
+ assert(tp_avail >= 0);
+ tp = format_dec(number, tp, tp_avail, 1);
*tp++ = ',';
tp = format_reg (disdata, (insn >> 12) & 15, tp, with_reg_prefix);
}
@@ -2474,7 +2488,10 @@ print_with_operands (const struct cris_opcode *opcodep,
break;
case 'i':
- tp = format_dec ((insn & 32) ? (insn & 31) | ~31L : insn & 31, tp, 1);
+ tp_avail = temp - tp;
+ assert(tp_avail >= 0);
+ tp = format_dec((insn & 32) ? (insn & 31) | ~31L : insn & 31,
+ tp, tp_avail, 1);
break;
case 'P':
--
2.41.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [RFC-PATCH-for-8.2?] disas/cris: Pass buffer size to format_dec() to avoid overflow warning
2023-11-20 13:22 [RFC-PATCH-for-8.2?] disas/cris: Pass buffer size to format_dec() to avoid overflow warning Philippe Mathieu-Daudé
@ 2023-11-20 13:47 ` Akihiko Odaki
0 siblings, 0 replies; 2+ messages in thread
From: Akihiko Odaki @ 2023-11-20 13:47 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel; +Cc: Edgar E. Iglesias, Eric Blake
On 2023/11/20 22:22, Philippe Mathieu-Daudé wrote:
> Propagate the buffer size to format_dec() and use snprintf().
>
> This should silence this UBSan -Wformat-overflow warning:
>
> In file included from /usr/include/stdio.h:906,
> from include/qemu/osdep.h:114,
> from ../disas/cris.c:21:
> In function 'sprintf',
> inlined from 'format_dec' at ../disas/cris.c:1737:3,
> inlined from 'print_with_operands' at ../disas/cris.c:2477:12,
> inlined from 'print_insn_cris_generic.constprop' at ../disas/cris.c:2690:8:
> /usr/include/bits/stdio2.h:30:10: warning: null destination pointer [-Wformat-overflow=]
> 30 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 31 | __glibc_objsize (__s), __fmt,
> | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 32 | __va_arg_pack ());
> | ~~~~~~~~~~~~~~~~~
>
> Reported-by: Akihiko Odaki <akihiko.odaki@daynix.com>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
> TODO: add compiler version
My compiler is GCC 12.1.0, and I confirmed this change suppresses the
warnings.
>
> Surgical alternative to this patch from Akihiko:
> https://lore.kernel.org/all/20231120112329.4149-1-akihiko.odaki@daynix.com/
> ---
> disas/cris.c | 47 ++++++++++++++++++++++++++++++++---------------
> 1 file changed, 32 insertions(+), 15 deletions(-)
>
> diff --git a/disas/cris.c b/disas/cris.c
> index 0b0a3fb916..74a487c733 100644
> --- a/disas/cris.c
> +++ b/disas/cris.c
> @@ -1731,10 +1731,10 @@ format_hex (unsigned long number,
> unsigned (== 0). */
>
> static char *
> -format_dec (long number, char *outbuffer, int signedp)
> +format_dec(long number, char *outbuffer, size_t outsize, int signedp)
> {
> last_immediate = number;
> - sprintf (outbuffer, signedp ? "%ld" : "%lu", number);
> + snprintf(outbuffer, outsize, signedp ? "%ld" : "%lu", number);
>
> return outbuffer + strlen (outbuffer);
> }
> @@ -1898,6 +1898,7 @@ print_with_operands (const struct cris_opcode *opcodep,
> intermediate parts of the insn. */
> char temp[sizeof (".d [$r13=$r12-2147483648],$r10") * 2];
> char *tp = temp;
> + ptrdiff_t tp_avail;
> static const char mode_char[] = "bwd?";
> const char *s;
> const char *cs;
> @@ -2102,12 +2103,13 @@ print_with_operands (const struct cris_opcode *opcodep,
> number = 42;
> }
>
> - if ((*cs == 'z' && (insn & 0x20))
> - || (opcodep->match == BDAP_QUICK_OPCODE
> - && (nbytes <= 2 || buffer[1 + nbytes] == 0)))
> - tp = format_dec (number, tp, signedp);
> - else
> - {
> + if ((*cs == 'z' && (insn & 0x20))
> + || (opcodep->match == BDAP_QUICK_OPCODE
> + && (nbytes <= 2 || buffer[1 + nbytes] == 0))) {
> + tp_avail = temp - tp;
I think this should be: temp + sizeof(temp) - tp
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-11-20 13:48 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-20 13:22 [RFC-PATCH-for-8.2?] disas/cris: Pass buffer size to format_dec() to avoid overflow warning Philippe Mathieu-Daudé
2023-11-20 13:47 ` Akihiko Odaki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).