Re: [PATCH 4/8] binfmt_elf: open code copy_siginfo_to_user to kernelspace buffer

From: Michael Ellerman
Date: Tue Apr 14 2020 - 23:01:54 EST


Christoph Hellwig <hch@xxxxxx> writes:

> Instead of messing with the address limit just open code the trivial
> memcpy + memset logic for the native version, and a call to
> to_compat_siginfo for the compat version.
>
> Signed-off-by: Christoph Hellwig <hch@xxxxxx>
> ---
> fs/binfmt_elf.c | 9 +++++----
> fs/compat_binfmt_elf.c | 6 +++++-
> 2 files changed, 10 insertions(+), 5 deletions(-)
>
> diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
> index 13f25e241ac4..607c5a5f855e 100644
> --- a/fs/binfmt_elf.c
> +++ b/fs/binfmt_elf.c
> @@ -1553,15 +1553,16 @@ static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm)
> fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv);
> }
>
> +#ifndef fill_siginfo_note
> static void fill_siginfo_note(struct memelfnote *note, user_siginfo_t *csigdata,
> const kernel_siginfo_t *siginfo)
> {
> - mm_segment_t old_fs = get_fs();
> - set_fs(KERNEL_DS);
> - copy_siginfo_to_user((user_siginfo_t __user *) csigdata, siginfo);
> - set_fs(old_fs);
> + memcpy(csigdata, siginfo, sizeof(struct kernel_siginfo));
> + memset((char *)csigdata + sizeof(struct kernel_siginfo), 0,
> + SI_EXPANSION_SIZE);
> fill_note(note, "CORE", NT_SIGINFO, sizeof(*csigdata), csigdata);
> }
> +#endif
>
> #define MAX_FILE_NOTE_SIZE (4*1024*1024)
> /*
> diff --git a/fs/compat_binfmt_elf.c b/fs/compat_binfmt_elf.c
> index aaad4ca1217e..ab84e095618b 100644
> --- a/fs/compat_binfmt_elf.c
> +++ b/fs/compat_binfmt_elf.c
> @@ -39,7 +39,11 @@
> */
> #define user_long_t compat_long_t
> #define user_siginfo_t compat_siginfo_t
> -#define copy_siginfo_to_user copy_siginfo_to_user32
> +#define fill_siginfo_note(note, csigdata, siginfo) \
> +do { \
> + to_compat_siginfo(csigdata, siginfo, compat_siginfo_flags()); \
> + fill_note(note, "CORE", NT_SIGINFO, sizeof(*csigdata), csigdata); \
> +} while (0)

This doesn't build on ppc (cell_defconfig):

../fs/binfmt_elf.c: In function 'fill_note_info':
../fs/compat_binfmt_elf.c:44:39: error: implicit declaration of function 'compat_siginfo_flags'; did you mean 'to_compat_siginfo'? [-Werror=implicit-function-d
eclaration]
to_compat_siginfo(csigdata, siginfo, compat_siginfo_flags()); \
^~~~~~~~~~~~~~~~~~~~
../fs/binfmt_elf.c:1846:2: note: in expansion of macro 'fill_siginfo_note'
fill_siginfo_note(&info->signote, &info->csigdata, siginfo);
^~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
make[2]: *** [../scripts/Makefile.build:266: fs/compat_binfmt_elf.o] Error 1


I guess the empty version from kernel/signal.c needs to move into a
header somewhere.

cheers