Commit 50157eaa authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull execve updates from Kees Cook:

 - binfmt_elf: preserve original ELF e_flags for core dumps (Svetlana
   Parfenova)

 - exec: Fix incorrect type for ret (Xichao Zhao)

 - binfmt_elf: Replace offsetof() with struct_size() in fill_note_info()
   (Xichao Zhao)

* tag 'execve-v6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
  binfmt_elf: preserve original ELF e_flags for core dumps
  binfmt_elf: Replace offsetof() with struct_size() in fill_note_info()
  exec: Fix incorrect type for ret
parents 8c1ed302 8c94db0a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ config RISCV
	select ARCH_HAS_DEBUG_VIRTUAL if MMU
	select ARCH_HAS_DEBUG_VM_PGTABLE
	select ARCH_HAS_DEBUG_WX
	select ARCH_HAS_ELF_CORE_EFLAGS
	select ARCH_HAS_FAST_MULTIPLIER
	select ARCH_HAS_FORTIFY_SOURCE
	select ARCH_HAS_GCOV_PROFILE_ALL
+9 −0
Original line number Diff line number Diff line
@@ -184,4 +184,13 @@ config EXEC_KUNIT_TEST
	  This builds the exec KUnit tests, which tests boundary conditions
	  of various aspects of the exec internals.

config ARCH_HAS_ELF_CORE_EFLAGS
	bool
	depends on BINFMT_ELF && ELF_CORE
	default n
	help
	  Select this option if the architecture makes use of the e_flags
	  field in the ELF header to store ABI or other architecture-specific
	  information that should be preserved in core dumps.

endmenu
+37 −11
Original line number Diff line number Diff line
@@ -103,6 +103,21 @@ static struct linux_binfmt elf_format = {

#define BAD_ADDR(x) (unlikely((unsigned long)(x) >= TASK_SIZE))

static inline void elf_coredump_set_mm_eflags(struct mm_struct *mm, u32 flags)
{
#ifdef CONFIG_ARCH_HAS_ELF_CORE_EFLAGS
	mm->saved_e_flags = flags;
#endif
}

static inline u32 elf_coredump_get_mm_eflags(struct mm_struct *mm, u32 flags)
{
#ifdef CONFIG_ARCH_HAS_ELF_CORE_EFLAGS
	flags = mm->saved_e_flags;
#endif
	return flags;
}

/*
 * We need to explicitly zero any trailing portion of the page that follows
 * p_filesz when it ends before the page ends (e.g. bss), otherwise this
@@ -1290,6 +1305,8 @@ static int load_elf_binary(struct linux_binprm *bprm)
	mm->end_data = end_data;
	mm->start_stack = bprm->p;

	elf_coredump_set_mm_eflags(mm, elf_ex->e_flags);

	/**
	 * DOC: "brk" handling
	 *
@@ -1804,6 +1821,8 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
	struct elf_thread_core_info *t;
	struct elf_prpsinfo *psinfo;
	struct core_thread *ct;
	u16 machine;
	u32 flags;

	psinfo = kmalloc(sizeof(*psinfo), GFP_KERNEL);
	if (!psinfo)
@@ -1831,30 +1850,37 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
		return 0;
	}

	/*
	 * Initialize the ELF file header.
	 */
	fill_elf_header(elf, phdrs,
			view->e_machine, view->e_flags);
	machine = view->e_machine;
	flags = view->e_flags;
#else
	view = NULL;
	info->thread_notes = 2;
	fill_elf_header(elf, phdrs, ELF_ARCH, ELF_CORE_EFLAGS);
	machine = ELF_ARCH;
	flags = ELF_CORE_EFLAGS;
#endif

	/*
	 * Override ELF e_flags with value taken from process,
	 * if arch needs that.
	 */
	flags = elf_coredump_get_mm_eflags(dump_task->mm, flags);

	/*
	 * Initialize the ELF file header.
	 */
	fill_elf_header(elf, phdrs, machine, flags);

	/*
	 * Allocate a structure for each thread.
	 */
	info->thread = kzalloc(offsetof(struct elf_thread_core_info,
				     notes[info->thread_notes]),
	info->thread = kzalloc(struct_size(info->thread, notes, info->thread_notes),
			       GFP_KERNEL);
	if (unlikely(!info->thread))
		return 0;

	info->thread->task = dump_task;
	for (ct = dump_task->signal->core_state->dumper.next; ct; ct = ct->next) {
		t = kzalloc(offsetof(struct elf_thread_core_info,
				     notes[info->thread_notes]),
		t = kzalloc(struct_size(t, notes, info->thread_notes),
			    GFP_KERNEL);
		if (unlikely(!t))
			return 0;
+1 −1
Original line number Diff line number Diff line
@@ -599,7 +599,7 @@ int setup_arg_pages(struct linux_binprm *bprm,
		    unsigned long stack_top,
		    int executable_stack)
{
	unsigned long ret;
	int ret;
	unsigned long stack_shift;
	struct mm_struct *mm = current->mm;
	struct vm_area_struct *vma = bprm->vma;
+5 −0
Original line number Diff line number Diff line
@@ -1107,6 +1107,11 @@ struct mm_struct {

		unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */

#ifdef CONFIG_ARCH_HAS_ELF_CORE_EFLAGS
		/* the ABI-related flags from the ELF header. Used for core dump */
		unsigned long saved_e_flags;
#endif

		struct percpu_counter rss_stat[NR_MM_COUNTERS];

		struct linux_binfmt *binfmt;