Commit 6411e75a authored by Zheng Zengkai's avatar Zheng Zengkai Committed by Aichun Shi
Browse files

mm: Fix kabi change caused by saved_auxv[] in mm_struct for x86_64

openeuler inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/intel-kernel/issues/I5RQLJ


CVE: NA

Intel-SIG: mm: Fix kabi change caused by saved_auxv[] in mm_struct for x86_64.

--------------------------------

Use the KABI_DEPRECATE and KABI_USE macro to fix kabi change caused by commit 1c33bb05 ("x86/elf: Support a new ELF
aux vector AT_MINSIGSTKSZ").

The extended saved_auxv[] causes the kabi breakage, move the saved_auxv[] to the end of struct mm_struct.
To avoid introducing too many size increase of mm_struct, use a pointer to indirectly reference the relocated saved_auxv[], then adapt the code where
mm->saved_auxv is used.

Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
Signed-off-by: default avatarLin Wang <lin.x.wang@intel.com>
Signed-off-by: default avatarAichun Shi <aichun.shi@intel.com>
parent 5a2451f1
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -13,8 +13,10 @@
/* entries in ARCH_DLINFO: */
#if defined(CONFIG_IA32_EMULATION) || !defined(CONFIG_X86_64)
# define AT_VECTOR_SIZE_ARCH 3
# define ORIG_AT_VECTOR_SIZE_ARCH 2
#else /* else it's non-compat x86-64 */
# define AT_VECTOR_SIZE_ARCH 2
# define ORIG_AT_VECTOR_SIZE_ARCH 1
#endif

#endif /* _ASM_X86_AUXVEC_H */
+6 −6
Original line number Diff line number Diff line
@@ -236,7 +236,7 @@ create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,
		return -EFAULT;

	/* Create the ELF interpreter info */
	elf_info = (elf_addr_t *)mm->saved_auxv;
	elf_info = (elf_addr_t *)MM_SAVED_AUXV(mm);
	/* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */
#define NEW_AUX_ENT(id, val) \
	do { \
@@ -285,13 +285,13 @@ create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,
	}
#undef NEW_AUX_ENT
	/* AT_NULL is zero; clear the rest too */
	memset(elf_info, 0, (char *)mm->saved_auxv +
			sizeof(mm->saved_auxv) - (char *)elf_info);
	memset(elf_info, 0, (char *)MM_SAVED_AUXV(mm) +
			sizeof(MM_SAVED_AUXV(mm)) - (char *)elf_info);

	/* And advance past the AT_NULL entry.  */
	elf_info += 2;

	ei_index = elf_info - (elf_addr_t *)mm->saved_auxv;
	ei_index = elf_info - (elf_addr_t *)MM_SAVED_AUXV(mm);
	sp = STACK_ADD(p, ei_index);

	items = (argc + 1) + (envc + 1) + 1;
@@ -352,7 +352,7 @@ create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,
	mm->env_end = p;

	/* Put the elf_info on the stack in the right place.  */
	if (copy_to_user(sp, mm->saved_auxv, ei_index * sizeof(elf_addr_t)))
	if (copy_to_user(sp, MM_SAVED_AUXV(mm), ei_index * sizeof(elf_addr_t)))
		return -EFAULT;
	return 0;
}
@@ -1586,7 +1586,7 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,

static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm)
{
	elf_addr_t *auxv = (elf_addr_t *) mm->saved_auxv;
	elf_addr_t *auxv = (elf_addr_t *) MM_SAVED_AUXV(mm);
	int i = 0;
	do
		i += 2;
+1 −1
Original line number Diff line number Diff line
@@ -1550,7 +1550,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
	fill_note(&psinfo_note, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo);
	thread_status_size += notesize(&psinfo_note);

	auxv = (elf_addr_t *) current->mm->saved_auxv;
	auxv = (elf_addr_t *) current->MM_SAVED_AUXV(mm);
	i = 0;
	do
		i += 2;
+3 −3
Original line number Diff line number Diff line
@@ -1038,9 +1038,9 @@ static ssize_t auxv_read(struct file *file, char __user *buf,
		return 0;
	do {
		nwords += 2;
	} while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
	return simple_read_from_buffer(buf, count, ppos, mm->saved_auxv,
				       nwords * sizeof(mm->saved_auxv[0]));
	} while (MM_SAVED_AUXV(mm)[nwords - 2] != 0); /* AT_NULL */
	return simple_read_from_buffer(buf, count, ppos, MM_SAVED_AUXV(mm),
				       nwords * sizeof(MM_SAVED_AUXV(mm)[0]));
}

static const struct file_operations proc_auxv_operations = {
+30 −0
Original line number Diff line number Diff line
@@ -24,6 +24,21 @@
#endif
#define AT_VECTOR_SIZE (2*(AT_VECTOR_SIZE_ARCH + AT_VECTOR_SIZE_BASE + 1))

#define _MM_STRUCT_SIZE (sizeof(struct mm_struct) + cpumask_size())

#if defined(CONFIG_X86_64)
	#define ORIG_AT_VECTOR_SIZE (2*(ORIG_AT_VECTOR_SIZE_ARCH + AT_VECTOR_SIZE_BASE + 1))
	#define MM_SAVED_AUXV(mm) mm->mm_extend->saved_auxv
	#define MM_STRUCT_SIZE (_MM_STRUCT_SIZE + sizeof(struct mm_struct_extend))
	#define OFFSET_OF_MM_SAVED_AUXV (_MM_STRUCT_SIZE + offsetof(struct mm_struct_extend, saved_auxv))
	#define SIZE_OF_MM_SAVED_AUXV sizeof_field(struct mm_struct_extend, saved_auxv)
#else
	#define MM_SAVED_AUXV(mm) mm->saved_auxv
	#define MM_STRUCT_SIZE _MM_STRUCT_SIZE
	#define OFFSET_OF_MM_SAVED_AUXV offsetof(struct mm_struct, saved_auxv)
	#define SIZE_OF_MM_SAVED_AUXV sizeof_field(struct mm_struct, saved_auxv)
#endif

#define INIT_PASID	0

struct address_space;
@@ -394,6 +409,13 @@ struct core_state {
};

struct kioctx_table;

#if defined(CONFIG_X86_64)
struct mm_struct_extend {
	unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */
};
#endif

struct mm_struct {
	struct {
		struct vm_area_struct *mmap;		/* list of VMAs */
@@ -508,7 +530,11 @@ struct mm_struct {
		unsigned long start_brk, brk, start_stack;
		unsigned long arg_start, arg_end, env_start, env_end;

#if defined(CONFIG_X86_64)
		KABI_DEPRECATE(unsigned long, saved_auxv[ORIG_AT_VECTOR_SIZE])
#else
		unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */
#endif

		/*
		 * Special counters, in some configurations protected by the
@@ -592,7 +618,11 @@ struct mm_struct {
#endif
	} __randomize_layout;

#if defined(CONFIG_X86_64)
	KABI_USE(1, struct mm_struct_extend *mm_extend)
#else
	KABI_RESERVE(1)
#endif
	KABI_RESERVE(2)
	KABI_RESERVE(3)
	KABI_RESERVE(4)
Loading