Skip to contentSkip to conversation

ARM: minor sigpage enhancements

PATCH New Nathan Lynch 2 participants 5 messages Jul 14, 2014 – Jul 18, 2014 Arm (32-bit)

lore
Share & tools
lore
#0 lore raw

cover ARM: minor sigpage enhancements

Russell,

Would you consider taking these for 3.17? I've been carrying the sigpage placement randomization as part of the VDSO patch set but it seems worthwhile on its own. Using _install_special_mapping for the VDSO and similar VMAs was recently suggested by Andy Lutomirski.

Nathan Lynch (2):
ARM: use _install_special_mapping for sigpage
ARM: place sigpage at a random offset above stack

 arch/arm/kernel/process.c | 60 ++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 51 insertions(+), 9 deletions(-)
Signature · 1 line
1.9.3
#1 lore raw

PATCH 1/2 ARM: use _install_special_mapping for sigpage

_install_special_mapping allows the VMA to be identifed in /proc/pid/maps without the use of arch_vma_name, providing a slight net reduction in object size:

  text    data     bss     dec     hex filename
  2996      96     144    3236     ca4 arch/arm/kernel/process.o (before)
  2956     104     144    3204     c84 arch/arm/kernel/process.o (after)
---
 arch/arm/kernel/process.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)
arch/arm/kernel/process.c +16 -8
index 81ef686a91ca..46fbbb3701a0 100644
@@ -472,19 +472,23 @@ int in_gate_area_no_mm(unsigned long addr)
 
 const char *arch_vma_name(struct vm_area_struct *vma)
 {
-	return is_gate_vma(vma) ? "[vectors]" :
-		(vma->vm_mm && vma->vm_start == vma->vm_mm->context.sigpage) ?
-		 "[sigpage]" : NULL;
+	return is_gate_vma(vma) ? "[vectors]" : NULL;
 }
 
 static struct page *signal_page;
 extern struct page *get_signal_page(void);
 
+static const struct vm_special_mapping sigpage_mapping = {
+	.name = "[sigpage]",
+	.pages = &signal_page,
+};
+
 int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 {
 	struct mm_struct *mm = current->mm;
+	struct vm_area_struct *vma;
 	unsigned long addr;
-	int ret;
+	int ret = 0;
 
 	if (!signal_page)
 		signal_page = get_signal_page();
@@ -498,12 +502,16 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 		goto up_fail;
 	}
 
-	ret = install_special_mapping(mm, addr, PAGE_SIZE,
+	vma = _install_special_mapping(mm, addr, PAGE_SIZE,
 		VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
-		&signal_page);
+		&sigpage_mapping);
+
+	if (IS_ERR(vma)) {
+		ret = PTR_ERR(vma);
+		goto up_fail;
+	}
 
-	if (ret == 0)
-		mm->context.sigpage = addr;
+	mm->context.sigpage = addr;
 
  up_fail:
 	up_write(&mm->mmap_sem);
Signature · 1 line
1.9.3
#2 lore raw

PATCH 2/2 ARM: place sigpage at a random offset above stack

In reply to Nathan Lynch

The sigpage is currently placed alongside shared libraries etc in the address space. Similar to what x86_64 does for its VDSO, place the sigpage at a randomized offset above the stack so that learning the base address of the sigpage doesn't help expose where shared libraries are loaded in the address space (and vice versa).

---
 arch/arm/kernel/process.c | 36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)
arch/arm/kernel/process.c +35 -1
index 46fbbb3701a0..9e0d931dd475 100644
@@ -475,6 +475,38 @@ const char *arch_vma_name(struct vm_area_struct *vma)
 	return is_gate_vma(vma) ? "[vectors]" : NULL;
 }
 
+/* If possible, provide a placement hint at a random offset from the
+ * stack for the signal page.
+ */
+static unsigned long sigpage_addr(const struct mm_struct *mm, unsigned int npages)
+{
+	unsigned long offset;
+	unsigned long first;
+	unsigned long last;
+	unsigned long addr;
+	unsigned int slots;
+
+	first = PAGE_ALIGN(mm->start_stack);
+
+	last = TASK_SIZE - (npages << PAGE_SHIFT);
+
+	/* No room after stack? */
+	if (first > last)
+		return 0;
+
+	/* Just enough room? */
+	if (first == last)
+		return first;
+
+	slots = ((last - first) >> PAGE_SHIFT) + 1;
+
+	offset = get_random_int() % slots;
+
+	addr = first + (offset << PAGE_SHIFT);
+
+	return addr;
+}
+
 static struct page *signal_page;
 extern struct page *get_signal_page(void);
 
@@ -488,6 +520,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma;
 	unsigned long addr;
+	unsigned long hint;
 	int ret = 0;
 
 	if (!signal_page)
@@ -496,7 +529,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 		return -ENOMEM;
 
 	down_write(&mm->mmap_sem);
-	addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
+	hint = sigpage_addr(mm, 1);
+	addr = get_unmapped_area(NULL, hint, PAGE_SIZE, 0, 0);
 	if (IS_ERR_VALUE(addr)) {
 		ret = addr;
 		goto up_fail;
Signature · 1 line
1.9.3
#3 lore raw

cover ARM: minor sigpage enhancements

In reply to Nathan Lynch
Quoted 7 lines · Nathan Lynch

Russell,

Would you consider taking these for 3.17? I've been carrying the sigpage placement randomization as part of the VDSO patch set but it seems worthwhile on its own. Using _install_special_mapping for the VDSO and similar VMAs was recently suggested by Andy Lutomirski.

Quoted 6 lines

Nathan Lynch (2):
ARM: use _install_special_mapping for sigpage
ARM: place sigpage at a random offset above stack

 arch/arm/kernel/process.c | 60 ++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 51 insertions(+), 9 deletions(-)

Cool! Thanks for this.

-Kees

Signature · 2 lines
Kees Cook
Chrome OS Security
#4 lore raw

cover ARM: minor sigpage enhancements

Quoted 12 lines · Kees Cook
Quoted 11 lines · Nathan Lynch

Russell,

Would you consider taking these for 3.17? I've been carrying the sigpage placement randomization as part of the VDSO patch set but it seems worthwhile on its own. Using _install_special_mapping for the VDSO and similar VMAs was recently suggested by Andy Lutomirski.

Nathan Lynch (2):
ARM: use _install_special_mapping for sigpage
ARM: place sigpage at a random offset above stack

Quoted 6 lines
Quoted 2 lines
 arch/arm/kernel/process.c | 60 ++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 51 insertions(+), 9 deletions(-)

Cool! Thanks for this.

Russell, okay to add these to your patch tracker?