kernel: printk: specify alignment for struct printk_log
authorAndrey Ryabinin <aryabinin@virtuozzo.com>
Wed, 20 Jan 2016 23:00:48 +0000 (15:00 -0800)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Wed, 1 Jun 2016 07:45:23 +0000 (16:45 +0900)
On architectures that have support for efficient unaligned access struct
printk_log has 4-byte alignment.  Specify alignment attribute in type
declaration.

The whole point of this patch is to fix deadlock which happening when
UBSAN detects unaligned access in printk() thus UBSAN recursively calls
printk() with logbuf_lock held by top printk() call.

Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sasha Levin <sasha.levin@oracle.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Michal Marek <mmarek@suse.cz>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Yury Gribov <y.gribov@samsung.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Konstantin Khlebnikov <koct9i@gmail.com>
Cc: Kostya Serebryany <kcc@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[Backport from mainline for UBSAN]
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Change-Id: I93d23dec2c1539faf21eb7242ccc328999950c01

kernel/printk/printk.c

index 2a38f63adf4360d7e807b6535bd5e92e6eb1646a..4a6dce9a3467c9552a28007cfa9d36d505fcaf25 100644 (file)
@@ -228,7 +228,11 @@ struct printk_log {
        u8 facility;            /* syslog facility */
        u8 flags:5;             /* internal record flags */
        u8 level:3;             /* syslog level */
-};
+}
+#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
+__packed __aligned(4)
+#endif
+;
 
 struct log_buffer {
 #ifdef CONFIG_PRINTK
@@ -276,11 +280,7 @@ static enum log_flags console_prev;
 #define KMSG_NUM_MAX    255
 
 /* record buffer */
-#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
-#define LOG_ALIGN 4
-#else
 #define LOG_ALIGN __alignof__(struct printk_log)
-#endif
 #define __LOG_BUF_K_LEN (1 << CONFIG_LOG_BUF_SHIFT)
 static char __log_buf_k[__LOG_BUF_K_LEN] __aligned(LOG_ALIGN);