summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2014-02-20 16:50:42 -0500
committerAnthony G. Basile <blueness@gentoo.org>2014-02-20 16:50:42 -0500
commit6f7a2db6f04b0d6197a234c19145d08d2946cc6c (patch)
tree186ee628095053c21dc43991a0cc534ad138e1ad
parentGrsec/PaX: 3.0-{3.2.55,3.13.3}-201402152204 (diff)
downloadhardened-patchset-6f7a2db6f04b0d6197a234c19145d08d2946cc6c.tar.gz
hardened-patchset-6f7a2db6f04b0d6197a234c19145d08d2946cc6c.tar.bz2
hardened-patchset-6f7a2db6f04b0d6197a234c19145d08d2946cc6c.zip
Grsec/PaX: 3.0-{3.2.55,3.13.3}-20140219225220140219
-rw-r--r--3.13.3/0000_README2
-rw-r--r--3.13.3/4420_grsecurity-3.0-3.13.3-201402192252.patch (renamed from 3.13.3/4420_grsecurity-3.0-3.13.3-201402152204.patch)596
-rw-r--r--3.2.55/0000_README2
-rw-r--r--3.2.55/4420_grsecurity-3.0-3.2.55-201402192249.patch (renamed from 3.2.55/4420_grsecurity-3.0-3.2.55-201402152203.patch)17
4 files changed, 586 insertions, 31 deletions
diff --git a/3.13.3/0000_README b/3.13.3/0000_README
index f4a0bac..398b4fa 100644
--- a/3.13.3/0000_README
+++ b/3.13.3/0000_README
@@ -2,7 +2,7 @@ README
-----------------------------------------------------------------------------
Individual Patch Descriptions:
-----------------------------------------------------------------------------
-Patch: 4420_grsecurity-3.0-3.13.3-201402152204.patch
+Patch: 4420_grsecurity-3.0-3.13.3-201402192252.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/3.13.3/4420_grsecurity-3.0-3.13.3-201402152204.patch b/3.13.3/4420_grsecurity-3.0-3.13.3-201402192252.patch
index 2fcc457..26f9252 100644
--- a/3.13.3/4420_grsecurity-3.0-3.13.3-201402152204.patch
+++ b/3.13.3/4420_grsecurity-3.0-3.13.3-201402192252.patch
@@ -1572,7 +1572,7 @@ index 75fe66b..ba3dee4 100644
#endif
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
-index ee753f1..c9c30a5 100644
+index ee753f1..2c2afeb 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -116,7 +116,7 @@ struct cpu_cache_fns {
@@ -1584,6 +1584,14 @@ index ee753f1..c9c30a5 100644
/*
* Select the calling method
+@@ -212,6 +212,7 @@ extern void copy_to_user_page(struct vm_area_struct *, struct page *,
+ static inline void __flush_icache_all(void)
+ {
+ __flush_icache_preferred();
++ dsb();
+ }
+
+ /*
diff --git a/arch/arm/include/asm/checksum.h b/arch/arm/include/asm/checksum.h
index 6dcc164..b14d917 100644
--- a/arch/arm/include/asm/checksum.h
@@ -1982,7 +1990,7 @@ index 626989f..9d67a33 100644
/*
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
-index 4f95039..b2dd513 100644
+index 4f95039..04d626a 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -82,6 +82,7 @@
@@ -2001,6 +2009,29 @@ index 4f95039..b2dd513 100644
#define L_PTE_XN_HIGH (1 << (54 - 32))
#define L_PTE_DIRTY_HIGH (1 << (55 - 32))
+@@ -120,13 +122,16 @@
+ /*
+ * 2nd stage PTE definitions for LPAE.
+ */
+-#define L_PTE_S2_MT_UNCACHED (_AT(pteval_t, 0x5) << 2) /* MemAttr[3:0] */
+-#define L_PTE_S2_MT_WRITETHROUGH (_AT(pteval_t, 0xa) << 2) /* MemAttr[3:0] */
+-#define L_PTE_S2_MT_WRITEBACK (_AT(pteval_t, 0xf) << 2) /* MemAttr[3:0] */
+-#define L_PTE_S2_RDONLY (_AT(pteval_t, 1) << 6) /* HAP[1] */
+-#define L_PTE_S2_RDWR (_AT(pteval_t, 3) << 6) /* HAP[2:1] */
++#define L_PTE_S2_MT_UNCACHED (_AT(pteval_t, 0x0) << 2) /* strongly ordered */
++#define L_PTE_S2_MT_WRITETHROUGH (_AT(pteval_t, 0xa) << 2) /* normal inner write-through */
++#define L_PTE_S2_MT_WRITEBACK (_AT(pteval_t, 0xf) << 2) /* normal inner write-back */
++#define L_PTE_S2_MT_DEV_SHARED (_AT(pteval_t, 0x1) << 2) /* device */
++#define L_PTE_S2_MT_MASK (_AT(pteval_t, 0xf) << 2)
+
+-#define L_PMD_S2_RDWR (_AT(pmdval_t, 3) << 6) /* HAP[2:1] */
++#define L_PTE_S2_RDONLY (_AT(pteval_t, 1) << 6) /* HAP[1] */
++#define L_PTE_S2_RDWR (_AT(pteval_t, 3) << 6) /* HAP[2:1] */
++
++#define L_PMD_S2_RDWR (_AT(pmdval_t, 3) << 6) /* HAP[2:1] */
+
+ /*
+ * Hyp-mode PL2 PTE definitions for LPAE.
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 1571d12..b8a9b43 100644
--- a/arch/arm/include/asm/pgtable.h
@@ -2133,6 +2164,32 @@ index 22a3b9b..7f214ee 100644
/*
* set platform specific SMP operations
+diff --git a/arch/arm/include/asm/spinlock.h b/arch/arm/include/asm/spinlock.h
+index ef3c607..ac4bfae 100644
+--- a/arch/arm/include/asm/spinlock.h
++++ b/arch/arm/include/asm/spinlock.h
+@@ -37,18 +37,9 @@
+
+ static inline void dsb_sev(void)
+ {
+-#if __LINUX_ARM_ARCH__ >= 7
+- __asm__ __volatile__ (
+- "dsb ishst\n"
+- SEV
+- );
+-#else
+- __asm__ __volatile__ (
+- "mcr p15, 0, %0, c7, c10, 4\n"
+- SEV
+- : : "r" (0)
+- );
+-#endif
++
++ dsb(ishst);
++ __asm__(SEV);
+ }
+
+ /*
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 71a06b2..8bb9ae1 100644
--- a/arch/arm/include/asm/thread_info.h
@@ -4179,6 +4236,18 @@ index f123d6e..04bf569 100644
return __arm_ioremap_caller(phys_addr, size, mtype,
__builtin_return_address(0));
+diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
+index d5a982d..7ea641b7 100644
+--- a/arch/arm/mm/mm.h
++++ b/arch/arm/mm/mm.h
+@@ -38,6 +38,7 @@ static inline pmd_t *pmd_off_k(unsigned long virt)
+
+ struct mem_type {
+ pteval_t prot_pte;
++ pteval_t prot_pte_s2;
+ pmdval_t prot_l1;
+ pmdval_t prot_sect;
+ unsigned int domain;
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index 5e85ed3..b10a7ed 100644
--- a/arch/arm/mm/mmap.c
@@ -4291,7 +4360,7 @@ index 5e85ed3..b10a7ed 100644
}
}
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
-index 580ef2d..2da06ca 100644
+index 580ef2d..4ed7f76 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -38,6 +38,22 @@
@@ -4317,12 +4386,13 @@ index 580ef2d..2da06ca 100644
/*
* empty_zero_page is a special page that is used for
* zero-initialized data and COW.
-@@ -230,10 +246,18 @@ __setup("noalign", noalign_setup);
+@@ -230,13 +246,25 @@ __setup("noalign", noalign_setup);
#endif /* ifdef CONFIG_CPU_CP15 / else */
-#define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_XN
+#define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY
++#define PROT_PTE_S2_DEVICE PROT_PTE_DEVICE|L_PTE_XN
#define PROT_SECT_DEVICE PMD_TYPE_SECT|PMD_SECT_AP_WRITE
-static struct mem_type mem_types[] = {
@@ -4338,7 +4408,13 @@ index 580ef2d..2da06ca 100644
[MT_DEVICE] = { /* Strongly ordered / ARMv6 shared device */
.prot_pte = PROT_PTE_DEVICE | L_PTE_MT_DEV_SHARED |
L_PTE_SHARED,
-@@ -262,16 +286,16 @@ static struct mem_type mem_types[] = {
++ .prot_pte_s2 = s2_policy(PROT_PTE_S2_DEVICE) |
++ s2_policy(L_PTE_S2_MT_DEV_SHARED) |
++ L_PTE_SHARED,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PROT_SECT_DEVICE | PMD_SECT_S,
+ .domain = DOMAIN_IO,
+@@ -262,16 +290,16 @@ static struct mem_type mem_types[] = {
[MT_UNCACHED] = {
.prot_pte = PROT_PTE_DEVICE,
.prot_l1 = PMD_TYPE_TABLE,
@@ -4358,7 +4434,7 @@ index 580ef2d..2da06ca 100644
.domain = DOMAIN_KERNEL,
},
#endif
-@@ -279,36 +303,54 @@ static struct mem_type mem_types[] = {
+@@ -279,36 +307,54 @@ static struct mem_type mem_types[] = {
.prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
L_PTE_RDONLY,
.prot_l1 = PMD_TYPE_TABLE,
@@ -4421,7 +4497,7 @@ index 580ef2d..2da06ca 100644
.domain = DOMAIN_KERNEL,
},
[MT_MEMORY_ITCM] = {
-@@ -318,10 +360,10 @@ static struct mem_type mem_types[] = {
+@@ -318,10 +364,10 @@ static struct mem_type mem_types[] = {
},
[MT_MEMORY_SO] = {
.prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
@@ -4434,7 +4510,7 @@ index 580ef2d..2da06ca 100644
.domain = DOMAIN_KERNEL,
},
[MT_MEMORY_DMA_READY] = {
-@@ -407,9 +449,35 @@ static void __init build_mem_type_table(void)
+@@ -407,9 +453,35 @@ static void __init build_mem_type_table(void)
* to prevent speculative instruction fetches.
*/
mem_types[MT_DEVICE].prot_sect |= PMD_SECT_XN;
@@ -4470,7 +4546,17 @@ index 580ef2d..2da06ca 100644
}
if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) {
/*
-@@ -470,6 +538,9 @@ static void __init build_mem_type_table(void)
+@@ -458,7 +530,8 @@ static void __init build_mem_type_table(void)
+ cp = &cache_policies[cachepolicy];
+ vecs_pgprot = kern_pgprot = user_pgprot = cp->pte;
+ s2_pgprot = cp->pte_s2;
+- hyp_device_pgprot = s2_device_pgprot = mem_types[MT_DEVICE].prot_pte;
++ hyp_device_pgprot = mem_types[MT_DEVICE].prot_pte;
++ s2_device_pgprot = mem_types[MT_DEVICE].prot_pte_s2;
+
+ /*
+ * ARMv6 and above have extended page tables.
+@@ -470,6 +543,9 @@ static void __init build_mem_type_table(void)
* from SVC mode and no access from userspace.
*/
mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
@@ -4480,7 +4566,7 @@ index 580ef2d..2da06ca 100644
mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
#endif
-@@ -487,11 +558,17 @@ static void __init build_mem_type_table(void)
+@@ -487,11 +563,17 @@ static void __init build_mem_type_table(void)
mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED;
mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S;
mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED;
@@ -4502,7 +4588,7 @@ index 580ef2d..2da06ca 100644
}
}
-@@ -502,15 +579,20 @@ static void __init build_mem_type_table(void)
+@@ -502,15 +584,20 @@ static void __init build_mem_type_table(void)
if (cpu_arch >= CPU_ARCH_ARMv6) {
if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) {
/* Non-cacheable Normal is XCB = 001 */
@@ -4526,7 +4612,7 @@ index 580ef2d..2da06ca 100644
}
#ifdef CONFIG_ARM_LPAE
-@@ -526,6 +608,8 @@ static void __init build_mem_type_table(void)
+@@ -526,6 +613,8 @@ static void __init build_mem_type_table(void)
vecs_pgprot |= PTE_EXT_AF;
#endif
@@ -4535,7 +4621,7 @@ index 580ef2d..2da06ca 100644
for (i = 0; i < 16; i++) {
pteval_t v = pgprot_val(protection_map[i]);
protection_map[i] = __pgprot(v | user_pgprot);
-@@ -543,10 +627,15 @@ static void __init build_mem_type_table(void)
+@@ -543,10 +632,15 @@ static void __init build_mem_type_table(void)
mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
@@ -4554,7 +4640,7 @@ index 580ef2d..2da06ca 100644
mem_types[MT_ROM].prot_sect |= cp->pmd;
switch (cp->pmd) {
-@@ -1188,18 +1277,15 @@ void __init arm_mm_memblock_reserve(void)
+@@ -1188,18 +1282,15 @@ void __init arm_mm_memblock_reserve(void)
* called function. This means you can't use any function or debugging
* method which may touch any device, otherwise the kernel _will_ crash.
*/
@@ -4577,7 +4663,7 @@ index 580ef2d..2da06ca 100644
for (addr = VMALLOC_START; addr; addr += PMD_SIZE)
pmd_clear(pmd_off_k(addr));
-@@ -1239,7 +1325,7 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
+@@ -1239,7 +1330,7 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
* location (0xffff0000). If we aren't using high-vectors, also
* create a mapping at the low-vectors virtual address.
*/
@@ -4586,7 +4672,7 @@ index 580ef2d..2da06ca 100644
map.virtual = 0xffff0000;
map.length = PAGE_SIZE;
#ifdef CONFIG_KUSER_HELPERS
-@@ -1311,8 +1397,39 @@ static void __init map_lowmem(void)
+@@ -1311,8 +1402,39 @@ static void __init map_lowmem(void)
map.pfn = __phys_to_pfn(start);
map.virtual = __phys_to_virt(start);
map.length = end - start;
@@ -4627,6 +4713,47 @@ index 580ef2d..2da06ca 100644
create_mapping(&map);
}
}
+diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
+index 45dc29f..32b3558 100644
+--- a/arch/arm/mm/proc-v6.S
++++ b/arch/arm/mm/proc-v6.S
+@@ -208,7 +208,6 @@ __v6_setup:
+ mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache
+- mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ #ifdef CONFIG_MMU
+ mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs
+ mcr p15, 0, r0, c2, c0, 2 @ TTB control register
+@@ -218,6 +217,8 @@ __v6_setup:
+ ALT_UP(orr r8, r8, #TTB_FLAGS_UP)
+ mcr p15, 0, r8, c2, c0, 1 @ load TTB1
+ #endif /* CONFIG_MMU */
++ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer and
++ @ complete invalidations
+ adr r5, v6_crval
+ ldmia r5, {r5, r6}
+ ARM_BE8(orr r6, r6, #1 << 25) @ big-endian page tables
+diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
+index bd17819..74f6033 100644
+--- a/arch/arm/mm/proc-v7.S
++++ b/arch/arm/mm/proc-v7.S
+@@ -351,7 +351,6 @@ __v7_setup:
+
+ 4: mov r10, #0
+ mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate
+- dsb
+ #ifdef CONFIG_MMU
+ mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs
+ v7_ttb_setup r10, r4, r8, r5 @ TTBCR, TTBRx setup
+@@ -360,6 +359,7 @@ __v7_setup:
+ mcr p15, 0, r5, c10, c2, 0 @ write PRRR
+ mcr p15, 0, r6, c10, c2, 1 @ write NMRR
+ #endif
++ dsb @ Complete invalidations
+ #ifndef CONFIG_ARM_THUMBEE
+ mrc p15, 0, r0, c0, c1, 0 @ read ID_PFR0 for ThumbEE
+ and r0, r0, #(0xf << 12) @ ThumbEE enabled field
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index a5bc92d..0bb4730 100644
--- a/arch/arm/plat-omap/sram.c
@@ -11662,7 +11789,7 @@ index ad8f795..2c7eec6 100644
/*
* Memory returned by kmalloc() may be used for DMA, so we must make
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
-index 0952ecd..725c779 100644
+index 0952ecd..9cf578c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -249,7 +249,7 @@ config X86_HT
@@ -11678,7 +11805,7 @@ index 0952ecd..725c779 100644
menuconfig HYPERVISOR_GUEST
bool "Linux guest support"
-+ depends on !GRKERNSEC_CONFIG_AUTO || GRKERNSEC_CONFIG_VIRT_GUEST
++ depends on !GRKERNSEC_CONFIG_AUTO || GRKERNSEC_CONFIG_VIRT_GUEST || (GRKERNSEC_CONFIG_VIRT_HOST && GRKERNSEC_CONFIG_VIRT_XEN)
---help---
Say Y here to enable options for running Linux under various hyper-
visors. This option enables basic hypervisor detection and platform
@@ -39402,7 +39529,7 @@ index 7d5a152..d7186da 100644
#if defined(__i386__)
pgprot = pgprot_val(vma->vm_page_prot);
diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c
-index 2f4c434..dd12cd2 100644
+index 2f4c4343..dd12cd2 100644
--- a/drivers/gpu/drm/drm_ioc32.c
+++ b/drivers/gpu/drm/drm_ioc32.c
@@ -457,7 +457,7 @@ static int compat_drm_infobufs(struct file *file, unsigned int cmd,
@@ -44958,6 +45085,19 @@ index 7b5424f..ed1d6ac 100644
err = -EFAULT;
goto cmd_rel_host;
}
+diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
+index 357bbc5..3e049c1 100644
+--- a/drivers/mmc/card/queue.c
++++ b/drivers/mmc/card/queue.c
+@@ -197,7 +197,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
+ struct mmc_queue_req *mqrq_prev = &mq->mqrq[1];
+
+ if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask)
+- limit = dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT;
++ limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT;
+
+ mq->card = card;
+ mq->queue = blk_init_queue(mmc_request_fn, lock);
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index e5b5eeb..7bf2212 100644
--- a/drivers/mmc/core/mmc_ops.c
@@ -48792,7 +48932,7 @@ index fe0bcb1..c9255be 100644
/* check if the device is still usable */
if (unlikely(cmd->device->sdev_state == SDEV_DEL)) {
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
-index 7bd7f0d..44147bf 100644
+index 7bd7f0d..93159d8 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1474,7 +1474,7 @@ static void scsi_kill_request(struct request *req, struct request_queue *q)
@@ -48816,6 +48956,15 @@ index 7bd7f0d..44147bf 100644
disposition = scsi_decide_disposition(cmd);
if (disposition != SUCCESS &&
+@@ -1684,7 +1684,7 @@ u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost)
+
+ host_dev = scsi_get_device(shost);
+ if (host_dev && host_dev->dma_mask)
+- bounce_limit = dma_max_pfn(host_dev) << PAGE_SHIFT;
++ bounce_limit = (u64)dma_max_pfn(host_dev) << PAGE_SHIFT;
+
+ return bounce_limit;
+ }
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 8ff62c2..693b6f7 100644
--- a/drivers/scsi/scsi_sysfs.c
@@ -56742,7 +56891,7 @@ index f918a99..bb300d5 100644
GLOBAL_EXTERN atomic_t smBufAllocCount;
GLOBAL_EXTERN atomic_t midCount;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
-index 5a5a872..92c3210 100644
+index 5a5a872..63e4c62 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1900,10 +1900,14 @@ static int cifs_writepages(struct address_space *mapping,
@@ -56763,6 +56912,63 @@ index 5a5a872..92c3210 100644
scanned = true;
}
retry:
+@@ -2381,7 +2385,7 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
+ unsigned long nr_segs, loff_t *poffset)
+ {
+ unsigned long nr_pages, i;
+- size_t copied, len, cur_len;
++ size_t bytes, copied, len, cur_len;
+ ssize_t total_written = 0;
+ loff_t offset;
+ struct iov_iter it;
+@@ -2436,14 +2440,45 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
+
+ save_len = cur_len;
+ for (i = 0; i < nr_pages; i++) {
+- copied = min_t(const size_t, cur_len, PAGE_SIZE);
++ bytes = min_t(const size_t, cur_len, PAGE_SIZE);
+ copied = iov_iter_copy_from_user(wdata->pages[i], &it,
+- 0, copied);
++ 0, bytes);
+ cur_len -= copied;
+ iov_iter_advance(&it, copied);
++ /*
++ * If we didn't copy as much as we expected, then that
++ * may mean we trod into an unmapped area. Stop copying
++ * at that point. On the next pass through the big
++ * loop, we'll likely end up getting a zero-length
++ * write and bailing out of it.
++ */
++ if (copied < bytes)
++ break;
+ }
+ cur_len = save_len - cur_len;
+
++ /*
++ * If we have no data to send, then that probably means that
++ * the copy above failed altogether. That's most likely because
++ * the address in the iovec was bogus. Set the rc to -EFAULT,
++ * free anything we allocated and bail out.
++ */
++ if (!cur_len) {
++ for (i = 0; i < nr_pages; i++)
++ put_page(wdata->pages[i]);
++ kfree(wdata);
++ rc = -EFAULT;
++ break;
++ }
++
++ /*
++ * i + 1 now represents the number of pages we actually used in
++ * the copy phase above. Bring nr_pages down to that, and free
++ * any pages that we didn't use.
++ */
++ for ( ; nr_pages > i + 1; nr_pages--)
++ put_page(wdata->pages[nr_pages - 1]);
++
+ wdata->sync_mode = WB_SYNC_ALL;
+ wdata->nr_pages = nr_pages;
+ wdata->offset = (__u64)offset;
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 2f9f379..43f8025 100644
--- a/fs/cifs/misc.c
@@ -58330,10 +58536,19 @@ index 6ea7b14..8fa16d9 100644
if (free_clusters >= (nclusters + dirty_clusters +
resv_clusters))
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
-index ece5556..e39d3a8 100644
+index ece5556..242c50a 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
-@@ -1267,19 +1267,19 @@ struct ext4_sb_info {
+@@ -771,6 +771,8 @@ do { \
+ if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime)) \
+ (einode)->xtime.tv_sec = \
+ (signed)le32_to_cpu((raw_inode)->xtime); \
++ else \
++ (einode)->xtime.tv_sec = 0; \
+ if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime ## _extra)) \
+ ext4_decode_extra_time(&(einode)->xtime, \
+ raw_inode->xtime ## _extra); \
+@@ -1267,19 +1269,19 @@ struct ext4_sb_info {
unsigned long s_mb_last_start;
/* stats for buddy allocator */
@@ -58363,6 +58578,39 @@ index ece5556..e39d3a8 100644
atomic_t s_lock_busy;
/* locality groups */
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index 3384dc4..02dd709 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -3906,6 +3906,7 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
+ } else
+ err = ret;
+ map->m_flags |= EXT4_MAP_MAPPED;
++ map->m_pblk = newblock;
+ if (allocated > map->m_len)
+ allocated = map->m_len;
+ map->m_len = allocated;
+diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
+index 60589b6..4a5fe55 100644
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -144,7 +144,7 @@ static long swap_inode_boot_loader(struct super_block *sb,
+ handle = ext4_journal_start(inode_bl, EXT4_HT_MOVE_EXTENTS, 2);
+ if (IS_ERR(handle)) {
+ err = -EINVAL;
+- goto swap_boot_out;
++ goto journal_err_out;
+ }
+
+ /* Protect extent tree against block allocations via delalloc */
+@@ -202,6 +202,7 @@ static long swap_inode_boot_loader(struct super_block *sb,
+
+ ext4_double_up_write_data_sem(inode, inode_bl);
+
++journal_err_out:
+ ext4_inode_resume_unlocked_dio(inode);
+ ext4_inode_resume_unlocked_dio(inode_bl);
+
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 04a5c75..09894fa 100644
--- a/fs/ext4/mballoc.c
@@ -58493,8 +58741,96 @@ index 04434ad..6404663 100644
__ext4_warning(sb, function, line,
"MMP failure info: last update time: %llu, last update "
"node: %s, last update device: %s\n",
+diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
+index c5adbb3..f3b84cd 100644
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -243,6 +243,7 @@ static int ext4_alloc_group_tables(struct super_block *sb,
+ ext4_group_t group;
+ ext4_group_t last_group;
+ unsigned overhead;
++ __u16 uninit_mask = (flexbg_size > 1) ? ~EXT4_BG_BLOCK_UNINIT : ~0;
+
+ BUG_ON(flex_gd->count == 0 || group_data == NULL);
+
+@@ -266,7 +267,7 @@ next_group:
+ src_group++;
+ for (; src_group <= last_group; src_group++) {
+ overhead = ext4_group_overhead_blocks(sb, src_group);
+- if (overhead != 0)
++ if (overhead == 0)
+ last_blk += group_data[src_group - group].blocks_count;
+ else
+ break;
+@@ -280,8 +281,7 @@ next_group:
+ group = ext4_get_group_number(sb, start_blk - 1);
+ group -= group_data[0].group;
+ group_data[group].free_blocks_count--;
+- if (flexbg_size > 1)
+- flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT;
++ flex_gd->bg_flags[group] &= uninit_mask;
+ }
+
+ /* Allocate inode bitmaps */
+@@ -292,22 +292,30 @@ next_group:
+ group = ext4_get_group_number(sb, start_blk - 1);
+ group -= group_data[0].group;
+ group_data[group].free_blocks_count--;
+- if (flexbg_size > 1)
+- flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT;
++ flex_gd->bg_flags[group] &= uninit_mask;
+ }
+
+ /* Allocate inode tables */
+ for (; it_index < flex_gd->count; it_index++) {
+- if (start_blk + EXT4_SB(sb)->s_itb_per_group > last_blk)
++ unsigned int itb = EXT4_SB(sb)->s_itb_per_group;
++ ext4_fsblk_t next_group_start;
++
++ if (start_blk + itb > last_blk)
+ goto next_group;
+ group_data[it_index].inode_table = start_blk;
+- group = ext4_get_group_number(sb, start_blk - 1);
++ group = ext4_get_group_number(sb, start_blk);
++ next_group_start = ext4_group_first_block_no(sb, group + 1);
+ group -= group_data[0].group;
+- group_data[group].free_blocks_count -=
+- EXT4_SB(sb)->s_itb_per_group;
+- if (flexbg_size > 1)
+- flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT;
+
++ if (start_blk + itb > next_group_start) {
++ flex_gd->bg_flags[group + 1] &= uninit_mask;
++ overhead = start_blk + itb - next_group_start;
++ group_data[group + 1].free_blocks_count -= overhead;
++ itb -= overhead;
++ }
++
++ group_data[group].free_blocks_count -= itb;
++ flex_gd->bg_flags[group] &= uninit_mask;
+ start_blk += EXT4_SB(sb)->s_itb_per_group;
+ }
+
+@@ -401,7 +409,7 @@ static int set_flexbg_block_bitmap(struct super_block *sb, handle_t *handle,
+ start = ext4_group_first_block_no(sb, group);
+ group -= flex_gd->groups[0].group;
+
+- count2 = sb->s_blocksize * 8 - (block - start);
++ count2 = EXT4_BLOCKS_PER_GROUP(sb) - (block - start);
+ if (count2 > count)
+ count2 = count;
+
+@@ -620,7 +628,7 @@ handle_ib:
+ if (err)
+ goto out;
+ count = group_table_count[j];
+- start = group_data[i].block_bitmap;
++ start = (&group_data[i].block_bitmap)[j];
+ block = start;
+ }
+
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
-index 1f7784d..5d8bbad 100644
+index 1f7784d..a82e4e8 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1270,7 +1270,7 @@ static ext4_fsblk_t get_sb_block(void **data)
@@ -58515,6 +58851,36 @@ index 1f7784d..5d8bbad 100644
static int parse_strtoull(const char *buf,
unsigned long long max, unsigned long long *value)
+@@ -3695,16 +3695,22 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ for (i = 0; i < 4; i++)
+ sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
+ sbi->s_def_hash_version = es->s_def_hash_version;
+- i = le32_to_cpu(es->s_flags);
+- if (i & EXT2_FLAGS_UNSIGNED_HASH)
+- sbi->s_hash_unsigned = 3;
+- else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) {
++ if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
++ i = le32_to_cpu(es->s_flags);
++ if (i & EXT2_FLAGS_UNSIGNED_HASH)
++ sbi->s_hash_unsigned = 3;
++ else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) {
+ #ifdef __CHAR_UNSIGNED__
+- es->s_flags |= cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH);
+- sbi->s_hash_unsigned = 3;
++ if (!(sb->s_flags & MS_RDONLY))
++ es->s_flags |=
++ cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH);
++ sbi->s_hash_unsigned = 3;
+ #else
+- es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH);
++ if (!(sb->s_flags & MS_RDONLY))
++ es->s_flags |=
++ cpu_to_le32(EXT2_FLAGS_SIGNED_HASH);
+ #endif
++ }
+ }
+
+ /* Handle clustersize */
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index 1423c48..9c0c6dc 100644
--- a/fs/ext4/xattr.c
@@ -60248,6 +60614,26 @@ index 4bcdad3..1883822 100644
res = next - LAST_INO_BATCH;
}
+diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
+index 8360674..60bb365 100644
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -514,11 +514,13 @@ int jbd2_journal_start_reserved(handle_t *handle, unsigned int type,
+ * similarly constrained call sites
+ */
+ ret = start_this_handle(journal, handle, GFP_NOFS);
+- if (ret < 0)
++ if (ret < 0) {
+ jbd2_journal_free_reserved(handle);
++ return ret;
++ }
+ handle->h_type = type;
+ handle->h_line_no = line_no;
+- return ret;
++ return 0;
+ }
+ EXPORT_SYMBOL(jbd2_journal_start_reserved);
+
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index 4a6cf28..d3a29d3 100644
--- a/fs/jffs2/erase.c
@@ -61092,6 +61478,22 @@ index f4ccfe6..a5cf064 100644
static struct callback_op callback_ops[];
+diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
+index 812154a..c442a74 100644
+--- a/fs/nfs/dir.c
++++ b/fs/nfs/dir.c
+@@ -1837,6 +1837,11 @@ int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
+ GFP_KERNEL)) {
+ SetPageUptodate(page);
+ unlock_page(page);
++ /*
++ * add_to_page_cache_lru() grabs an extra page refcount.
++ * Drop it here to avoid leaking this page later.
++ */
++ page_cache_release(page);
+ } else
+ __free_page(page);
+
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 00ad1c2..2fde15e 100644
--- a/fs/nfs/inode.c
@@ -86887,7 +87289,7 @@ index 06ec886..9dba35e 100644
if (pm_wakeup_pending()) {
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
-index be7c86b..c741464 100644
+index be7c86b..b972b27 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -385,6 +385,11 @@ static int check_syslog_permissions(int type, bool from_file)
@@ -86902,6 +87304,22 @@ index be7c86b..c741464 100644
if (syslog_action_restricted(type)) {
if (capable(CAP_SYSLOG))
return 0;
+@@ -1080,7 +1085,6 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
+ next_seq = log_next_seq;
+
+ len = 0;
+- prev = 0;
+ while (len >= 0 && seq < next_seq) {
+ struct printk_log *msg = log_from_idx(idx);
+ int textlen;
+@@ -2789,7 +2793,6 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
+ next_idx = idx;
+
+ l = 0;
+- prev = 0;
+ while (seq < dumper->next_seq) {
+ struct printk_log *msg = log_from_idx(idx);
+
diff --git a/kernel/profile.c b/kernel/profile.c
index 6631e1e..310c266 100644
--- a/kernel/profile.c
@@ -100470,6 +100888,71 @@ index e83c416..1094d88 100644
set_fs(KERNEL_DS);
if (level == SOL_SOCKET)
+diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
+index 42fdfc6..1eebf22 100644
+--- a/net/sunrpc/auth_gss/auth_gss.c
++++ b/net/sunrpc/auth_gss/auth_gss.c
+@@ -108,6 +108,7 @@ struct gss_auth {
+ static DEFINE_SPINLOCK(pipe_version_lock);
+ static struct rpc_wait_queue pipe_version_rpc_waitqueue;
+ static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue);
++static void gss_put_auth(struct gss_auth *gss_auth);
+
+ static void gss_free_ctx(struct gss_cl_ctx *);
+ static const struct rpc_pipe_ops gss_upcall_ops_v0;
+@@ -320,6 +321,7 @@ gss_release_msg(struct gss_upcall_msg *gss_msg)
+ if (gss_msg->ctx != NULL)
+ gss_put_ctx(gss_msg->ctx);
+ rpc_destroy_wait_queue(&gss_msg->rpc_waitqueue);
++ gss_put_auth(gss_msg->auth);
+ kfree(gss_msg);
+ }
+
+@@ -498,9 +500,12 @@ gss_alloc_msg(struct gss_auth *gss_auth,
+ default:
+ err = gss_encode_v1_msg(gss_msg, service_name, gss_auth->target_name);
+ if (err)
+- goto err_free_msg;
++ goto err_put_pipe_version;
+ };
++ kref_get(&gss_auth->kref);
+ return gss_msg;
++err_put_pipe_version:
++ put_pipe_version(gss_auth->net);
+ err_free_msg:
+ kfree(gss_msg);
+ err:
+@@ -1071,6 +1076,12 @@ gss_free_callback(struct kref *kref)
+ }
+
+ static void
++gss_put_auth(struct gss_auth *gss_auth)
++{
++ kref_put(&gss_auth->kref, gss_free_callback);
++}
++
++static void
+ gss_destroy(struct rpc_auth *auth)
+ {
+ struct gss_auth *gss_auth = container_of(auth,
+@@ -1091,7 +1102,7 @@ gss_destroy(struct rpc_auth *auth)
+ gss_auth->gss_pipe[1] = NULL;
+ rpcauth_destroy_credcache(auth);
+
+- kref_put(&gss_auth->kref, gss_free_callback);
++ gss_put_auth(gss_auth);
+ }
+
+ /*
+@@ -1262,7 +1273,7 @@ gss_destroy_nullcred(struct rpc_cred *cred)
+ call_rcu(&cred->cr_rcu, gss_free_cred_callback);
+ if (ctx)
+ gss_put_ctx(ctx);
+- kref_put(&gss_auth->kref, gss_free_callback);
++ gss_put_auth(gss_auth);
+ }
+
+ static void
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 1b94a9c..496f7f5 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
@@ -100492,6 +100975,38 @@ index 1b94a9c..496f7f5 100644
/* make a copy for the caller */
*handle = ctxh;
+diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c
+index 890a299..e860d4f 100644
+--- a/net/sunrpc/backchannel_rqst.c
++++ b/net/sunrpc/backchannel_rqst.c
+@@ -64,7 +64,6 @@ static void xprt_free_allocation(struct rpc_rqst *req)
+ free_page((unsigned long)xbufp->head[0].iov_base);
+ xbufp = &req->rq_snd_buf;
+ free_page((unsigned long)xbufp->head[0].iov_base);
+- list_del(&req->rq_bc_pa_list);
+ kfree(req);
+ }
+
+@@ -168,8 +167,10 @@ out_free:
+ /*
+ * Memory allocation failed, free the temporary list
+ */
+- list_for_each_entry_safe(req, tmp, &tmp_list, rq_bc_pa_list)
++ list_for_each_entry_safe(req, tmp, &tmp_list, rq_bc_pa_list) {
++ list_del(&req->rq_bc_pa_list);
+ xprt_free_allocation(req);
++ }
+
+ dprintk("RPC: setup backchannel transport failed\n");
+ return -ENOMEM;
+@@ -198,6 +199,7 @@ void xprt_destroy_backchannel(struct rpc_xprt *xprt, unsigned int max_reqs)
+ xprt_dec_alloc_count(xprt, max_reqs);
+ list_for_each_entry_safe(req, tmp, &xprt->bc_pa_list, rq_bc_pa_list) {
+ dprintk("RPC: req=%p\n", req);
++ list_del(&req->rq_bc_pa_list);
+ xprt_free_allocation(req);
+ if (--max_reqs == 0)
+ break;
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index e726e16..393c39e 100644
--- a/net/sunrpc/clnt.c
@@ -100764,6 +101279,37 @@ index 62e4f9b..dd3f2d7 100644
/* See if we can opportunistically reap SQ WR to make room */
sq_cq_reap(xprt);
+diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
+index dd9d295..cad4a95 100644
+--- a/net/sunrpc/xprtsock.c
++++ b/net/sunrpc/xprtsock.c
+@@ -504,6 +504,7 @@ static int xs_nospace(struct rpc_task *task)
+ struct rpc_rqst *req = task->tk_rqstp;
+ struct rpc_xprt *xprt = req->rq_xprt;
+ struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
++ struct sock *sk = transport->inet;
+ int ret = -EAGAIN;
+
+ dprintk("RPC: %5u xmit incomplete (%u left of %u)\n",
+@@ -521,7 +522,7 @@ static int xs_nospace(struct rpc_task *task)
+ * window size
+ */
+ set_bit(SOCK_NOSPACE, &transport->sock->flags);
+- transport->inet->sk_write_pending++;
++ sk->sk_write_pending++;
+ /* ...and wait for more buffer space */
+ xprt_wait_for_buffer_space(task, xs_nospace_callback);
+ }
+@@ -531,6 +532,9 @@ static int xs_nospace(struct rpc_task *task)
+ }
+
+ spin_unlock_bh(&xprt->transport_lock);
++
++ /* Race breaker in case memory is freed before above code is called */
++ sk->sk_write_space(sk);
+ return ret;
+ }
+
diff --git a/net/sysctl_net.c b/net/sysctl_net.c
index e7000be..e3b0ba7 100644
--- a/net/sysctl_net.c
diff --git a/3.2.55/0000_README b/3.2.55/0000_README
index f81409b..943c944 100644
--- a/3.2.55/0000_README
+++ b/3.2.55/0000_README
@@ -138,7 +138,7 @@ Patch: 1054_linux-3.2.55.patch
From: http://www.kernel.org
Desc: Linux 3.2.55
-Patch: 4420_grsecurity-3.0-3.2.55-201402152203.patch
+Patch: 4420_grsecurity-3.0-3.2.55-201402192249.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/3.2.55/4420_grsecurity-3.0-3.2.55-201402152203.patch b/3.2.55/4420_grsecurity-3.0-3.2.55-201402192249.patch
index c279324..598b438 100644
--- a/3.2.55/4420_grsecurity-3.0-3.2.55-201402152203.patch
+++ b/3.2.55/4420_grsecurity-3.0-3.2.55-201402192249.patch
@@ -9518,7 +9518,7 @@ index ad8f795..2c7eec6 100644
/*
* Memory returned by kmalloc() may be used for DMA, so we must make
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
-index fb2e69d..205753c 100644
+index fb2e69d..440cb91 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -75,6 +75,7 @@ config X86
@@ -9542,7 +9542,7 @@ index fb2e69d..205753c 100644
menuconfig PARAVIRT_GUEST
bool "Paravirtualized guest support"
-+ depends on !GRKERNSEC_CONFIG_AUTO || GRKERNSEC_CONFIG_VIRT_GUEST
++ depends on !GRKERNSEC_CONFIG_AUTO || GRKERNSEC_CONFIG_VIRT_GUEST || (GRKERNSEC_CONFIG_VIRT_HOST && GRKERNSEC_CONFIG_VIRT_XEN)
---help---
Say Y here to get to see options related to running Linux under
various hypervisors. This option alone does not add any kernel code.
@@ -56135,10 +56135,19 @@ index 2845a1f..f29de63 100644
if (free_clusters >= (nclusters + dirty_clusters))
return 1;
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
-index 68b1602..830e05c 100644
+index 68b1602..7f3507d 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
-@@ -1216,19 +1216,19 @@ struct ext4_sb_info {
+@@ -745,6 +745,8 @@ do { \
+ if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime)) \
+ (einode)->xtime.tv_sec = \
+ (signed)le32_to_cpu((raw_inode)->xtime); \
++ else \
++ (einode)->xtime.tv_sec = 0; \
+ if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime ## _extra)) \
+ ext4_decode_extra_time(&(einode)->xtime, \
+ raw_inode->xtime ## _extra); \
+@@ -1216,19 +1218,19 @@ struct ext4_sb_info {
unsigned long s_mb_last_start;
/* stats for buddy allocator */