Skip to content

Commit

Permalink
Merge tag 'v4.9.34' into linux-4.9.x-unofficial_grsec
Browse files Browse the repository at this point in the history
This is the 4.9.34 stable release -- which tend to be rather unstable,
according to the various regression reports due to upstream's Stack
Clash "fix" ([1], [2], [3]).

In return I've essentially reverted commit 27f9070614aa ("mm: larger
stack guard gap, between vmas") and its follow-up commits. PaX (and
grsec) did handle this just fine since 2010 (see [4]) and even have a
sysctl to allow tweaking the gap size at runtime. But, at least, I took
the commit as a hint to extend PaX 'n grsec's coverage somewhat to other
arches like ARC, S390,... -- untested, though.

The newly introduced stack_guard_gap kernel command line parameter was
recoined to apply to the existing PaX mechanism and takes a byte value
instead of a number of pages, e.g. use 'stack_guard_gap=1M' to mirror
upstream's 1MiB gap. It's now still the 64KiB gap which is sufficient,
as the problem can't be solved in the kernel anyways. You still need to
compile your userland apps with -fstack-check to make unbounded / large
/ attacker-controlled alloca()s trap on the guard area instead of
jumping over it.

Signed-off-by: Mathias Krause <minipli@googlemail.com>

[1] rust-lang/rust#43052
[2] https://lwn.net/Articles/727206/
[3] https://lwn.net/Articles/727703/
[4] https://grsecurity.net/~spender/stack_gap_fix.txt

Conflicts:
	arch/arm/mm/mmap.c
	arch/frv/mm/elf-fdpic.c
	arch/mips/mm/mmap.c
	arch/powerpc/mm/slice.c
	arch/sh/mm/mmap.c
	arch/sparc/kernel/sys_sparc_64.c
	arch/sparc/mm/hugetlbpage.c
	arch/x86/kernel/sys_x86_64.c
	arch/x86/mm/hugetlbpage.c
	fs/hugetlbfs/inode.c
	fs/proc/task_mmu.c
	mm/mmap.c
  • Loading branch information
minipli committed Jul 14, 2017
2 parents 114ed8d + 493ecd5 commit 59c07b1
Show file tree
Hide file tree
Showing 73 changed files with 346 additions and 199 deletions.
10 changes: 10 additions & 0 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3971,6 +3971,16 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
spia_pedr=
spia_peddr=

stack_guard_gap=nn[KMG] [MM]
Override the default heap stack gap protection range.
The value defines how many bytes prior to (for stacks
growing down) resp. after (for stacks growing up) the
main stack are reserved for no other mapping. The
granularity is in bytes, rounded up to the page size
of the given architecture. The default value is 64 kB.
This value can also be changed at runtime through the
vm.heap_stack_gap sysctl.

stacktrace [FTRACE]
Enabled the stack tracer on boot up.

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
VERSION = 4
PATCHLEVEL = 9
SUBLEVEL = 33
SUBLEVEL = 34
EXTRAVERSION =
NAME = Roaring Lionus

Expand Down
4 changes: 2 additions & 2 deletions arch/arc/mm/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
addr = PAGE_ALIGN(addr);

vma = find_vma(mm, addr);
if (TASK_SIZE - len >= addr &&
(!vma || addr + len <= vma->vm_start))
if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len, 0))
return addr;
}

Expand All @@ -74,5 +73,6 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
info.high_limit = TASK_SIZE;
info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
info.threadstack_offset = 0;
return vm_unmapped_area(&info);
}
10 changes: 5 additions & 5 deletions arch/mips/boot/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -128,19 +128,19 @@ quiet_cmd_cpp_its_S = ITS $@
-DADDR_BITS=$(ADDR_BITS) \
-DADDR_CELLS=$(itb_addr_cells)

$(obj)/vmlinux.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE
$(obj)/vmlinux.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE
$(call if_changed_dep,cpp_its_S,none,vmlinux.bin)

$(obj)/vmlinux.gz.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE
$(obj)/vmlinux.gz.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE
$(call if_changed_dep,cpp_its_S,gzip,vmlinux.bin.gz)

$(obj)/vmlinux.bz2.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE
$(obj)/vmlinux.bz2.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE
$(call if_changed_dep,cpp_its_S,bzip2,vmlinux.bin.bz2)

