From fd93cf71df80f7bb5aae707ea5a5875727a85770 Mon Sep 17 00:00:00 2001 From: Sultan Alsawaf Date: Wed, 9 Dec 2020 12:55:10 -0800 Subject: [PATCH] PR26844: fix off-by-one error when copying printed backtraces Since log->buf isn't null-terminated, log->len represents the total number of bytes present in the log buffer for copying. The use of strlcpy() here with log->len as its size results in log->len - 1 bytes being copied, with the log->len'nth byte of the output buffer being set to zero to terminate the string. Use memcpy() instead to remedy this, while ensuring that the output buffer has space for null termination, since the output buffer needs to be terminated. --- runtime/stack.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/runtime/stack.c b/runtime/stack.c index da23d4395..85883d6c4 100644 --- a/runtime/stack.c +++ b/runtime/stack.c @@ -692,6 +692,7 @@ static void _stp_stack_kernel_sprint(char *str, int size, struct context* c, * and clear the print buffer. */ struct _stp_log *log; unsigned long flags; + int bytes; if (!_stp_print_trylock_irqsave(&flags)) { *str = '\0'; @@ -701,7 +702,9 @@ static void _stp_stack_kernel_sprint(char *str, int size, struct context* c, log = per_cpu_ptr(_stp_log_pcpu, raw_smp_processor_id()); __stp_print_flush(log); _stp_stack_kernel_print(c, sym_flags); - strlcpy(str, log->buf, min_t(int, size, log->len)); + bytes = min_t(int, size - 1, log->len); + memcpy(str, log->buf, bytes); + str[bytes] = '\0'; log->len = 0; _stp_print_unlock_irqrestore(&flags); } @@ -716,6 +719,7 @@ static void _stp_stack_user_sprint(char *str, int size, struct context* c, * and clear the print buffer. */ struct _stp_log *log; unsigned long flags; + int bytes; if (!_stp_print_trylock_irqsave(&flags)) { *str = '\0'; @@ -725,7 +729,9 @@ static void _stp_stack_user_sprint(char *str, int size, struct context* c, log = per_cpu_ptr(_stp_log_pcpu, raw_smp_processor_id()); __stp_print_flush(log); _stp_stack_user_print(c, sym_flags); - strlcpy(str, log->buf, min_t(int, size, log->len)); + bytes = min_t(int, size - 1, log->len); + memcpy(str, log->buf, bytes); + str[bytes] = '\0'; log->len = 0; _stp_print_unlock_irqrestore(&flags); } -- 2.43.5