Re: [PATCH v2 4/4] x86/boot: Check that there are no runtime relocations

From: Fangrui Song
Date: Tue May 26 2020 - 13:13:50 EST

On 2020-05-26, Arvind Sankar wrote:
On Tue, May 26, 2020 at 08:11:56AM +0200, Ard Biesheuvel wrote:
On Tue, 26 May 2020 at 00:59, Arvind Sankar <nivedita@xxxxxxxxxxxx> wrote:
> # Compressed kernel should be built as PIE since it may be loaded at any
> # address by the bootloader.
> -KBUILD_LDFLAGS += $(call ld-option, -pie) $(call ld-option, --no-dynamic-linker)
> +KBUILD_LDFLAGS += -pie $(call ld-option, --no-dynamic-linker)

Do we still need -pie linking with these changes applied?

I think it's currently not strictly necessary -- eg the 64bit kernel
doesn't get linked as pie right now with LLD or old binutils. However,
it is safer to do so to ensure that the result remains PIC with future
versions of the linker. There are linker optimizations that can convert
certain PIC instructions when PIE is disabled. While I think they
currently all focus on eliminating indirection through the GOT (and thus
wouldn't be applicable any more),

There are 3 forms described by x86-64 psABI B.2 Optimize GOTPCRELX Relocations

(1) movq foo@GOTPCREL(%rip), %reg -> leaq foo(%rip), %reg
(2) call *foo@GOTPCREL(%rip) -> nop; call foo
(3) jmp *foo@GOTPCREL(%rip) -> jmp foo; nop

ld.bfd and gold perform (1) even for R_X86_64_GOTPCREL. LLD requires R_X86_64_[REX_]GOTPCRELX

it's easy to imagine that they could
get extended to, for eg, convert
leaq foo(%rip), %rax
movl $foo, %eax
with some nop padding, etc.

Not with NOP padding, but probably with instruction prefixes. It is
unclear the rewriting will be beneficial. Rewriting instructions definitely requires a
dedicated relocation type like R_X86_64_[REX_]GOTPCRELX.

Also, the relocation check that's being added here would only work with
PIE linking.