Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e35ac62d authored by Russell King's avatar Russell King
Browse files

Merge branch 'security-fixes' into fixes

parents 24195cad 8c0cc8a5
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -130,8 +130,10 @@ struct mm_struct;
extern unsigned long arch_randomize_brk(struct mm_struct *mm);
extern unsigned long arch_randomize_brk(struct mm_struct *mm);
#define arch_randomize_brk arch_randomize_brk
#define arch_randomize_brk arch_randomize_brk


#ifdef CONFIG_MMU
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
struct linux_binprm;
struct linux_binprm;
int arch_setup_additional_pages(struct linux_binprm *, int);
int arch_setup_additional_pages(struct linux_binprm *, int);
#endif


#endif
#endif
+5 −4
Original line number Original line Diff line number Diff line
@@ -474,17 +474,18 @@ const char *arch_vma_name(struct vm_area_struct *vma)
		 "[sigpage]" : NULL;
		 "[sigpage]" : NULL;
}
}


static struct page *signal_page;
extern struct page *get_signal_page(void);
extern struct page *get_signal_page(void);


int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
{
{
	struct mm_struct *mm = current->mm;
	struct mm_struct *mm = current->mm;
	struct page *page;
	unsigned long addr;
	unsigned long addr;
	int ret;
	int ret;


	page = get_signal_page();
	if (!signal_page)
	if (!page)
		signal_page = get_signal_page();
	if (!signal_page)
		return -ENOMEM;
		return -ENOMEM;


	down_write(&mm->mmap_sem);
	down_write(&mm->mmap_sem);
@@ -496,7 +497,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)


	ret = install_special_mapping(mm, addr, PAGE_SIZE,
	ret = install_special_mapping(mm, addr, PAGE_SIZE,
		VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
		VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
		&page);
		&signal_page);


	if (ret == 0)
	if (ret == 0)
		mm->context.sigpage = addr;
		mm->context.sigpage = addr;
+24 −24
Original line number Original line Diff line number Diff line
@@ -402,7 +402,8 @@ setup_return(struct pt_regs *regs, struct ksignal *ksig,
		    __put_user(sigreturn_codes[idx+1], rc+1))
		    __put_user(sigreturn_codes[idx+1], rc+1))
			return 1;
			return 1;


		if ((cpsr & MODE32_BIT) && !IS_ENABLED(CONFIG_ARM_MPU)) {
#ifdef CONFIG_MMU
		if (cpsr & MODE32_BIT) {
			struct mm_struct *mm = current->mm;
			struct mm_struct *mm = current->mm;


			/*
			/*
@@ -412,7 +413,9 @@ setup_return(struct pt_regs *regs, struct ksignal *ksig,
			 */
			 */
			retcode = mm->context.sigpage + signal_return_offset +
			retcode = mm->context.sigpage + signal_return_offset +
				  (idx << 2) + thumb;
				  (idx << 2) + thumb;
		} else {
		} else
#endif
		{
			/*
			/*
			 * Ensure that the instruction cache sees
			 * Ensure that the instruction cache sees
			 * the return code written onto the stack.
			 * the return code written onto the stack.
@@ -614,21 +617,19 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
	return 0;
	return 0;
}
}


static struct page *signal_page;

struct page *get_signal_page(void)
struct page *get_signal_page(void)
{
{
	if (!signal_page) {
	unsigned long ptr;
	unsigned long ptr;
	unsigned offset;
	unsigned offset;
	struct page *page;
	void *addr;
	void *addr;


		signal_page = alloc_pages(GFP_KERNEL, 0);
	page = alloc_pages(GFP_KERNEL, 0);


		if (!signal_page)
	if (!page)
		return NULL;
		return NULL;


		addr = page_address(signal_page);
	addr = page_address(page);


	/* Give the signal return code some randomness */
	/* Give the signal return code some randomness */
	offset = 0x200 + (get_random_int() & 0x7fc);
	offset = 0x200 + (get_random_int() & 0x7fc);
@@ -642,7 +643,6 @@ struct page *get_signal_page(void)


	ptr = (unsigned long)addr + offset;
	ptr = (unsigned long)addr + offset;
	flush_icache_range(ptr, ptr + sizeof(sigreturn_codes));
	flush_icache_range(ptr, ptr + sizeof(sigreturn_codes));
	}


	return signal_page;
	return page;
}
}