Skip to content

Commit d75b26f

Browse files
andy-shevpmladek
authored andcommitted
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: af612e4 ("lib/vsprintf: Add support for printing V4L2 and DRM fourccs") Cc: Sakari Ailus <[email protected]> Signed-off-by: Andy Shevchenko <[email protected]> Reviewed-by: Petr Mladek <[email protected]> Signed-off-by: Petr Mladek <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent a229327 commit d75b26f

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

lib/vsprintf.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949

5050
#include <asm/page.h> /* for PAGE_SIZE */
5151
#include <asm/byteorder.h> /* cpu_to_le16 */
52+
#include <asm/unaligned.h>
5253

5354
#include <linux/string_helpers.h>
5455
#include "kstrtox.h"
@@ -1771,29 +1772,30 @@ char *fourcc_string(char *buf, char *end, const u32 *fourcc,
17711772
char output[sizeof("0123 little-endian (0x01234567)")];
17721773
char *p = output;
17731774
unsigned int i;
1774-
u32 val;
1775+
u32 orig, val;
17751776

17761777
if (fmt[1] != 'c' || fmt[2] != 'c')
17771778
return error_string(buf, end, "(%p4?)", spec);
17781779

17791780
if (check_pointer(&buf, end, fourcc, spec))
17801781
return buf;
17811782

1782-
val = *fourcc & ~BIT(31);
1783+
orig = get_unaligned(fourcc);
1784+
val = orig & ~BIT(31);
17831785

1784-
for (i = 0; i < sizeof(*fourcc); i++) {
1786+
for (i = 0; i < sizeof(u32); i++) {
17851787
unsigned char c = val >> (i * 8);
17861788

17871789
/* Print non-control ASCII characters as-is, dot otherwise */
17881790
*p++ = isascii(c) && isprint(c) ? c : '.';
17891791
}
17901792

1791-
strcpy(p, *fourcc & BIT(31) ? " big-endian" : " little-endian");
1793+
strcpy(p, orig & BIT(31) ? " big-endian" : " little-endian");
17921794
p += strlen(p);
17931795

17941796
*p++ = ' ';
17951797
*p++ = '(';
1796-
p = special_hex_number(p, output + sizeof(output) - 2, *fourcc, sizeof(u32));
1798+
p = special_hex_number(p, output + sizeof(output) - 2, orig, sizeof(u32));
17971799
*p++ = ')';
17981800
*p = '\0';
17991801

0 commit comments

Comments
 (0)