$(obj)/vmlinux.lzma.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE
$(obj)/vmlinux.lzma.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE
$(call if_changed_dep,cpp_its_S,lzma,vmlinux.bin.lzma)

$(obj)/vmlinux.lzo.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE
$(obj)/vmlinux.lzo.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE
$(call if_changed_dep,cpp_its_S,lzo,vmlinux.bin.lzo)

quiet_cmd_itb-image = ITB $@
Expand Down
4 changes: 3 additions & 1 deletion arch/mips/kernel/branch.c
Original file line number Diff line number Diff line change
Expand Up @@ -804,8 +804,10 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
break;
}
/* Compact branch: BNEZC || JIALC */
if (insn.i_format.rs)
if (!insn.i_format.rs) {
/* JIALC: set $31/ra */
regs->regs[31] = epc + 4;
}
regs->cp0_epc += 8;
break;
#endif
Expand Down
7 changes: 3 additions & 4 deletions arch/parisc/kernel/sys_parisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
addr = PAGE_ALIGN(addr);

vma = find_vma(mm, addr);
if (task_size - len >= addr &&
(!vma || addr + len <= vma->vm_start))
if (task_size - len >= addr && check_heap_stack_gap(vma, addr, len, offset))
goto found_addr;
}

Expand Down Expand Up @@ -186,9 +185,9 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
addr = COLOR_ALIGN(addr, last_mmap, pgoff);
else
addr = PAGE_ALIGN(addr);

vma = find_vma(mm, addr);
if (TASK_SIZE - len >= addr &&
(!vma || addr + len <= vma->vm_start))
if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len, offset))
goto found_addr;
}

Expand Down
4 changes: 2 additions & 2 deletions arch/powerpc/mm/hugetlbpage-radix.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ radix__hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
if (addr) {
addr = ALIGN(addr, huge_page_size(h));
vma = find_vma(mm, addr);
if (TASK_SIZE - len >= addr &&
(!vma || addr + len <= vma->vm_start))
if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len, 0))
return addr;
}
/*
Expand All @@ -78,5 +77,6 @@ radix__hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
info.high_limit = current->mm->mmap_base;
info.align_mask = PAGE_MASK & ~huge_page_mask(h);
info.align_offset = 0;
info.threadstack_offset = 0;
return vm_unmapped_area(&info);
}
8 changes: 4 additions & 4 deletions arch/powerpc/mm/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,7 @@ radix__arch_get_unmapped_area(struct file *filp, unsigned long addr,
if (addr) {
addr = PAGE_ALIGN(addr);
vma = find_vma(mm, addr);
if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
(!vma || addr + len <= vma->vm_start))
if (TASK_SIZE - len >= addr && addr >= mmap_min_addr && check_heap_stack_gap(vma, addr, len, 0))
return addr;
}

Expand All @@ -115,6 +114,7 @@ radix__arch_get_unmapped_area(struct file *filp, unsigned long addr,
info.low_limit = mm->mmap_base;
info.high_limit = TASK_SIZE;
info.align_mask = 0;
info.threadstack_offset = 0;
return vm_unmapped_area(&info);
}

Expand All @@ -141,8 +141,7 @@ radix__arch_get_unmapped_area_topdown(struct file *filp,
if (addr) {
addr = PAGE_ALIGN(addr);
vma = find_vma(mm, addr);
if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
(!vma || addr + len <= vma->vm_start))
if (TASK_SIZE - len >= addr && addr >= mmap_min_addr && check_heap_stack_gap(vma, addr, len, 0))
return addr;
}

Expand All @@ -151,6 +150,7 @@ radix__arch_get_unmapped_area_topdown(struct file *filp,
info.low_limit = max(PAGE_SIZE, mmap_min_addr);
info.high_limit = mm->mmap_base;
info.align_mask = 0;
info.threadstack_offset = 0;
addr = vm_unmapped_area(&info);

/*
Expand Down
18 changes: 14 additions & 4 deletions arch/s390/mm/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,18 +87,22 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
struct vm_unmapped_area_info info;
unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);

if (len > TASK_SIZE - mmap_min_addr)
return -ENOMEM;

if (flags & MAP_FIXED)
return addr;

#ifdef CONFIG_PAX_RANDMMAP
if (!(mm->pax_flags & MF_PAX_RANDMMAP))
#endif

if (addr) {
addr = PAGE_ALIGN(addr);
vma = find_vma(mm, addr);
if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
(!vma || addr + len <= vma->vm_start))
if (TASK_SIZE - len >= addr && addr >= mmap_min_addr && check_heap_stack_gap(vma, addr, len, offset))
return addr;
}

Expand All @@ -111,6 +115,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
else
info.align_mask = 0;
info.align_offset = pgoff << PAGE_SHIFT;
info.threadstack_offset = offset;
return vm_unmapped_area(&info);
}

Expand All @@ -123,6 +128,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
struct mm_struct *mm = current->mm;
unsigned long addr = addr0;
struct vm_unmapped_area_info info;
unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);

/* requested length too big for entire address space */
if (len > TASK_SIZE - mmap_min_addr)
Expand All @@ -131,12 +137,15 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
if (flags & MAP_FIXED)
return addr;

