From 158a608a6f09b6a5d1250835d9b10fcf0fdaa437 Mon Sep 17 00:00:00 2001 From: Hilko Bengen Date: Tue, 3 Oct 2023 20:08:34 +0200 Subject: [PATCH] Fix error handling after calloc calls that may ask for 0 bytes (#1981) Close #1980 --- libyara/modules/console/console.c | 17 +++++++++++++---- libyara/modules/dotnet/dotnet.c | 2 +- libyara/modules/elf/elf.c | 2 +- .../pe/authenticode-parser/certificate.c | 2 +- libyara/scanner.c | 6 +++--- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/libyara/modules/console/console.c b/libyara/modules/console/console.c index a5c46acc11..1342093625 100644 --- a/libyara/modules/console/console.c +++ b/libyara/modules/console/console.c @@ -46,9 +46,18 @@ define_function(log_string) // Assume the entire string is non-printable, so allocate 4 times the // space so that we can represent each byte as an escaped value. eg: \x00 // Add an extra byte for the NULL terminator. - char* msg = (char*) yr_calloc((s->length * 4) + 1, sizeof(char)); - if (msg == NULL) - return_integer(YR_UNDEFINED); + char* msg; + if (s->length == 0) + { + callback(ctx, CALLBACK_MSG_CONSOLE_LOG, (void*) "", ctx->user_data); + return_integer(1); + } + else + { + msg = (char*) yr_calloc((s->length * 4) + 1, sizeof(char)); + if (msg == NULL) + return_integer(YR_UNDEFINED); + } char* p = msg; for (size_t i = 0; i < s->length; i++) @@ -86,7 +95,7 @@ define_function(log_string_msg) // Add an extra byte for the NULL terminator. size_t msg_len = strlen(m) + (s->length * 4) + 1; char* msg = (char*) yr_calloc(msg_len, sizeof(char)); - if (msg == NULL) + if (msg == NULL && msg_len > 0) return_integer(YR_UNDEFINED); char* p = msg; diff --git a/libyara/modules/dotnet/dotnet.c b/libyara/modules/dotnet/dotnet.c index cbbe87f9e3..0952296d9e 100644 --- a/libyara/modules/dotnet/dotnet.c +++ b/libyara/modules/dotnet/dotnet.c @@ -1179,7 +1179,7 @@ static bool parse_method_params( // Array to hold all the possible parameters PARAMETERS* params = yr_calloc(param_count, sizeof(PARAMETERS)); - if (!params) + if (params == NULL && param_count > 0) return false; for (uint32_t idx = 0; idx < param_count; ++idx) diff --git a/libyara/modules/elf/elf.c b/libyara/modules/elf/elf.c index 2a34cc8ec5..6f728705f7 100644 --- a/libyara/modules/elf/elf.c +++ b/libyara/modules/elf/elf.c @@ -82,7 +82,7 @@ define_function(telfhash) int symbol_count = 0; char** clean_names = yr_calloc(list->count, sizeof(*clean_names)); - if (!clean_names) + if (clean_names == NULL && list->count > 0) return_string(YR_UNDEFINED); for (ELF_SYMBOL* i = list->symbols; i != NULL; i = i->next) diff --git a/libyara/modules/pe/authenticode-parser/certificate.c b/libyara/modules/pe/authenticode-parser/certificate.c index 455b2bbe88..3a95d0c124 100644 --- a/libyara/modules/pe/authenticode-parser/certificate.c +++ b/libyara/modules/pe/authenticode-parser/certificate.c @@ -141,7 +141,7 @@ CertificateArray* parse_signer_chain(X509* signCert, STACK_OF(X509) * certs) goto error; result->certs = (Certificate**) calloc(certCount, sizeof(Certificate*)); - if (!result->certs) + if (!result->certs && certCount > 0) goto error; /* Convert each certificate to internal representation */ diff --git a/libyara/scanner.c b/libyara/scanner.c index 342bdcbfc7..4bd7577dd0 100644 --- a/libyara/scanner.c +++ b/libyara/scanner.c @@ -283,8 +283,8 @@ YR_API int yr_scanner_create(YR_RULES* rules, YR_SCANNER** scanner) new_scanner->rule_evaluate_condition_flags == NULL || new_scanner->ns_unsatisfied_flags == NULL || new_scanner->strings_temp_disabled == NULL || - new_scanner->matches == NULL || // - new_scanner->unconfirmed_matches == NULL) + (new_scanner->matches == NULL && rules->num_strings > 0) || + (new_scanner->unconfirmed_matches == NULL && rules->num_strings > 0)) { yr_scanner_destroy(new_scanner); return ERROR_INSUFFICIENT_MEMORY; @@ -294,7 +294,7 @@ YR_API int yr_scanner_create(YR_RULES* rules, YR_SCANNER** scanner) new_scanner->profiling_info = yr_calloc( rules->num_rules, sizeof(YR_PROFILING_INFO)); - if (new_scanner->profiling_info == NULL) + if (new_scanner->profiling_info == NULL && rules->num_rules > 0) { yr_scanner_destroy(new_scanner); return ERROR_INSUFFICIENT_MEMORY;