Commit 223abe96 authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Juergen Gross
Browse files

x86/xen: Avoid relocatable quantities in Xen ELF notes



Xen puts virtual and physical addresses into ELF notes that are treated
by the linker as relocatable by default. Doing so is not only pointless,
given that the ELF notes are only intended for consumption by Xen before
the kernel boots. It is also a KASLR leak, given that the kernel's ELF
notes are exposed via the world readable /sys/kernel/notes.

So emit these constants in a way that prevents the linker from marking
them as relocatable. This involves place-relative relocations (which
subtract their own virtual address from the symbol value) and linker
provided absolute symbols that add the address of the place to the
desired value.

Tested-by: default avatarJason Andryuk <jason.andryuk@amd.com>
Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
Reviewed-by: default avatarJason Andryuk <jason.andryuk@amd.com>
Message-ID: <20241009160438.3884381-11-ardb+git@google.com>
Signed-off-by: default avatarJuergen Gross <jgross@suse.com>
parent d5835423
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -528,3 +528,22 @@ INIT_PER_CPU(irq_stack_backing_store);
#endif

#endif /* CONFIG_X86_64 */

/*
 * The symbols below are referenced using relative relocations in the
 * respective ELF notes. This produces build time constants that the
 * linker will never mark as relocatable. (Using just ABSOLUTE() is not
 * sufficient for that).
 */
#ifdef CONFIG_XEN
#ifdef CONFIG_XEN_PV
xen_elfnote_entry_value =
	ABSOLUTE(xen_elfnote_entry) + ABSOLUTE(startup_xen);
#endif
xen_elfnote_hypercall_page_value =
	ABSOLUTE(xen_elfnote_hypercall_page) + ABSOLUTE(hypercall_page);
#endif
#ifdef CONFIG_PVH
xen_elfnote_phys32_entry_value =
	ABSOLUTE(xen_elfnote_phys32_entry) + ABSOLUTE(pvh_start_xen - LOAD_OFFSET);
#endif
+3 −3
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@
#define PVH_CS_SEL		(PVH_GDT_ENTRY_CS * 8)
#define PVH_DS_SEL		(PVH_GDT_ENTRY_DS * 8)

SYM_CODE_START_LOCAL(pvh_start_xen)
SYM_CODE_START(pvh_start_xen)
	UNWIND_HINT_END_OF_STACK
	cld

@@ -300,5 +300,5 @@ SYM_DATA_END(pvh_level2_kernel_pgt)
		     .long KERNEL_IMAGE_SIZE - 1)
#endif

	ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY,
	             _ASM_PTR (pvh_start_xen - __START_KERNEL_map))
	ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY, .global xen_elfnote_phys32_entry;
		xen_elfnote_phys32_entry: _ASM_PTR xen_elfnote_phys32_entry_value - .)
+1 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = {
	[S_ABS] =
	"^(xen_irq_disable_direct_reloc$|"
	"xen_save_fl_direct_reloc$|"
	"xen_elfnote_.+_offset$|"
	"VDSO|"
	"__kcfi_typeid_|"
	"__crc_)",
+4 −2
Original line number Diff line number Diff line
@@ -94,7 +94,8 @@ SYM_CODE_END(xen_cpu_bringup_again)
	ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE,      _ASM_PTR __START_KERNEL_map)
	/* Map the p2m table to a 512GB-aligned user address. */
	ELFNOTE(Xen, XEN_ELFNOTE_INIT_P2M,       .quad (PUD_SIZE * PTRS_PER_PUD))
	ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          _ASM_PTR startup_xen)
	ELFNOTE(Xen, XEN_ELFNOTE_ENTRY,          .globl xen_elfnote_entry;
		xen_elfnote_entry: _ASM_PTR xen_elfnote_entry_value - .)
	ELFNOTE(Xen, XEN_ELFNOTE_FEATURES,       .ascii "!writable_page_tables")
	ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE,       .asciz "yes")
	ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,
@@ -115,7 +116,8 @@ SYM_CODE_END(xen_cpu_bringup_again)
#else
# define FEATURES_DOM0 0
#endif
	ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, _ASM_PTR hypercall_page)
	ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .globl xen_elfnote_hypercall_page;
		xen_elfnote_hypercall_page: _ASM_PTR xen_elfnote_hypercall_page_value - .)
	ELFNOTE(Xen, XEN_ELFNOTE_SUPPORTED_FEATURES,
		.long FEATURES_PV | FEATURES_PVH | FEATURES_DOM0)
	ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz "generic")