#ifdef CONFIG_PAX_RANDMMAP
if (!(mm->pax_flags & MF_PAX_RANDMMAP))
#endif

/* requesting a specific address */
if (addr) {
addr = PAGE_ALIGN(addr);
vma = find_vma(mm, addr);
if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
(!vma || addr + len <= vma->vm_start))
if (TASK_SIZE - len >= addr && addr >= mmap_min_addr && check_heap_stack_gap(vma, addr, len, offset))
return addr;
}

Expand All @@ -149,6 +158,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
else
info.align_mask = 0;
info.align_offset = pgoff << PAGE_SHIFT;
info.threadstack_offset = offset;
addr = vm_unmapped_area(&info);

/*
Expand Down
2 changes: 2 additions & 0 deletions arch/sh/mm/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
info.high_limit = TASK_SIZE;
info.align_mask = do_colour_align ? (PAGE_MASK & shm_align_mask) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
info.threadstack_offset = offset;
return vm_unmapped_area(&info);
}

Expand Down Expand Up @@ -131,6 +132,7 @@ arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr0,
info.high_limit = mm->mmap_base;
info.align_mask = do_colour_align ? (PAGE_MASK & shm_align_mask) : 0;
info.align_offset = pgoff << PAGE_SHIFT;
info.threadstack_offset = offset;
addr = vm_unmapped_area(&info);

/*
Expand Down
3 changes: 1 addition & 2 deletions arch/tile/mm/hugetlbpage.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,7 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
if (addr) {
addr = ALIGN(addr, huge_page_size(h));
vma = find_vma(mm, addr);
if (TASK_SIZE - len >= addr &&
(!vma || addr + len <= vma->vm_start))
if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len, 0))
return addr;
}
if (current->mm->get_unmapped_area == arch_get_unmapped_area)
Expand Down
1 change: 1 addition & 0 deletions arch/x86/mm/numa_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,5 +100,6 @@ void __init initmem_init(void)
printk(KERN_DEBUG "High memory starts at vaddr %08lx\n",
(ulong) pfn_to_kaddr(highstart_pfn));

__vmalloc_start_set = true;
setup_bootmem_allocator();
}
2 changes: 1 addition & 1 deletion arch/xtensa/kernel/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
/* At this point: (!vmm || addr < vmm->vm_end). */
if (TASK_SIZE - len < addr)
return -ENOMEM;
if (!vmm || addr + len <= vmm->vm_start)
if (check_heap_stack_gap(vma, addr, len, 0))
return addr;
addr = vmm->vm_end;
if (flags & MAP_SHARED)
Expand Down
17 changes: 11 additions & 6 deletions drivers/char/tpm/tpm_ibmvtpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,8 @@ static int tpm_ibmvtpm_remove(struct vio_dev *vdev)
}

kfree(ibmvtpm);
/* For tpm_ibmvtpm_get_desired_dma */
dev_set_drvdata(&vdev->dev, NULL);

return 0;
}
Expand All @@ -309,13 +311,16 @@ static int tpm_ibmvtpm_remove(struct vio_dev *vdev)
static unsigned long tpm_ibmvtpm_get_desired_dma(struct vio_dev *vdev)
{
struct tpm_chip *chip = dev_get_drvdata(&vdev->dev);
struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev);
struct ibmvtpm_dev *ibmvtpm;

