Skip to content

Commit 24195ca

Browse files
author
Russell King
committed
Merge branch 'security-fixes' into fixes
2 parents 2449189 + a5463cd commit 24195ca

File tree

13 files changed

+253
-99
lines changed

13 files changed

+253
-99
lines changed

arch/arm/Kconfig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ config VECTORS_BASE
217217
default DRAM_BASE if REMAP_VECTORS_TO_RAM
218218
default 0x00000000
219219
help
220-
The base address of exception vectors.
220+
The base address of exception vectors. This must be two pages
221+
in size.
221222

222223
config ARM_PATCH_PHYS_VIRT
223224
bool "Patch physical to virtual translations at runtime" if EMBEDDED

arch/arm/include/asm/elf.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,8 @@ struct mm_struct;
130130
extern unsigned long arch_randomize_brk(struct mm_struct *mm);
131131
#define arch_randomize_brk arch_randomize_brk
132132

133+
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
134+
struct linux_binprm;
135+
int arch_setup_additional_pages(struct linux_binprm *, int);
136+
133137
#endif

arch/arm/include/asm/mmu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ typedef struct {
1010
int switch_pending;
1111
#endif
1212
unsigned int vmalloc_seq;
13+
unsigned long sigpage;
1314
} mm_context_t;
1415

1516
#ifdef CONFIG_CPU_HAS_ASID

arch/arm/include/asm/page.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,9 @@ extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
142142
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
143143
extern void copy_page(void *to, const void *from);
144144

145+
#ifdef CONFIG_KUSER_HELPERS
145146
#define __HAVE_ARCH_GATE_AREA 1
147+
#endif
146148

147149
#ifdef CONFIG_ARM_LPAE
148150
#include <asm/pgtable-3level-types.h>

arch/arm/kernel/entry-armv.S

Lines changed: 53 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,18 @@ ENDPROC(__switch_to)
742742
#endif
743743
.endm
744744

745+
.macro kuser_pad, sym, size
746+
.if (. - \sym) & 3
747+
.rept 4 - (. - \sym) & 3
748+
.byte 0
749+
.endr
750+
.endif
751+
.rept (\size - (. - \sym)) / 4
752+
.word 0xe7fddef1
753+
.endr
754+
.endm
755+
756+
#ifdef CONFIG_KUSER_HELPERS
745757
.align 5
746758
.globl __kuser_helper_start
747759
__kuser_helper_start:
@@ -832,18 +844,13 @@ kuser_cmpxchg64_fixup:
832844
#error "incoherent kernel configuration"
833845
#endif
834846

835-
/* pad to next slot */
836-
.rept (16 - (. - __kuser_cmpxchg64)/4)
837-
.word 0
838-
.endr
839-
840-
.align 5
847+
kuser_pad __kuser_cmpxchg64, 64
841848

842849
__kuser_memory_barrier: @ 0xffff0fa0
843850
smp_dmb arm
844851
usr_ret lr
845852

846-
.align 5
853+
kuser_pad __kuser_memory_barrier, 32
847854

848855
__kuser_cmpxchg: @ 0xffff0fc0
849856

@@ -916,13 +923,14 @@ kuser_cmpxchg32_fixup:
916923

917924
#endif
918925

919-
.align 5
926+
kuser_pad __kuser_cmpxchg, 32
920927

