diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2014-02-20 16:50:42 -0500 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2014-02-20 16:50:42 -0500 |
commit | 6f7a2db6f04b0d6197a234c19145d08d2946cc6c (patch) | |
tree | 186ee628095053c21dc43991a0cc534ad138e1ad | |
parent | Grsec/PaX: 3.0-{3.2.55,3.13.3}-201402152204 (diff) | |
download | hardened-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_README | 2 | ||||
-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_README | 2 | ||||
-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 */ |