/* ibmvtpm initializes at probe time, so the data we are
* asking for may not be set yet. Estimate that 4K required
* for TCE-mapped buffer in addition to CRQ.
*/
if (!ibmvtpm)
/*
* ibmvtpm initializes at probe time, so the data we are
* asking for may not be set yet. Estimate that 4K required
* for TCE-mapped buffer in addition to CRQ.
*/
if (chip)
ibmvtpm = dev_get_drvdata(&chip->dev);
else
return CRQ_RES_BUF_SIZE + PAGE_SIZE;

return CRQ_RES_BUF_SIZE + ibmvtpm->rtce_size;
Expand Down
4 changes: 2 additions & 2 deletions drivers/cpufreq/cpufreq_conservative.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ static ssize_t store_down_threshold(struct gov_attr_set *attr_set,
int ret;
ret = sscanf(buf, "%u", &input);

/* cannot be lower than 11 otherwise freq will not fall */
if (ret != 1 || input < 11 || input > 100 ||
/* cannot be lower than 1 otherwise freq will not fall */
if (ret != 1 || input < 1 || input > 100 ||
input >= dbs_data->up_threshold)
return -EINVAL;

Expand Down
7 changes: 5 additions & 2 deletions drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
Original file line number Diff line number Diff line change
Expand Up @@ -1290,8 +1290,11 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev,
u32 tmp, wm_mask, lb_vblank_lead_lines = 0;

if (amdgpu_crtc->base.enabled && num_heads && mode) {
active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
(u32)mode->clock);
line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
(u32)mode->clock);
line_time = min(line_time, (u32)65535);

/* watermark for high clocks */
if (adev->pm.dpm_enabled) {
Expand Down
7 changes: 5 additions & 2 deletions drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
Original file line number Diff line number Diff line change
Expand Up @@ -1257,8 +1257,11 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev,
u32 tmp, wm_mask, lb_vblank_lead_lines = 0;

if (amdgpu_crtc->base.enabled && num_heads && mode) {
active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
(u32)mode->clock);
line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
(u32)mode->clock);
line_time = min(line_time, (u32)65535);

/* watermark for high clocks */
if (adev->pm.dpm_enabled) {
Expand Down
7 changes: 5 additions & 2 deletions drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
Original file line number Diff line number Diff line change
Expand Up @@ -1054,8 +1054,11 @@ static void dce_v6_0_program_watermarks(struct amdgpu_device *adev,
fixed20_12 a, b, c;

if (amdgpu_crtc->base.enabled && num_heads && mode) {
active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
(u32)mode->clock);
line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
(u32)mode->clock);
line_time = min(line_time, (u32)65535);
priority_a_cnt = 0;
priority_b_cnt = 0;

Expand Down
7 changes: 5 additions & 2 deletions drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
Original file line number Diff line number Diff line change
Expand Up @@ -1211,8 +1211,11 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev,
u32 tmp, wm_mask, lb_vblank_lead_lines = 0;

if (amdgpu_crtc->base.enabled && num_heads && mode) {
active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
(u32)mode->clock);
line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
(u32)mode->clock);
line_time = min(line_time, (u32)65535);

/* watermark for high clocks */
if (adev->pm.dpm_enabled) {
Expand Down
8 changes: 2 additions & 6 deletions drivers/gpu/drm/i915/i915_pvinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@
#define VGT_VERSION_MAJOR 1
#define VGT_VERSION_MINOR 0

#define INTEL_VGT_IF_VERSION_ENCODE(major, minor) ((major) << 16 | (minor))
#define INTEL_VGT_IF_VERSION \
INTEL_VGT_IF_VERSION_ENCODE(VGT_VERSION_MAJOR, VGT_VERSION_MINOR)

/*
* notifications from guest to vgpu device model
*/
Expand All @@ -55,8 +51,8 @@ enum vgt_g2v_type {

struct vgt_if {
u64 magic; /* VGT_MAGIC */
uint16_t version_major;
uint16_t version_minor;
u16 version_major;
u16 version_minor;
u32 vgt_id; /* ID of vGT instance */
u32 rsv1[12]; /* pad to offset 0x40 */
/*
Expand Down
Loading

0 comments on commit 59c07b1

Please sign in to comment.