From: Kees Cook <keescook@chromium.org>
To: Vignesh Balasubramanian <vigbalas@amd.com>
Cc: linux-kernel@vger.kernel.org, linux-toolchains@vger.kernel.org,
mpe@ellerman.id.au, npiggin@gmail.com,
christophe.leroy@csgroup.eu, aneesh.kumar@kernel.org,
naveen.n.rao@linux.ibm.com, ebiederm@xmission.com,
x86@kernel.org, linuxppc-dev@lists.ozlabs.org,
linux-mm@kvack.org, bpetkov@amd.com, jinisusan.george@amd.com,
matz@suse.de, binutils@sourceware.org, jhb@freebsd.org,
felix.willgerodt@intel.com
Subject: Re: [PATCH 1/1] x86/elf: Add a new .note section containing Xfeatures information to x86 core files
Date: Thu, 14 Mar 2024 09:13:00 -0700 [thread overview]
Message-ID: <202403140850.5659C0F4@keescook> (raw)
In-Reply-To: <20240314112359.50713-2-vigbalas@amd.com>
On Thu, Mar 14, 2024 at 04:53:28PM +0530, Vignesh Balasubramanian wrote:
> Add a new .note section containing type, size, offset and flags of
> every xfeature that is present.
>
> This information will be used by the debuggers to understand the XSAVE
> layout of the machine where the core file is dumped, and to read XSAVE
> registers, especially during cross-platform debugging.
I see binutils in CC. Can someone from gdb confirm that this solution
can be used?
>
> Co-developed-by: Jini Susan George <jinisusan.george@amd.com>
> Signed-off-by: Jini Susan George <jinisusan.george@amd.com>
> Signed-off-by: Vignesh Balasubramanian <vigbalas@amd.com>
> ---
> arch/Kconfig | 9 +++
> arch/powerpc/Kconfig | 1 +
> arch/powerpc/include/asm/elf.h | 2 -
> arch/x86/Kconfig | 1 +
> arch/x86/include/asm/elf.h | 7 +++
> arch/x86/kernel/fpu/xstate.c | 101 +++++++++++++++++++++++++++++++++
> include/linux/elf.h | 2 +-
> include/uapi/linux/elf.h | 1 +
> 8 files changed, 121 insertions(+), 3 deletions(-)
>
> diff --git a/arch/Kconfig b/arch/Kconfig
> index fd18b7db2c77..3bd8a0b2bba1 100644
> --- a/arch/Kconfig
> +++ b/arch/Kconfig
> @@ -502,6 +502,15 @@ config MMU_LAZY_TLB_SHOOTDOWN
> config ARCH_HAVE_NMI_SAFE_CMPXCHG
> bool
>
> +config ARCH_HAVE_EXTRA_ELF_NOTES
> + bool
> + help
> + An architecture should select this in order to enable adding an
> + arch-specific ELF note section to core files. It must provide two
> + functions: elf_coredump_extra_notes_size() and
> + elf_coredump_extra_notes_write() which are invoked by the ELF core
> + dumper.
> +
> config ARCH_HAS_NMI_SAFE_THIS_CPU_OPS
> bool
>
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index a91cb070ca4a..3b31bd7490e2 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -156,6 +156,7 @@ config PPC
> select ARCH_HAS_UACCESS_FLUSHCACHE
> select ARCH_HAS_UBSAN
> select ARCH_HAVE_NMI_SAFE_CMPXCHG
> + select ARCH_HAVE_EXTRA_ELF_NOTES if SPU_BASE
> select ARCH_KEEP_MEMBLOCK
> select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE if PPC_RADIX_MMU
> select ARCH_MIGHT_HAVE_PC_PARPORT
> diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
> index 79f1c480b5eb..bb4b94444d3e 100644
> --- a/arch/powerpc/include/asm/elf.h
> +++ b/arch/powerpc/include/asm/elf.h
> @@ -127,8 +127,6 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
> /* Notes used in ET_CORE. Note name is "SPU/<fd>/<filename>". */
> #define NT_SPU 1
>
> -#define ARCH_HAVE_EXTRA_ELF_NOTES
> -
> #endif /* CONFIG_SPU_BASE */
>
> #ifdef CONFIG_PPC64
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 78050d5d7fac..35e8d1201099 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -104,6 +104,7 @@ config X86
> select ARCH_HAS_DEBUG_WX
> select ARCH_HAS_ZONE_DMA_SET if EXPERT
> select ARCH_HAVE_NMI_SAFE_CMPXCHG
> + select ARCH_HAVE_EXTRA_ELF_NOTES
> select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE
> select ARCH_MIGHT_HAVE_ACPI_PDC if ACPI
> select ARCH_MIGHT_HAVE_PC_PARPORT
> diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
> index 1fb83d47711f..1b9f0b4bf6bc 100644
> --- a/arch/x86/include/asm/elf.h
> +++ b/arch/x86/include/asm/elf.h
> @@ -13,6 +13,13 @@
> #include <asm/auxvec.h>
> #include <asm/fsgsbase.h>
>
> +struct xfeat_component {
> + u32 xfeat_type;
> + u32 xfeat_sz;
> + u32 xfeat_off;
> + u32 xfeat_flags;
> +} __packed;
While it is currently true, just for robustness, can you add
a _Static_assert that sizeof(struct xfeat_component) % 4 == 0 ?
Notes must be 4-byte aligned.
> +
> typedef unsigned long elf_greg_t;
>
> #define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
> diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
> index 117e74c44e75..6e5ea483ec1d 100644
> --- a/arch/x86/kernel/fpu/xstate.c
> +++ b/arch/x86/kernel/fpu/xstate.c
> @@ -13,6 +13,7 @@
> #include <linux/seq_file.h>
> #include <linux/proc_fs.h>
> #include <linux/vmalloc.h>
> +#include <linux/coredump.h>
>
> #include <asm/fpu/api.h>
> #include <asm/fpu/regset.h>
> @@ -1836,3 +1837,103 @@ int proc_pid_arch_status(struct seq_file *m, struct pid_namespace *ns,
> return 0;
> }
> #endif /* CONFIG_PROC_PID_ARCH_STATUS */
> +
> +/*
> + * Dump type, size, offset and flag values for every xfeature that is present.
> + */
> +static int dump_xsave_layout_desc(struct coredump_params *cprm)
> +{
> +
> + struct xfeat_component xc;
> + int num_records = 0;
> + int i;
> +
> + /* XFEATURE_FPU and XFEATURE_SSE, both are fixed legacy states. */
> + for (i = 0; i < FIRST_EXTENDED_XFEATURE; i++) {
> + xc.xfeat_type = i;
> + xc.xfeat_sz = xstate_sizes[i];
> + xc.xfeat_off = xstate_offsets[i];
> + xc.xfeat_flags = xstate_flags[i];
> +
> + if (!dump_emit(cprm, &xc, sizeof(struct xfeat_component)))
> + return 0;
> + num_records++;
> + }
> +
> + for_each_extended_xfeature(i, fpu_user_cfg.max_features) {
> + xc.xfeat_type = i;
> + xc.xfeat_sz = xstate_sizes[i];
> + xc.xfeat_off = xstate_offsets[i];
> + xc.xfeat_flags = xstate_flags[i];
> +
> + if (!dump_emit(cprm, &xc, sizeof(struct xfeat_component)))
> + return 0;
> + num_records++;
> + }
> +
> + return num_records;
> +}
> +
> +static int get_xsave_desc_size(void)
> +{
> + /* XFEATURE_FP and XFEATURE_SSE, both are fixed legacy states */
> + int xfeatures_count = 2;
> + int i;
> +
> + for_each_extended_xfeature(i, fpu_user_cfg.max_features)
> + xfeatures_count++;
> +
> + return xfeatures_count * (sizeof(struct xfeat_component));
> +}
> +
> +int elf_coredump_extra_notes_write(struct coredump_params *cprm)
> +{
> + const char *owner_name = "LINUX";
If you use an array instead of a pointer, there's no need for strlen(),
and you can make it a static outside of the function to refer to it
later.
static const char owner_name[] = "LINUX";
> + int num_records = 0;
> + struct elf_note en;
> +
> + en.n_namesz = strlen(owner_name) + 1;
en.n_namesz = sizeof(owner_name);
> + en.n_descsz = get_xsave_desc_size();
> + en.n_type = NT_X86_XSAVE_LAYOUT;
> +
> + if (!dump_emit(cprm, &en, sizeof(en)))
> + return 1;
> + if (!dump_emit(cprm, owner_name, en.n_namesz))
> + return 1;
> + if (!dump_align(cprm, 4))
> + return 1;
> +
> + num_records = dump_xsave_layout_desc(cprm);
> + if (!num_records) {
> + pr_warn("Error adding XSTATE layout ELF note. XSTATE buffer in the core file will be unparseable.");
Can you make this pr_warn_ratelimited() (and below)?
> + return 1;
> + }
> +
> + /* Total size should be equal to the number of records */
> + if ((sizeof(struct xfeat_component) * num_records) != en.n_descsz) {
> + pr_warn("Error adding XSTATE layout ELF note. The size of the .note section does not match with the total size of the records.");
> + return 1;
> + }
> +
> + if (!dump_align(cprm, 4))
> + return 1;
I don't think this call is needed?
> +
> + return 0;
> +}
> +
> +/*
> + * Return the size of new note.
> + */
> +int elf_coredump_extra_notes_size(void)
> +{
> + const char *fullname = "LINUX";
Now this can be dropped.
> + int size = 0;
> +
> + /* NOTE Header */
> + size += sizeof(struct elf_note);
> + /* name + align */
> + size += roundup(strlen(fullname) + 1, 4);
size += roundup(sizeof(owner_name), 4);
> + size += get_xsave_desc_size();
> +
> + return size;
> +}
> diff --git a/include/linux/elf.h b/include/linux/elf.h
> index c9a46c4e183b..5c402788da19 100644
> --- a/include/linux/elf.h
> +++ b/include/linux/elf.h
> @@ -65,7 +65,7 @@ extern Elf64_Dyn _DYNAMIC [];
> struct file;
> struct coredump_params;
>
> -#ifndef ARCH_HAVE_EXTRA_ELF_NOTES
> +#ifndef CONFIG_ARCH_HAVE_EXTRA_ELF_NOTES
> static inline int elf_coredump_extra_notes_size(void) { return 0; }
> static inline int elf_coredump_extra_notes_write(struct coredump_params *cprm) { return 0; }
> #else
> diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
> index 9417309b7230..3325488cb39b 100644
> --- a/include/uapi/linux/elf.h
> +++ b/include/uapi/linux/elf.h
> @@ -411,6 +411,7 @@ typedef struct elf64_shdr {
> #define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
> /* Old binutils treats 0x203 as a CET state */
> #define NT_X86_SHSTK 0x204 /* x86 SHSTK state */
> +#define NT_X86_XSAVE_LAYOUT 0x205 /* XSAVE layout description */
> #define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */
> #define NT_S390_TIMER 0x301 /* s390 timer register */
> #define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */
> --
> 2.43.0
>
Otherwise looks reasonable, though I see Dave has feedback to address
too. :)
Thanks for working on this!
-Kees
--
Kees Cook
next prev parent reply other threads:[~2024-03-14 16:13 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-14 11:23 [PATCH 0/1] Add XSAVE layout description to Core files for debuggers to support varying XSAVE layouts Vignesh Balasubramanian
2024-03-14 11:23 ` [PATCH 1/1] x86/elf: Add a new .note section containing Xfeatures information to x86 core files Vignesh Balasubramanian
2024-03-14 15:37 ` Dave Hansen
2024-03-14 16:08 ` Borislav Petkov
2024-03-14 16:19 ` Dave Hansen
2024-03-14 16:29 ` Borislav Petkov
2024-03-14 16:39 ` Dave Hansen
2024-03-26 9:59 ` Balasubrmanian, Vignesh
2024-03-15 23:51 ` Thomas Gleixner
2024-03-16 10:29 ` Borislav Petkov
2024-03-14 16:45 ` John Baldwin
2024-03-14 17:10 ` Dave Hansen
2024-03-14 17:36 ` John Baldwin
2024-03-14 17:05 ` John Baldwin
2024-03-14 16:13 ` Kees Cook [this message]
2024-03-26 10:06 ` Balasubrmanian, Vignesh
2024-03-14 22:13 ` Michael Ellerman
2024-03-26 10:09 ` Balasubrmanian, Vignesh
2024-03-15 9:59 ` kernel test robot
2024-03-15 12:59 ` kernel test robot
2024-03-14 16:25 ` [PATCH 0/1] Add XSAVE layout description to Core files for debuggers to support varying XSAVE layouts Willgerodt, Felix
2024-03-14 16:33 ` Borislav Petkov
2024-03-15 8:43 ` Willgerodt, Felix
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=202403140850.5659C0F4@keescook \
--to=keescook@chromium.org \
--cc=aneesh.kumar@kernel.org \
--cc=binutils@sourceware.org \
--cc=bpetkov@amd.com \
--cc=christophe.leroy@csgroup.eu \
--cc=ebiederm@xmission.com \
--cc=felix.willgerodt@intel.com \
--cc=jhb@freebsd.org \
--cc=jinisusan.george@amd.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-toolchains@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=matz@suse.de \
--cc=mpe@ellerman.id.au \
--cc=naveen.n.rao@linux.ibm.com \
--cc=npiggin@gmail.com \
--cc=vigbalas@amd.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox