Skip to content

Commit 50157ea

Browse files
committed
Merge tag 'execve-v6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
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
2 parents 8c1ed30 + 8c94db0 commit 50157ea

5 files changed

Lines changed: 53 additions & 12 deletions

File tree

arch/riscv/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ config RISCV
2828
select ARCH_HAS_DEBUG_VIRTUAL if MMU
2929
select ARCH_HAS_DEBUG_VM_PGTABLE
3030
select ARCH_HAS_DEBUG_WX
31+
select ARCH_HAS_ELF_CORE_EFLAGS
3132
select ARCH_HAS_FAST_MULTIPLIER
3233
select ARCH_HAS_FORTIFY_SOURCE
3334
select ARCH_HAS_GCOV_PROFILE_ALL

fs/Kconfig.binfmt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,4 +184,13 @@ config EXEC_KUNIT_TEST
184184
This builds the exec KUnit tests, which tests boundary conditions
185185
of various aspects of the exec internals.
186186

187+
config ARCH_HAS_ELF_CORE_EFLAGS
188+
bool
189+
depends on BINFMT_ELF && ELF_CORE
190+
default n
191+
help
192+
Select this option if the architecture makes use of the e_flags
193+
field in the ELF header to store ABI or other architecture-specific
194+
information that should be preserved in core dumps.
195+
187196
endmenu

fs/binfmt_elf.c

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,21 @@ static struct linux_binfmt elf_format = {
103103

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

106+
static inline void elf_coredump_set_mm_eflags(struct mm_struct *mm, u32 flags)
107+
{
108+
#ifdef CONFIG_ARCH_HAS_ELF_CORE_EFLAGS
109+
mm->saved_e_flags = flags;
110+
#endif
111+
}
112+
113+
static inline u32 elf_coredump_get_mm_eflags(struct mm_struct *mm, u32 flags)
114+
{
115+
#ifdef CONFIG_ARCH_HAS_ELF_CORE_EFLAGS
116+
flags = mm->saved_e_flags;
117+
#endif
118+
return flags;
119+
}
120+
106121
/*
107122
* We need to explicitly zero any trailing portion of the page that follows
108123
* 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)
12901305
mm->end_data = end_data;
12911306
mm->start_stack = bprm->p;
12921307

1308+
elf_coredump_set_mm_eflags(mm, elf_ex->e_flags);
1309+
12931310
/**
12941311
* DOC: "brk" handling
12951312
*
@@ -1804,6 +1821,8 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
18041821
struct elf_thread_core_info *t;
18051822
struct elf_prpsinfo *psinfo;
18061823
struct core_thread *ct;
1824+
u16 machine;
1825+
u32 flags;
18071826

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

1834-
/*
1835-
* Initialize the ELF file header.
1836-
*/
1837-
fill_elf_header(elf, phdrs,
1838-
view->e_machine, view->e_flags);
1853+
machine = view->e_machine;
1854+
flags = view->e_flags;
18391855
#else
18401856
view = NULL;
18411857
info->thread_notes = 2;
1842-
fill_elf_header(elf, phdrs, ELF_ARCH, ELF_CORE_EFLAGS);
1858+
machine = ELF_ARCH;
1859+
flags = ELF_CORE_EFLAGS;
18431860
#endif
18441861

1862+
/*
1863+
* Override ELF e_flags with value taken from process,
1864+
* if arch needs that.
1865+
*/
1866+
flags = elf_coredump_get_mm_eflags(dump_task->mm, flags);
1867+
1868+
/*
1869+
* Initialize the ELF file header.
1870+
*/
1871+
fill_elf_header(elf, phdrs, machine, flags);
1872+
18451873
/*
18461874
* Allocate a structure for each thread.
18471875
*/
1848-
info->thread = kzalloc(offsetof(struct elf_thread_core_info,
1849-
notes[info->thread_notes]),
1850-
GFP_KERNEL);
1876+
info->thread = kzalloc(struct_size(info->thread, notes, info->thread_notes),
1877+
GFP_KERNEL);
18511878
if (unlikely(!info->thread))
18521879
return 0;
18531880

18541881
info->thread->task = dump_task;
18551882
for (ct = dump_task->signal->core_state->dumper.next; ct; ct = ct->next) {
1856-
t = kzalloc(offsetof(struct elf_thread_core_info,
1857-
notes[info->thread_notes]),
1883+
t = kzalloc(struct_size(t, notes, info->thread_notes),
18581884
GFP_KERNEL);
18591885
if (unlikely(!t))
18601886
return 0;

fs/exec.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ int setup_arg_pages(struct linux_binprm *bprm,
599599
unsigned long stack_top,
600600
int executable_stack)
601601
{
602-
unsigned long ret;
602+
int ret;
603603
unsigned long stack_shift;
604604
struct mm_struct *mm = current->mm;
605605
struct vm_area_struct *vma = bprm->vma;

include/linux/mm_types.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,6 +1107,11 @@ struct mm_struct {
11071107

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

1110+
#ifdef CONFIG_ARCH_HAS_ELF_CORE_EFLAGS
1111+
/* the ABI-related flags from the ELF header. Used for core dump */
1112+
unsigned long saved_e_flags;
1113+
#endif
1114+
11101115
struct percpu_counter rss_stat[NR_MM_COUNTERS];
11111116

11121117
struct linux_binfmt *binfmt;

0 commit comments

Comments
 (0)