Skip to content

Commit 1335d9a

Browse files
committed
Merge branch 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull core fixes from Ingo Molnar: "This fixes a particularly thorny munmap() bug with MPX, plus fixes a host build environment assumption in objtool" * 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: objtool: Allow AR to be overridden with HOSTAR x86/mpx, mm/core: Fix recursive munmap() corruption
2 parents 4c4a5c9 + 8ea58f1 commit 1335d9a

File tree

9 files changed

+27
-26
lines changed

9 files changed

+27
-26
lines changed

arch/powerpc/include/asm/mmu_context.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,6 @@ static inline void enter_lazy_tlb(struct mm_struct *mm,
232232
extern void arch_exit_mmap(struct mm_struct *mm);
233233

234234
static inline void arch_unmap(struct mm_struct *mm,
235-
struct vm_area_struct *vma,
236235
unsigned long start, unsigned long end)
237236
{
238237
if (start <= mm->context.vdso_base && mm->context.vdso_base < end)

arch/um/include/asm/mmu_context.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ static inline int arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
2222
}
2323
extern void arch_exit_mmap(struct mm_struct *mm);
2424
static inline void arch_unmap(struct mm_struct *mm,
25-
struct vm_area_struct *vma,
2625
unsigned long start, unsigned long end)
2726
{
2827
}

arch/unicore32/include/asm/mmu_context.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ static inline int arch_dup_mmap(struct mm_struct *oldmm,
8888
}
8989

9090
static inline void arch_unmap(struct mm_struct *mm,
91-
struct vm_area_struct *vma,
9291
unsigned long start, unsigned long end)
9392
{
9493
}

arch/x86/include/asm/mmu_context.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,8 @@ static inline void arch_bprm_mm_init(struct mm_struct *mm,
278278
mpx_mm_init(mm);
279279
}
280280

281-
static inline void arch_unmap(struct mm_struct *mm, struct vm_area_struct *vma,
282-
unsigned long start, unsigned long end)
281+
static inline void arch_unmap(struct mm_struct *mm, unsigned long start,
282+
unsigned long end)
283283
{
284284
/*
285285
* mpx_notify_unmap() goes and reads a rarely-hot
@@ -299,7 +299,7 @@ static inline void arch_unmap(struct mm_struct *mm, struct vm_area_struct *vma,
299299
* consistently wrong.
300300
*/
301301
if (unlikely(cpu_feature_enabled(X86_FEATURE_MPX)))
302-
mpx_notify_unmap(mm, vma, start, end);
302+
mpx_notify_unmap(mm, start, end);
303303
}
304304

305305
/*

arch/x86/include/asm/mpx.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,15 @@ struct mpx_fault_info {
6464
};
6565

6666
#ifdef CONFIG_X86_INTEL_MPX
67-
int mpx_fault_info(struct mpx_fault_info *info, struct pt_regs *regs);
68-
int mpx_handle_bd_fault(void);
67+
68+
extern int mpx_fault_info(struct mpx_fault_info *info, struct pt_regs *regs);
69+
extern int mpx_handle_bd_fault(void);
70+
6971
static inline int kernel_managing_mpx_tables(struct mm_struct *mm)
7072
{
7173
return (mm->context.bd_addr != MPX_INVALID_BOUNDS_DIR);
7274
}
75+
7376
static inline void mpx_mm_init(struct mm_struct *mm)
7477
{
7578
/*
@@ -78,11 +81,10 @@ static inline void mpx_mm_init(struct mm_struct *mm)
7881
*/
7982
mm->context.bd_addr = MPX_INVALID_BOUNDS_DIR;
8083
}
81-
void mpx_notify_unmap(struct mm_struct *mm, struct vm_area_struct *vma,
82-
unsigned long start, unsigned long end);
8384

