From 734766c2596b6ff940778f659bd664b3d72abd61 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 31 Jul 2024 11:12:48 +0200 Subject: [PATCH] Use vasprintf() if available for error messages and otherwise vsnprintf() vasprintf() is a GNU/BSD extension and would allocate as much memory as required on the heap, similar to g_strdup_printf(). It's ridiculous that such a function is still not provided as part of standard C. If it's not available, use vsnprintf() to at least avoid stack/heap buffer overflows, which can lead to arbitrary code execution. Thanks to Noriko Totsuka for reporting. Fixes JVN#02030803 / JPCERT#92912620 / CVE-2024-40897 Fixes #69 Part-of: --- meson.build | 1 + orc/orccompiler.c | 6 +++++- orc/orcparse.c | 18 +++++++++++++++--- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/meson.build b/meson.build index 41d5e5b..0e0d83b 100644 --- a/meson.build +++ b/meson.build @@ -118,6 +118,7 @@ int main() { ''' cdata.set('HAVE_MONOTONIC_CLOCK', cc.compiles(monotonic_test)) cdata.set('HAVE_GETTIMEOFDAY', cc.has_function('gettimeofday')) +cdata.set('HAVE_VASPRINTF', cc.has_function('vasprintf')) cdata.set('HAVE_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix : '#include ')) cdata.set('HAVE_MMAP', cc.has_function('mmap')) diff --git a/orc/orccompiler.c b/orc/orccompiler.c index 8d92cbe..ea0853c 100644 --- a/orc/orccompiler.c +++ b/orc/orccompiler.c @@ -1210,8 +1210,12 @@ orc_compiler_error_valist (OrcCompiler *compiler, const char *fmt, if (compiler->error_msg) return; +#ifdef HAVE_VASPRINTF + vasprintf (&s, fmt, args); +#else s = malloc (ORC_COMPILER_ERROR_BUFFER_SIZE); - vsprintf (s, fmt, args); + vsnprintf (s, ORC_COMPILER_ERROR_BUFFER_SIZE, fmt, args); +#endif compiler->error_msg = s; compiler->error = TRUE; compiler->result = ORC_COMPILE_RESULT_UNKNOWN_COMPILE; diff --git a/orc/orcparse.c b/orc/orcparse.c index f46b0be..56a9c3a 100644 --- a/orc/orcparse.c +++ b/orc/orcparse.c @@ -401,9 +401,13 @@ opcode_arg_size (OrcStaticOpcode *opcode, int arg) static void orc_parse_log_valist (OrcParser *parser, const char *format, va_list args) { - char s[100]; +#ifdef HAVE_VASPRINTF + char *s; +#else + char s[100] = { '\0' }; +#endif int len; - + if (parser->error_program != parser->program) { sprintf(s, "In function %s:\n", parser->program->name); len = strlen(s); @@ -418,7 +422,11 @@ orc_parse_log_valist (OrcParser *parser, const char *format, va_list args) parser->error_program = parser->program; } - vsprintf(s, format, args); +#ifdef HAVE_VASPRINTF + vasprintf (&s, format, args); +#else + vsnprintf (s, sizeof (s), format, args); +#endif len = strlen(s); if (parser->log_size + len + 1 >= parser->log_alloc) { @@ -428,6 +436,10 @@ orc_parse_log_valist (OrcParser *parser, const char *format, va_list args) strcpy (parser->log + parser->log_size, s); parser->log_size += len; + +#ifdef HAVE_VASPRINTF + free (s); +#endif } static void -- 2.45.2