921928
__kuser_get_tls: @ 0xffff0fe0
922929
ldr r0, [pc, #(16 - 8)] @ read TLS, set in kuser_get_tls_init
923930
usr_ret lr
924931
mrc p15, 0, r0, c13, c0, 3 @ 0xffff0fe8 hardware TLS code
925-
.rep 4
932+
kuser_pad __kuser_get_tls, 16
933+
.rep 3
926934
.word 0 @ 0xffff0ff0 software TLS value, then
927935
.endr @ pad up to __kuser_helper_version
928936

@@ -932,14 +940,16 @@ __kuser_helper_version: @ 0xffff0ffc
932940
.globl __kuser_helper_end
933941
__kuser_helper_end:
934942

943+
#endif
944+
935945
THUMB( .thumb )
936946

937947
/*
938948
* Vector stubs.
939949
*
940-
* This code is copied to 0xffff0200 so we can use branches in the
941-
* vectors, rather than ldr's. Note that this code must not
942-
* exceed 0x300 bytes.
950+
* This code is copied to 0xffff1000 so we can use branches in the
951+
* vectors, rather than ldr's. Note that this code must not exceed
952+
* a page size.
943953
*
944954
* Common stub entry macro:
945955
* Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
@@ -986,8 +996,17 @@ ENDPROC(vector_\name)
986996
1:
987997
.endm
988998

989-
.globl __stubs_start
999+
.section .stubs, "ax", %progbits
9901000
__stubs_start:
1001+
@ This must be the first word
1002+
.word vector_swi
1003+
1004+
vector_rst:
1005+
ARM( swi SYS_ERROR0 )
1006+
THUMB( svc #0 )
1007+
THUMB( nop )
1008+
b vector_und
1009+
9911010
/*
9921011
* Interrupt dispatcher
9931012
*/
@@ -1081,6 +1100,16 @@ __stubs_start:
10811100

10821101
.align 5
10831102

1103+
/*=============================================================================
1104+
* Address exception handler
1105+
*-----------------------------------------------------------------------------
1106+
* These aren't too critical.
1107+
* (they're not supposed to happen, and won't happen in 32-bit data mode).
1108+
*/
1109+
1110+
vector_addrexcptn:
1111+
b vector_addrexcptn
1112+
10841113
/*=============================================================================
10851114
* Undefined FIQs
10861115
*-----------------------------------------------------------------------------
@@ -1094,45 +1123,19 @@ __stubs_start:
10941123
vector_fiq:
10951124
subs pc, lr, #4
10961125

1097-
/*=============================================================================
1098-
* Address exception handler
1099-
*-----------------------------------------------------------------------------
1100-
* These aren't too critical.
1101-
* (they're not supposed to happen, and won't happen in 32-bit data mode).
1102-
*/
1103-
1104-
vector_addrexcptn:
1105-
b vector_addrexcptn
1106-
1107-
/*
1108-
* We group all the following data together to optimise
1109-
* for CPUs with separate I & D caches.
1110-
*/
1111-
.align 5
1112-
1113-
.LCvswi:
1114-
.word vector_swi
1115-
1116-
.globl __stubs_end
1117-
__stubs_end:
1118-
1119-
.equ stubs_offset, __vectors_start + 0x200 - __stubs_start
1126+
.globl vector_fiq_offset
1127+
.equ vector_fiq_offset, vector_fiq
11201128

1121-
.globl __vectors_start
1129+
.section .vectors, "ax", %progbits
11221130
__vectors_start:
1123-
ARM( swi SYS_ERROR0 )
1124-
THUMB( svc #0 )
1125-
THUMB( nop )
1126-
W(b) vector_und + stubs_offset
1127-
W(ldr) pc, .LCvswi + stubs_offset
1128-
W(b) vector_pabt + stubs_offset
1129-
W(b) vector_dabt + stubs_offset
1130-
W(b) vector_addrexcptn + stubs_offset
1131-
W(b) vector_irq + stubs_offset
1132-
W(b) vector_fiq + stubs_offset
1133-
1134-
.globl __vectors_end
1135-
__vectors_end:
1131+
W(b) vector_rst
1132+
W(b) vector_und
1133+
W(ldr) pc, __vectors_start + 0x1000
1134+
W(b) vector_pabt
1135+
W(b) vector_dabt
1136+
W(b) vector_addrexcptn
1137+
W(b) vector_irq
1138+
W(b) vector_fiq
11361139

11371140
.data
11381141

arch/arm/kernel/fiq.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@
4747
#include <asm/irq.h>
4848
#include <asm/traps.h>
4949

50+
#define FIQ_OFFSET ({ \
51+
extern void *vector_fiq_offset; \
52+
(unsigned)&vector_fiq_offset; \
53+
})
54+
5055
static unsigned long no_fiq_insn;
5156

