lkml.org 
[lkml]   [2019]   [Oct]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.3 159/197] s390/kaslr: add support for R_390_GLOB_DAT relocation type
    Date
    From: Gerald Schaefer <gerald.schaefer@de.ibm.com>

    commit ac49303d9ef0ad98b79867a380ef23480e48870b upstream.

    Commit "bpf: Process in-kernel BTF" in linux-next introduced an undefined
    __weak symbol, which results in an R_390_GLOB_DAT relocation type. That
    is not yet handled by the KASLR relocation code, and the kernel stops with
    the message "Unknown relocation type".

    Add code to detect and handle R_390_GLOB_DAT relocation types and undefined
    symbols.

    Fixes: 805bc0bc238f ("s390/kernel: build a relocatable kernel")
    Cc: <stable@vger.kernel.org> # v5.2+
    Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com>
    Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
    Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/s390/boot/startup.c | 14 +++++++++++---
    arch/s390/kernel/machine_kexec_reloc.c | 1 +
    2 files changed, 12 insertions(+), 3 deletions(-)

    --- a/arch/s390/boot/startup.c
    +++ b/arch/s390/boot/startup.c
    @@ -101,10 +101,18 @@ static void handle_relocs(unsigned long
    dynsym = (Elf64_Sym *) vmlinux.dynsym_start;
    for (rela = rela_start; rela < rela_end; rela++) {
    loc = rela->r_offset + offset;
    - val = rela->r_addend + offset;
    + val = rela->r_addend;
    r_sym = ELF64_R_SYM(rela->r_info);
    - if (r_sym)
    - val += dynsym[r_sym].st_value;
    + if (r_sym) {
    + if (dynsym[r_sym].st_shndx != SHN_UNDEF)
    + val += dynsym[r_sym].st_value + offset;
    + } else {
    + /*
    + * 0 == undefined symbol table index (STN_UNDEF),
    + * used for R_390_RELATIVE, only add KASLR offset
    + */
    + val += offset;
    + }
    r_type = ELF64_R_TYPE(rela->r_info);
    rc = arch_kexec_do_relocs(r_type, (void *) loc, val, 0);
    if (rc)
    --- a/arch/s390/kernel/machine_kexec_reloc.c
    +++ b/arch/s390/kernel/machine_kexec_reloc.c
    @@ -27,6 +27,7 @@ int arch_kexec_do_relocs(int r_type, voi
    *(u32 *)loc = val;
    break;
    case R_390_64: /* Direct 64 bit. */
    + case R_390_GLOB_DAT:
    *(u64 *)loc = val;
    break;
    case R_390_PC16: /* PC relative 16 bit. */

    \
     
     \ /
      Last update: 2019-10-27 22:28    [W:8.487 / U:0.140 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site