84-
unsigned long mpx_unmapped_area_check(unsigned long addr, unsigned long len,
85-
unsigned long flags);
85+
extern void mpx_notify_unmap(struct mm_struct *mm, unsigned long start, unsigned long end);
86+
extern unsigned long mpx_unmapped_area_check(unsigned long addr, unsigned long len, unsigned long flags);
87+
8688
#else
8789
static inline int mpx_fault_info(struct mpx_fault_info *info, struct pt_regs *regs)
8890
{
@@ -100,7 +102,6 @@ static inline void mpx_mm_init(struct mm_struct *mm)
100102
{
101103
}
102104
static inline void mpx_notify_unmap(struct mm_struct *mm,
103-
struct vm_area_struct *vma,
104105
unsigned long start, unsigned long end)
105106
{
106107
}

arch/x86/mm/mpx.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -881,9 +881,10 @@ static int mpx_unmap_tables(struct mm_struct *mm,
881881
* the virtual address region start...end have already been split if
882882
* necessary, and the 'vma' is the first vma in this range (start -> end).
883883
*/
884-
void mpx_notify_unmap(struct mm_struct *mm, struct vm_area_struct *vma,
885-
unsigned long start, unsigned long end)
884+
void mpx_notify_unmap(struct mm_struct *mm, unsigned long start,
885+
unsigned long end)
886886
{
887+
struct vm_area_struct *vma;
887888
int ret;
888889

889890
/*
@@ -902,11 +903,12 @@ void mpx_notify_unmap(struct mm_struct *mm, struct vm_area_struct *vma,
902903
* which should not occur normally. Being strict about it here
903904
* helps ensure that we do not have an exploitable stack overflow.
904905
*/
905-
do {
906+
vma = find_vma(mm, start);
907+
while (vma && vma->vm_start < end) {
906908
if (vma->vm_flags & VM_MPX)
907909
return;
908910
vma = vma->vm_next;
909-
} while (vma && vma->vm_start < end);
911+
}
910912

911913
ret = mpx_unmap_tables(mm, start, end);
912914
if (ret)

include/asm-generic/mm_hooks.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ static inline void arch_exit_mmap(struct mm_struct *mm)
1818
}
1919

2020
static inline void arch_unmap(struct mm_struct *mm,
21-
struct vm_area_struct *vma,
2221
unsigned long start, unsigned long end)
2322
{
2423
}

mm/mmap.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2735,9 +2735,17 @@ int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len,
27352735
return -EINVAL;
27362736

27372737
len = PAGE_ALIGN(len);
2738+
end = start + len;
27382739
if (len == 0)
27392740
return -EINVAL;
27402741

2742+
/*
2743+
* arch_unmap() might do unmaps itself. It must be called
2744+
* and finish any rbtree manipulation before this code
2745+
* runs and also starts to manipulate the rbtree.
2746+
*/
2747+
arch_unmap(mm, start, end);
2748+
27412749
/* Find the first overlapping VMA */
27422750
vma = find_vma(mm, start);
27432751
if (!vma)
@@ -2746,7 +2754,6 @@ int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len,
27462754
/* we have start < vma->vm_end */
27472755

27482756
/* if it doesn't overlap, we have nothing.. */
2749-
end = start + len;
27502757
if (vma->vm_start >= end)
27512758
return 0;
27522759

@@ -2816,12 +2823,6 @@ int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len,
28162823
/* Detach vmas from rbtree */
28172824
detach_vmas_to_be_unmapped(mm, vma, prev, end);
28182825

2819-
/*
2820-
* mpx unmap needs to be called with mmap_sem held for write.
2821-
* It is safe to call it before unmap_region().
2822-
*/
2823-
arch_unmap(mm, vma, start, end);
2824-
28252826
if (downgrade)
28262827
downgrade_write(&mm->mmap_sem);
28272828

tools/objtool/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ ARCH := x86
77
endif
88

99
# always use the host compiler
10+
HOSTAR ?= ar
1011
HOSTCC ?= gcc
1112
HOSTLD ?= ld
13+
AR = $(HOSTAR)
1214
CC = $(HOSTCC)
1315
LD = $(HOSTLD)
14-
AR = ar
1516

1617
ifeq ($(srctree),)
1718
srctree := $(patsubst %/,%,$(dir $(CURDIR)))

0 commit comments

Comments
 (0)