5257
/* Default reacquire function
@@ -80,13 +85,16 @@ int show_fiq_list(struct seq_file *p, int prec)
8085
void set_fiq_handler(void *start, unsigned int length)
8186
{
8287
#if defined(CONFIG_CPU_USE_DOMAINS)
83-
memcpy((void *)0xffff001c, start, length);
88+
void *base = (void *)0xffff0000;
8489
#else
85-
memcpy(vectors_page + 0x1c, start, length);
90+
void *base = vectors_page;
8691
#endif
87-
flush_icache_range(0xffff001c, 0xffff001c + length);
92+
unsigned offset = FIQ_OFFSET;
93+
94+
memcpy(base + offset, start, length);
95+
flush_icache_range(0xffff0000 + offset, 0xffff0000 + offset + length);
8896
if (!vectors_high())
89-
flush_icache_range(0x1c, 0x1c + length);
97+
flush_icache_range(offset, offset + length);
9098
}
9199

92100
int claim_fiq(struct fiq_handler *f)
@@ -144,6 +152,7 @@ EXPORT_SYMBOL(disable_fiq);
144152

145153
void __init init_FIQ(int start)
146154
{
147-
no_fiq_insn = *(unsigned long *)0xffff001c;
155+
unsigned offset = FIQ_OFFSET;
156+
no_fiq_insn = *(unsigned long *)(0xffff0000 + offset);
148157
fiq_start = start;
149158
}

arch/arm/kernel/process.c

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -429,10 +429,11 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
429429
}
430430

431431
#ifdef CONFIG_MMU
432+
#ifdef CONFIG_KUSER_HELPERS
432433
/*
433434
* The vectors page is always readable from user space for the
434-
* atomic helpers and the signal restart code. Insert it into the
435-
* gate_vma so that it is visible through ptrace and /proc/<pid>/mem.
435+
* atomic helpers. Insert it into the gate_vma so that it is visible
436+
* through ptrace and /proc/<pid>/mem.
436437
*/
437438
static struct vm_area_struct gate_vma = {
438439
.vm_start = 0xffff0000,
@@ -461,9 +462,47 @@ int in_gate_area_no_mm(unsigned long addr)
461462
{
462463
return in_gate_area(NULL, addr);
463464
}
465+
#define is_gate_vma(vma) ((vma) = &gate_vma)
466+
#else
467+
#define is_gate_vma(vma) 0
468+
#endif
464469

465470
const char *arch_vma_name(struct vm_area_struct *vma)
466471
{
467-
return (vma == &gate_vma) ? "[vectors]" : NULL;
472+
return is_gate_vma(vma) ? "[vectors]" :
473+
(vma->vm_mm && vma->vm_start == vma->vm_mm->context.sigpage) ?
474+
"[sigpage]" : NULL;
475+
}
476+
477+
extern struct page *get_signal_page(void);
478+
479+
int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
480+
{
481+
struct mm_struct *mm = current->mm;
482+
struct page *page;
483+
unsigned long addr;
484+
int ret;
485+
486+
page = get_signal_page();
487+
if (!page)
488+
return -ENOMEM;
489+
490+
down_write(&mm->mmap_sem);
491+
addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
492+
if (IS_ERR_VALUE(addr)) {
493+
ret = addr;
494+
goto up_fail;
495+
}
496+
497+
ret = install_special_mapping(mm, addr, PAGE_SIZE,
498+
VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
499+
&page);
500+
501+
if (ret == 0)
502+
mm->context.sigpage = addr;
503+
504+
up_fail:
505+
up_write(&mm->mmap_sem);
506+
return ret;
468507
}
469508
#endif

0 commit comments

Comments
 (0)