When dyndbg classmaps get used (later in this series), the
__dyndbg_classes section (which has 28 byte structs on i386), causes
mis-alignment of the following __dyndbg section, resulting in a NULL
pointer deref in dynamic_debug_init().

To fix this, employ belt + suspenders:

1. move __dyndbg section above __dyndbg_classes.  This restores it to
its original position directly after the ALIGN(8), and fixes the
immediate problem.

2. add ALIGN(8) to the BOUNDED_SECTION* macros.  This aligns all
existing sections using the macro, and also fixes a future
dyndbg_class_* addition which would suffer the same misalignment on
i386.  Many of the existing macro uses already have a preceding ALIGN,
these are now redundant, but are harmless, so are left to avoid churn.

3. remove BOUNDED_SECTION* uses in ORC_UNWINDER sections.  These have
smaller alignments, *and* scripts/sorttable.c does not tolerate the
added ALIGN(8) padding.

Reported-by: kernel test robot <[email protected]>
Closes: https://lore.kernel.org/oe-lkp/[email protected]
Signed-off-by: Jim Cromie <[email protected]>
---
 include/asm-generic/vmlinux.lds.h | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index 8ca130af301f..4b4d2773aa22 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -212,11 +212,13 @@
 #endif
 
 #define BOUNDED_SECTION_PRE_LABEL(_sec_, _label_, _BEGIN_, _END_)      \
+       . = ALIGN(8);                                                   \
        _BEGIN_##_label_ = .;                                           \
        KEEP(*(_sec_))                                                  \
        _END_##_label_ = .;
 
 #define BOUNDED_SECTION_POST_LABEL(_sec_, _label_, _BEGIN_, _END_)     \
+       . = ALIGN(8);                                                   \
        _label_##_BEGIN_ = .;                                           \
        KEEP(*(_sec_))                                                  \
        _label_##_END_ = .;
@@ -383,8 +385,8 @@
        *(__tracepoints)                                                \
        /* implement dynamic printk debug */                            \
        . = ALIGN(8);                                                   \
-       BOUNDED_SECTION_BY(__dyndbg_classes, ___dyndbg_classes)         \
        BOUNDED_SECTION_BY(__dyndbg, ___dyndbg)                         \
+       BOUNDED_SECTION_BY(__dyndbg_classes, ___dyndbg_classes)         \
        CODETAG_SECTIONS()                                              \
        LIKELY_PROFILE()                                                \
        BRANCH_PROFILE()                                                \
@@ -867,15 +869,21 @@
 #ifdef CONFIG_UNWINDER_ORC
 #define ORC_UNWIND_TABLE                                               \
        .orc_header : AT(ADDR(.orc_header) - LOAD_OFFSET) {             \
-               BOUNDED_SECTION_BY(.orc_header, _orc_header)            \
+               __start_orc_header = .;                                 \
+               KEEP(*(.orc_header))                                    \
+               __stop_orc_header = .;                                  \
        }                                                               \
        . = ALIGN(4);                                                   \
        .orc_unwind_ip : AT(ADDR(.orc_unwind_ip) - LOAD_OFFSET) {       \
-               BOUNDED_SECTION_BY(.orc_unwind_ip, _orc_unwind_ip)      \
+               __start_orc_unwind_ip = .;                              \
+               KEEP(*(.orc_unwind_ip))                                 \
+               __stop_orc_unwind_ip = .;                               \
        }                                                               \
        . = ALIGN(2);                                                   \
        .orc_unwind : AT(ADDR(.orc_unwind) - LOAD_OFFSET) {             \
-               BOUNDED_SECTION_BY(.orc_unwind, _orc_unwind)            \
+               __start_orc_unwind = .;                                 \
+               KEEP(*(.orc_unwind))                                    \
+               __stop_orc_unwind = .;                                  \
        }                                                               \
        text_size = _etext - _stext;                                    \
        . = ALIGN(4);                                                   \
-- 
2.52.0

Reply via email to