From d75b26f880f60ead301e79ba0f4a635c5a60767f Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 27 Jan 2022 20:12:32 +0200 Subject: vsprintf: Fix potential unaligned access The %p4cc specifier in some cases might get an unaligned pointer. Due to this we need to make copy to local variable once to avoid potential crashes on some architectures due to improper access. Fixes: af612e43de6d ("lib/vsprintf: Add support for printing V4L2 and DRM fourccs") Cc: Sakari Ailus Signed-off-by: Andy Shevchenko Reviewed-by: Petr Mladek Signed-off-by: Petr Mladek Link: https://lore.kernel.org/r/20220127181233.72910-1-andriy.shevchenko@linux.intel.com --- lib/vsprintf.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'lib/vsprintf.c') diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 53d6081f9e8b..3e416a3cb66d 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -49,6 +49,7 @@ #include /* for PAGE_SIZE */ #include /* cpu_to_le16 */ +#include #include #include "kstrtox.h" @@ -1771,7 +1772,7 @@ char *fourcc_string(char *buf, char *end, const u32 *fourcc, char output[sizeof("0123 little-endian (0x01234567)")]; char *p = output; unsigned int i; - u32 val; + u32 orig, val; if (fmt[1] != 'c' || fmt[2] != 'c') return error_string(buf, end, "(%p4?)", spec); @@ -1779,21 +1780,22 @@ char *fourcc_string(char *buf, char *end, const u32 *fourcc, if (check_pointer(&buf, end, fourcc, spec)) return buf; - val = *fourcc & ~BIT(31); + orig = get_unaligned(fourcc); + val = orig & ~BIT(31); - for (i = 0; i < sizeof(*fourcc); i++) { + for (i = 0; i < sizeof(u32); i++) { unsigned char c = val >> (i * 8); /* Print non-control ASCII characters as-is, dot otherwise */ *p++ = isascii(c) && isprint(c) ? c : '.'; } - strcpy(p, *fourcc & BIT(31) ? " big-endian" : " little-endian"); + strcpy(p, orig & BIT(31) ? " big-endian" : " little-endian"); p += strlen(p); *p++ = ' '; *p++ = '('; - p = special_hex_number(p, output + sizeof(output) - 2, *fourcc, sizeof(u32)); + p = special_hex_number(p, output + sizeof(output) - 2, orig, sizeof(u32)); *p++ = ')'; *p = '\0'; -- cgit From f74a08fc61073cc5b5f4e24eb513f0b79f4f6ce7 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 27 Jan 2022 20:12:33 +0200 Subject: vsprintf: Move space out of string literals in fourcc_string() The literals "big-endian" and "little-endian" may be potentially occurred in other places. Dropping space allows linker to merge them by using only a single copy. Signed-off-by: Andy Shevchenko Acked-by: Sakari Ailus Reviewed-by: Petr Mladek Signed-off-by: Petr Mladek Link: https://lore.kernel.org/r/20220127181233.72910-2-andriy.shevchenko@linux.intel.com --- lib/vsprintf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/vsprintf.c') diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 3e416a3cb66d..f96c66899df6 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1790,7 +1790,8 @@ char *fourcc_string(char *buf, char *end, const u32 *fourcc, *p++ = isascii(c) && isprint(c) ? c : '.'; } - strcpy(p, orig & BIT(31) ? " big-endian" : " little-endian"); + *p++ = ' '; + strcpy(p, orig & BIT(31) ? "big-endian" : "little-endian"); p += strlen(p); *p++ = ' '; -- cgit