• Jens Remus's avatar
    s390/boot: Do not adjust GOT entries for undef weak sym · cea5589e
    Jens Remus authored
    Since commit 778666df ("s390: compile relocatable kernel without
    -fPIE") and commit 00cda11d ("s390: Compile kernel with -fPIC and
    link with -no-pie") the kernel on s390x may have a Global Offset Table
    (GOT) whose entries are adjusted for KASLR in kaslr_adjust_got().
    
    The GOT may contain entries for undefined weak symbols that resolved to
    zero. That is the resulting GOT entry value is zero. Adjusting those
    entries unconditionally in kaslr_adjust_got() is wrong. Otherwise the
    following sample code would erroneously assume foo to be defined, due to
    the adjustment changing the zero-value to a non-zero one:
    
      extern int foo __attribute__((weak));
      if (*foo)
        /* foo is defined [or undefined and erroneously adjusted] */
    
    The vmlinux build at commit 00cda11d ("s390: Compile kernel with
    -fPIC and link with -no-pie") with defconfig actually had two GOT
    entries for the undefined weak symbols __start_BTF and __stop_BTF:
    
    $ objdump -tw vmlinux | grep -F "*UND*"
    0000000000000000  w      *UND*  0000000000000000 __stop_BTF
    0000000000000000  w      *UND*  0000000000000000 __start_BTF
    
    $ readelf -rw vmlinux | grep -E "R_390_GOTENT +0{16}"
    000000345760  2776a0000001a R_390_GOTENT      0000000000000000 __stop_BTF + 2
    000000345766  2d5480000001a R_390_GOTENT      0000000000000000 __start_BTF + 2
    
    The s390-specific vmlinux linker script sets the section start to
    __START_KERNEL, which is currently defined as 0x100000 on s390x. Access
    to lowcore is performed via a pointer of 0 and not a symbol in a section
    starting at 0. The first 64K are reserved for the loader on s390x. Thus
    it is safe to assume that __START_KERNEL will never be 0. As a result
    there cannot be any defined symbols resolving to zero in the kernel.
    
    Note that the first three GOT entries are reserved for the dynamic
    loader on s390x. [1] In the kernel they are zero. Therefore no extra
    handling is required to skip these.
    
    Skip adjusting GOT entries with a value of zero in kaslr_adjust_got().
    
    While at it update the comment when a GOT exists on s390x. Since commit
    00cda11d ("s390: Compile kernel with -fPIC and link with -no-pie")
    it no longer only exists when compiling with Clang, but also with GCC.
    
    [1]: s390x ELF ABI, section "Global Offset Table",
         https://github.com/IBM/s390x-abi/releases
    
    Fixes: 778666df ("s390: compile relocatable kernel without -fPIE")
    Reviewed-by: default avatarIlya Leoshkevich <iii@linux.ibm.com>
    Acked-by: default avatarSumanth Korikkar <sumanthk@linux.ibm.com>
    Acked-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
    Signed-off-by: default avatarJens Remus <jremus@linux.ibm.com>
    Signed-off-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
    cea5589e
startup.c 16.5 KB