commit: eed555cb75109ee399d86659b67a757737eb2890 Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org> AuthorDate: Mon Jan 12 21:59:54 2015 +0000 Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org> CommitDate: Mon Jan 12 21:59:54 2015 +0000 URL: http://sources.gentoo.org/gitweb/?p=proj/hardened-patchset.git;a=commit;h=eed555cb
Grsec/PaX: 3.0-{3.2.66,3.14.2i,3.18.2}-201501120821 --- {3.14.27 => 3.14.28}/0000_README | 6 +- 3.14.28/1027_linux-3.14.28.patch | 1961 ++++++++++++++++++++ .../4420_grsecurity-3.0-3.14.28-201501120819.patch | 335 +--- {3.18.1 => 3.14.28}/4425_grsec_remove_EI_PAX.patch | 0 .../4427_force_XATTR_PAX_tmpfs.patch | 0 .../4430_grsec-remove-localversion-grsec.patch | 0 .../4435_grsec-mute-warnings.patch | 0 .../4440_grsec-remove-protected-paths.patch | 0 .../4450_grsec-kconfig-default-gids.patch | 0 .../4465_selinux-avc_audit-log-curr_ip.patch | 0 .../4470_disable-compat_vdso.patch | 0 {3.18.1 => 3.14.28}/4475_emutramp_default_on.patch | 0 {3.18.1 => 3.18.2}/0000_README | 2 +- .../4420_grsecurity-3.0-3.18.2-201501120821.patch | 624 +------ {3.14.27 => 3.18.2}/4425_grsec_remove_EI_PAX.patch | 0 .../4427_force_XATTR_PAX_tmpfs.patch | 0 .../4430_grsec-remove-localversion-grsec.patch | 0 {3.18.1 => 3.18.2}/4435_grsec-mute-warnings.patch | 0 .../4440_grsec-remove-protected-paths.patch | 0 .../4450_grsec-kconfig-default-gids.patch | 0 .../4465_selinux-avc_audit-log-curr_ip.patch | 0 {3.18.1 => 3.18.2}/4470_disable-compat_vdso.patch | 0 {3.14.27 => 3.18.2}/4475_emutramp_default_on.patch | 0 3.2.66/0000_README | 2 +- ... 4420_grsecurity-3.0-3.2.66-201501111416.patch} | 4 +- 25 files changed, 2124 insertions(+), 810 deletions(-) diff --git a/3.14.27/0000_README b/3.14.28/0000_README similarity index 92% rename from 3.14.27/0000_README rename to 3.14.28/0000_README index c7d2136..fd01bb1 100644 --- a/3.14.27/0000_README +++ b/3.14.28/0000_README @@ -2,7 +2,11 @@ README ----------------------------------------------------------------------------- Individual Patch Descriptions: ----------------------------------------------------------------------------- -Patch: 4420_grsecurity-3.0-3.14.27-201501042018.patch +Patch: 1027_linux-3.14.28.patch +From: http://www.kernel.org +Desc: Linux 3.14.28 + +Patch: 4420_grsecurity-3.0-3.14.28-201501120819.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.14.28/1027_linux-3.14.28.patch b/3.14.28/1027_linux-3.14.28.patch new file mode 100644 index 0000000..ac1ed3f --- /dev/null +++ b/3.14.28/1027_linux-3.14.28.patch @@ -0,0 +1,1961 @@ +diff --git a/Makefile b/Makefile +index 944db23..a2e572b 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 14 +-SUBLEVEL = 27 ++SUBLEVEL = 28 + EXTRAVERSION = + NAME = Remembering Coco + +diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi +index 0d8530c..34841fc 100644 +--- a/arch/arm/boot/dts/armada-370.dtsi ++++ b/arch/arm/boot/dts/armada-370.dtsi +@@ -106,11 +106,6 @@ + reg = <0x11100 0x20>; + }; + +- system-controller@18200 { +- compatible = "marvell,armada-370-xp-system-controller"; +- reg = <0x18200 0x100>; +- }; +- + pinctrl { + compatible = "marvell,mv88f6710-pinctrl"; + reg = <0x18000 0x38>; +@@ -167,6 +162,11 @@ + interrupts = <91>; + }; + ++ system-controller@18200 { ++ compatible = "marvell,armada-370-xp-system-controller"; ++ reg = <0x18200 0x100>; ++ }; ++ + gateclk: clock-gating-control@18220 { + compatible = "marvell,armada-370-gating-clock"; + reg = <0x18220 0x4>; +diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S +index 8c1ba4f..3505799 100644 +--- a/arch/arm/mach-tegra/reset-handler.S ++++ b/arch/arm/mach-tegra/reset-handler.S +@@ -51,6 +51,7 @@ ENTRY(tegra_resume) + THUMB( it ne ) + bne cpu_resume @ no + ++ tegra_get_soc_id TEGRA_APB_MISC_BASE, r6 + /* Are we on Tegra20? */ + cmp r6, #TEGRA20 + beq 1f @ Yes +diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h +index 6cddbb0..e0ec201 100644 +--- a/arch/arm64/include/asm/hwcap.h ++++ b/arch/arm64/include/asm/hwcap.h +@@ -30,6 +30,7 @@ + #define COMPAT_HWCAP_IDIVA (1 << 17) + #define COMPAT_HWCAP_IDIVT (1 << 18) + #define COMPAT_HWCAP_IDIV (COMPAT_HWCAP_IDIVA|COMPAT_HWCAP_IDIVT) ++#define COMPAT_HWCAP_LPAE (1 << 20) + #define COMPAT_HWCAP_EVTSTRM (1 << 21) + + #ifndef __ASSEMBLY__ +diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c +index c8e9eff..071c382 100644 +--- a/arch/arm64/kernel/setup.c ++++ b/arch/arm64/kernel/setup.c +@@ -67,7 +67,8 @@ EXPORT_SYMBOL_GPL(elf_hwcap); + COMPAT_HWCAP_FAST_MULT|COMPAT_HWCAP_EDSP|\ + COMPAT_HWCAP_TLS|COMPAT_HWCAP_VFP|\ + COMPAT_HWCAP_VFPv3|COMPAT_HWCAP_VFPv4|\ +- COMPAT_HWCAP_NEON|COMPAT_HWCAP_IDIV) ++ COMPAT_HWCAP_NEON|COMPAT_HWCAP_IDIV|\ ++ COMPAT_HWCAP_LPAE) + unsigned int compat_elf_hwcap __read_mostly = COMPAT_ELF_HWCAP_DEFAULT; + #endif + +diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c +index db02052..5426c9e 100644 +--- a/arch/s390/kernel/compat_linux.c ++++ b/arch/s390/kernel/compat_linux.c +@@ -245,7 +245,7 @@ asmlinkage long sys32_setgroups16(int gidsetsize, u16 __user *grouplist) + struct group_info *group_info; + int retval; + +- if (!capable(CAP_SETGID)) ++ if (!may_setgroups()) + return -EPERM; + if ((unsigned)gidsetsize > NGROUPS_MAX) + return -EINVAL; +diff --git a/arch/x86/include/uapi/asm/ldt.h b/arch/x86/include/uapi/asm/ldt.h +index 46727eb..6e1aaf7 100644 +--- a/arch/x86/include/uapi/asm/ldt.h ++++ b/arch/x86/include/uapi/asm/ldt.h +@@ -28,6 +28,13 @@ struct user_desc { + unsigned int seg_not_present:1; + unsigned int useable:1; + #ifdef __x86_64__ ++ /* ++ * Because this bit is not present in 32-bit user code, user ++ * programs can pass uninitialized values here. Therefore, in ++ * any context in which a user_desc comes from a 32-bit program, ++ * the kernel must act as though lm == 0, regardless of the ++ * actual value. ++ */ + unsigned int lm:1; + #endif + }; +diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c +index 713f1b3..0b1e1d5 100644 +--- a/arch/x86/kernel/kvm.c ++++ b/arch/x86/kernel/kvm.c +@@ -280,7 +280,14 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code) + static void __init paravirt_ops_setup(void) + { + pv_info.name = "KVM"; +- pv_info.paravirt_enabled = 1; ++ ++ /* ++ * KVM isn't paravirt in the sense of paravirt_enabled. A KVM ++ * guest kernel works like a bare metal kernel with additional ++ * features, and paravirt_enabled is about features that are ++ * missing. ++ */ ++ pv_info.paravirt_enabled = 0; + + if (kvm_para_has_feature(KVM_FEATURE_NOP_IO_DELAY)) + pv_cpu_ops.io_delay = kvm_io_delay; +diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c +index e604109..c8e98cd 100644 +--- a/arch/x86/kernel/kvmclock.c ++++ b/arch/x86/kernel/kvmclock.c +@@ -263,7 +263,6 @@ void __init kvmclock_init(void) + #endif + kvm_get_preset_lpj(); + clocksource_register_hz(&kvm_clock, NSEC_PER_SEC); +- pv_info.paravirt_enabled = 1; + pv_info.name = "KVM"; + + if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE_STABLE_BIT)) +diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c +index 9c0280f..e2d26ce 100644 +--- a/arch/x86/kernel/process_64.c ++++ b/arch/x86/kernel/process_64.c +@@ -286,24 +286,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) + + fpu = switch_fpu_prepare(prev_p, next_p, cpu); + +- /* +- * Reload esp0, LDT and the page table pointer: +- */ ++ /* Reload esp0 and ss1. */ + load_sp0(tss, next); + +- /* +- * Switch DS and ES. +- * This won't pick up thread selector changes, but I guess that is ok. +- */ +- savesegment(es, prev->es); +- if (unlikely(next->es | prev->es)) +- loadsegment(es, next->es); +- +- savesegment(ds, prev->ds); +- if (unlikely(next->ds | prev->ds)) +- loadsegment(ds, next->ds); +- +- + /* We must save %fs and %gs before load_TLS() because + * %fs and %gs may be cleared by load_TLS(). + * +@@ -312,41 +297,101 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) + savesegment(fs, fsindex); + savesegment(gs, gsindex); + ++ /* ++ * Load TLS before restoring any segments so that segment loads ++ * reference the correct GDT entries. ++ */ + load_TLS(next, cpu); + + /* +- * Leave lazy mode, flushing any hypercalls made here. +- * This must be done before restoring TLS segments so +- * the GDT and LDT are properly updated, and must be +- * done before math_state_restore, so the TS bit is up +- * to date. ++ * Leave lazy mode, flushing any hypercalls made here. This ++ * must be done after loading TLS entries in the GDT but before ++ * loading segments that might reference them, and and it must ++ * be done before math_state_restore, so the TS bit is up to ++ * date. + */ + arch_end_context_switch(next_p); + ++ /* Switch DS and ES. ++ * ++ * Reading them only returns the selectors, but writing them (if ++ * nonzero) loads the full descriptor from the GDT or LDT. The ++ * LDT for next is loaded in switch_mm, and the GDT is loaded ++ * above. ++ * ++ * We therefore need to write new values to the segment ++ * registers on every context switch unless both the new and old ++ * values are zero. ++ * ++ * Note that we don't need to do anything for CS and SS, as ++ * those are saved and restored as part of pt_regs. ++ */ ++ savesegment(es, prev->es); ++ if (unlikely(next->es | prev->es)) ++ loadsegment(es, next->es); ++ ++ savesegment(ds, prev->ds); ++ if (unlikely(next->ds | prev->ds)) ++ loadsegment(ds, next->ds); ++ + /* + * Switch FS and GS. + * +- * Segment register != 0 always requires a reload. Also +- * reload when it has changed. When prev process used 64bit +- * base always reload to avoid an information leak. ++ * These are even more complicated than FS and GS: they have ++ * 64-bit bases are that controlled by arch_prctl. Those bases ++ * only differ from the values in the GDT or LDT if the selector ++ * is 0. ++ * ++ * Loading the segment register resets the hidden base part of ++ * the register to 0 or the value from the GDT / LDT. If the ++ * next base address zero, writing 0 to the segment register is ++ * much faster than using wrmsr to explicitly zero the base. ++ * ++ * The thread_struct.fs and thread_struct.gs values are 0 ++ * if the fs and gs bases respectively are not overridden ++ * from the values implied by fsindex and gsindex. They ++ * are nonzero, and store the nonzero base addresses, if ++ * the bases are overridden. ++ * ++ * (fs != 0 && fsindex != 0) || (gs != 0 && gsindex != 0) should ++ * be impossible. ++ * ++ * Therefore we need to reload the segment registers if either ++ * the old or new selector is nonzero, and we need to override ++ * the base address if next thread expects it to be overridden. ++ * ++ * This code is unnecessarily slow in the case where the old and ++ * new indexes are zero and the new base is nonzero -- it will ++ * unnecessarily write 0 to the selector before writing the new ++ * base address. ++ * ++ * Note: This all depends on arch_prctl being the only way that ++ * user code can override the segment base. Once wrfsbase and ++ * wrgsbase are enabled, most of this code will need to change. + */ + if (unlikely(fsindex | next->fsindex | prev->fs)) { + loadsegment(fs, next->fsindex); ++ + /* +- * Check if the user used a selector != 0; if yes +- * clear 64bit base, since overloaded base is always +- * mapped to the Null selector ++ * If user code wrote a nonzero value to FS, then it also ++ * cleared the overridden base address. ++ * ++ * XXX: if user code wrote 0 to FS and cleared the base ++ * address itself, we won't notice and we'll incorrectly ++ * restore the prior base address next time we reschdule ++ * the process. + */ + if (fsindex) + prev->fs = 0; + } +- /* when next process has a 64bit base use it */ + if (next->fs) + wrmsrl(MSR_FS_BASE, next->fs); + prev->fsindex = fsindex; + + if (unlikely(gsindex | next->gsindex | prev->gs)) { + load_gs_index(next->gsindex); ++ ++ /* This works (and fails) the same way as fsindex above. */ + if (gsindex) + prev->gs = 0; + } +diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c +index f7fec09..4e942f3 100644 +--- a/arch/x86/kernel/tls.c ++++ b/arch/x86/kernel/tls.c +@@ -27,6 +27,37 @@ static int get_free_idx(void) + return -ESRCH; + } + ++static bool tls_desc_okay(const struct user_desc *info) ++{ ++ if (LDT_empty(info)) ++ return true; ++ ++ /* ++ * espfix is required for 16-bit data segments, but espfix ++ * only works for LDT segments. ++ */ ++ if (!info->seg_32bit) ++ return false; ++ ++ /* Only allow data segments in the TLS array. */ ++ if (info->contents > 1) ++ return false; ++ ++ /* ++ * Non-present segments with DPL 3 present an interesting attack ++ * surface. The kernel should handle such segments correctly, ++ * but TLS is very difficult to protect in a sandbox, so prevent ++ * such segments from being created. ++ * ++ * If userspace needs to remove a TLS entry, it can still delete ++ * it outright. ++ */ ++ if (info->seg_not_present) ++ return false; ++ ++ return true; ++} ++ + static void set_tls_desc(struct task_struct *p, int idx, + const struct user_desc *info, int n) + { +@@ -66,6 +97,9 @@ int do_set_thread_area(struct task_struct *p, int idx, + if (copy_from_user(&info, u_info, sizeof(info))) + return -EFAULT; + ++ if (!tls_desc_okay(&info)) ++ return -EINVAL; ++ + if (idx == -1) + idx = info.entry_number; + +@@ -192,6 +226,7 @@ int regset_tls_set(struct task_struct *target, const struct user_regset *regset, + { + struct user_desc infobuf[GDT_ENTRY_TLS_ENTRIES]; + const struct user_desc *info; ++ int i; + + if (pos >= GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) || + (pos % sizeof(struct user_desc)) != 0 || +@@ -205,6 +240,10 @@ int regset_tls_set(struct task_struct *target, const struct user_regset *regset, + else + info = infobuf; + ++ for (i = 0; i < count / sizeof(struct user_desc); i++) ++ if (!tls_desc_okay(info + i)) ++ return -EINVAL; ++ + set_tls_desc(target, + GDT_ENTRY_TLS_MIN + (pos / sizeof(struct user_desc)), + info, count / sizeof(struct user_desc)); +diff --git a/crypto/af_alg.c b/crypto/af_alg.c +index 6a3ad80..1de4bee 100644 +--- a/crypto/af_alg.c ++++ b/crypto/af_alg.c +@@ -449,6 +449,9 @@ void af_alg_complete(struct crypto_async_request *req, int err) + { + struct af_alg_completion *completion = req->data; + ++ if (err == -EINPROGRESS) ++ return; ++ + completion->err = err; + complete(&completion->completion); + } +diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c +index 4195a01..8e51b3a 100644 +--- a/drivers/md/bitmap.c ++++ b/drivers/md/bitmap.c +@@ -883,7 +883,6 @@ void bitmap_unplug(struct bitmap *bitmap) + { + unsigned long i; + int dirty, need_write; +- int wait = 0; + + if (!bitmap || !bitmap->storage.filemap || + test_bit(BITMAP_STALE, &bitmap->flags)) +@@ -901,16 +900,13 @@ void bitmap_unplug(struct bitmap *bitmap) + clear_page_attr(bitmap, i, BITMAP_PAGE_PENDING); + write_page(bitmap, bitmap->storage.filemap[i], 0); + } +- if (dirty) +- wait = 1; +- } +- if (wait) { /* if any writes were performed, we need to wait on them */ +- if (bitmap->storage.file) +- wait_event(bitmap->write_wait, +- atomic_read(&bitmap->pending_writes)==0); +- else +- md_super_wait(bitmap->mddev); + } ++ if (bitmap->storage.file) ++ wait_event(bitmap->write_wait, ++ atomic_read(&bitmap->pending_writes)==0); ++ else ++ md_super_wait(bitmap->mddev); ++ + if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags)) + bitmap_file_kick(bitmap); + } +diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c +index a1cebf7..03c872f 100644 +--- a/drivers/md/dm-bufio.c ++++ b/drivers/md/dm-bufio.c +@@ -532,6 +532,19 @@ static void use_dmio(struct dm_buffer *b, int rw, sector_t block, + end_io(&b->bio, r); + } + ++static void inline_endio(struct bio *bio, int error) ++{ ++ bio_end_io_t *end_fn = bio->bi_private; ++ ++ /* ++ * Reset the bio to free any attached resources ++ * (e.g. bio integrity profiles). ++ */ ++ bio_reset(bio); ++ ++ end_fn(bio, error); ++} ++ + static void use_inline_bio(struct dm_buffer *b, int rw, sector_t block, + bio_end_io_t *end_io) + { +@@ -543,7 +556,12 @@ static void use_inline_bio(struct dm_buffer *b, int rw, sector_t block, + b->bio.bi_max_vecs = DM_BUFIO_INLINE_VECS; + b->bio.bi_iter.bi_sector = block << b->c->sectors_per_block_bits; + b->bio.bi_bdev = b->c->bdev; +- b->bio.bi_end_io = end_io; ++ b->bio.bi_end_io = inline_endio; ++ /* ++ * Use of .bi_private isn't a problem here because ++ * the dm_buffer's inline bio is local to bufio. ++ */ ++ b->bio.bi_private = end_io; + + /* + * We assume that if len >= PAGE_SIZE ptr is page-aligned. +diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c +index 2331543..ff284b7 100644 +--- a/drivers/md/dm-cache-target.c ++++ b/drivers/md/dm-cache-target.c +@@ -946,10 +946,14 @@ static void migration_success_post_commit(struct dm_cache_migration *mg) + } + + } else { +- clear_dirty(cache, mg->new_oblock, mg->cblock); +- if (mg->requeue_holder) ++ if (mg->requeue_holder) { ++ clear_dirty(cache, mg->new_oblock, mg->cblock); + cell_defer(cache, mg->new_ocell, true); +- else { ++ } else { ++ /* ++ * The block was promoted via an overwrite, so it's dirty. ++ */ ++ set_dirty(cache, mg->new_oblock, mg->cblock); + bio_endio(mg->new_ocell->holder, 0); + cell_defer(cache, mg->new_ocell, false); + } +@@ -1060,7 +1064,8 @@ static void issue_copy(struct dm_cache_migration *mg) + + avoid = is_discarded_oblock(cache, mg->new_oblock); + +- if (!avoid && bio_writes_complete_block(cache, bio)) { ++ if (writeback_mode(&cache->features) && ++ !avoid && bio_writes_complete_block(cache, bio)) { + issue_overwrite(mg, bio); + return; + } +diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c +index 9533f83..4a8d19d 100644 +--- a/drivers/md/dm-crypt.c ++++ b/drivers/md/dm-crypt.c +@@ -709,7 +709,7 @@ static int crypt_iv_tcw_whitening(struct crypt_config *cc, + for (i = 0; i < ((1 << SECTOR_SHIFT) / 8); i++) + crypto_xor(data + i * 8, buf, 8); + out: +- memset(buf, 0, sizeof(buf)); ++ memzero_explicit(buf, sizeof(buf)); + return r; + } + +diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c +index 37f2648..f7e052c 100644 +--- a/drivers/md/dm-thin.c ++++ b/drivers/md/dm-thin.c +@@ -916,6 +916,24 @@ static void schedule_zero(struct thin_c *tc, dm_block_t virt_block, + } + } + ++static void set_pool_mode(struct pool *pool, enum pool_mode new_mode); ++ ++static void check_for_space(struct pool *pool) ++{ ++ int r; ++ dm_block_t nr_free; ++ ++ if (get_pool_mode(pool) != PM_OUT_OF_DATA_SPACE) ++ return; ++ ++ r = dm_pool_get_free_block_count(pool->pmd, &nr_free); ++ if (r) ++ return; ++ ++ if (nr_free) ++ set_pool_mode(pool, PM_WRITE); ++} ++ + /* + * A non-zero return indicates read_only or fail_io mode. + * Many callers don't care about the return value. +@@ -930,6 +948,8 @@ static int commit(struct pool *pool) + r = dm_pool_commit_metadata(pool->pmd); + if (r) + metadata_operation_failed(pool, "dm_pool_commit_metadata", r); ++ else ++ check_for_space(pool); + + return r; + } +@@ -948,8 +968,6 @@ static void check_low_water_mark(struct pool *pool, dm_block_t free_blocks) + } + } + +-static void set_pool_mode(struct pool *pool, enum pool_mode new_mode); +- + static int alloc_data_block(struct thin_c *tc, dm_block_t *result) + { + int r; +@@ -1592,7 +1610,7 @@ static void set_pool_mode(struct pool *pool, enum pool_mode new_mode) + pool->process_bio = process_bio_read_only; + pool->process_discard = process_discard; + pool->process_prepared_mapping = process_prepared_mapping; +- pool->process_prepared_discard = process_prepared_discard_passdown; ++ pool->process_prepared_discard = process_prepared_discard; + + if (!pool->pf.error_if_no_space && no_space_timeout) + queue_delayed_work(pool->wq, &pool->no_space_timeout, no_space_timeout); +diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/md/persistent-data/dm-space-map-metadata.c +index 786b689..f4e22bc 100644 +--- a/drivers/md/persistent-data/dm-space-map-metadata.c ++++ b/drivers/md/persistent-data/dm-space-map-metadata.c +@@ -564,7 +564,9 @@ static int sm_bootstrap_get_nr_blocks(struct dm_space_map *sm, dm_block_t *count + { + struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); + +- return smm->ll.nr_blocks; ++ *count = smm->ll.nr_blocks; ++ ++ return 0; + } + + static int sm_bootstrap_get_nr_free(struct dm_space_map *sm, dm_block_t *count) +diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c +index 11c19e5..48579e5 100644 +--- a/drivers/mfd/tc6393xb.c ++++ b/drivers/mfd/tc6393xb.c +@@ -263,6 +263,17 @@ static int tc6393xb_ohci_disable(struct platform_device *dev) + return 0; + } + ++static int tc6393xb_ohci_suspend(struct platform_device *dev) ++{ ++ struct tc6393xb_platform_data *tcpd = dev_get_platdata(dev->dev.parent); ++ ++ /* We can't properly store/restore OHCI state, so fail here */ ++ if (tcpd->resume_restore) ++ return -EBUSY; ++ ++ return tc6393xb_ohci_disable(dev); ++} ++ + static int tc6393xb_fb_enable(struct platform_device *dev) + { + struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); +@@ -403,7 +414,7 @@ static struct mfd_cell tc6393xb_cells[] = { + .num_resources = ARRAY_SIZE(tc6393xb_ohci_resources), + .resources = tc6393xb_ohci_resources, + .enable = tc6393xb_ohci_enable, +- .suspend = tc6393xb_ohci_disable, ++ .suspend = tc6393xb_ohci_suspend, + .resume = tc6393xb_ohci_enable, + .disable = tc6393xb_ohci_disable, + }, +diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c +index 7b5424f..df72c47 100644 +--- a/drivers/mmc/card/block.c ++++ b/drivers/mmc/card/block.c +@@ -260,7 +260,7 @@ static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr, + int ret; + struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev)); + +- ret = snprintf(buf, PAGE_SIZE, "%d", ++ ret = snprintf(buf, PAGE_SIZE, "%d\n", + get_disk_ro(dev_to_disk(dev)) ^ + md->read_only); + mmc_blk_put(md); +diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c +index 55cd110..caed9d5 100644 +--- a/drivers/mmc/host/dw_mmc.c ++++ b/drivers/mmc/host/dw_mmc.c +@@ -632,6 +632,13 @@ static void dw_mci_ctrl_rd_thld(struct dw_mci *host, struct mmc_data *data) + + WARN_ON(!(data->flags & MMC_DATA_READ)); + ++ /* ++ * CDTHRCTL doesn't exist prior to 240A (in fact that register offset is ++ * in the FIFO region, so we really shouldn't access it). ++ */ ++ if (host->verid < DW_MMC_240A) ++ return; ++ + if (host->timing != MMC_TIMING_MMC_HS200 && + host->timing != MMC_TIMING_UHS_SDR104) + goto disable; +diff --git a/drivers/mmc/host/sdhci-pci-o2micro.c b/drivers/mmc/host/sdhci-pci-o2micro.c +index f49666b..257e9ca 100644 +--- a/drivers/mmc/host/sdhci-pci-o2micro.c ++++ b/drivers/mmc/host/sdhci-pci-o2micro.c +@@ -88,8 +88,6 @@ void sdhci_pci_o2_fujin2_pci_init(struct sdhci_pci_chip *chip) + return; + scratch_32 &= ~((1 << 21) | (1 << 30)); + +- /* Set RTD3 function disabled */ +- scratch_32 |= ((1 << 29) | (1 << 28)); + pci_write_config_dword(chip->pdev, O2_SD_FUNC_REG3, scratch_32); + + /* Set L1 Entrance Timer */ +diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c +index 1e9d6ad..7563b3d 100644 +--- a/drivers/scsi/NCR5380.c ++++ b/drivers/scsi/NCR5380.c +@@ -2655,14 +2655,14 @@ static void NCR5380_dma_complete(NCR5380_instance * instance) { + * + * Purpose : abort a command + * +- * Inputs : cmd - the Scsi_Cmnd to abort, code - code to set the +- * host byte of the result field to, if zero DID_ABORTED is ++ * Inputs : cmd - the Scsi_Cmnd to abort, code - code to set the ++ * host byte of the result field to, if zero DID_ABORTED is + * used. + * +- * Returns : 0 - success, -1 on failure. ++ * Returns : SUCCESS - success, FAILED on failure. + * +- * XXX - there is no way to abort the command that is currently +- * connected, you have to wait for it to complete. If this is ++ * XXX - there is no way to abort the command that is currently ++ * connected, you have to wait for it to complete. If this is + * a problem, we could implement longjmp() / setjmp(), setjmp() + * called where the loop started in NCR5380_main(). + * +@@ -2712,7 +2712,7 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) { + * aborted flag and get back into our main loop. + */ + +- return 0; ++ return SUCCESS; + } + #endif + +diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c +index 5f31017..31ace4b 100644 +--- a/drivers/scsi/aha1740.c ++++ b/drivers/scsi/aha1740.c +@@ -531,7 +531,7 @@ static int aha1740_eh_abort_handler (Scsi_Cmnd *dummy) + * quiet as possible... + */ + +- return 0; ++ return SUCCESS; + } + + static struct scsi_host_template aha1740_template = { +diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c +index 0f3cdbc..30073d4 100644 +--- a/drivers/scsi/atari_NCR5380.c ++++ b/drivers/scsi/atari_NCR5380.c +@@ -2613,7 +2613,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) + * host byte of the result field to, if zero DID_ABORTED is + * used. + * +- * Returns : 0 - success, -1 on failure. ++ * Returns : SUCCESS - success, FAILED on failure. + * + * XXX - there is no way to abort the command that is currently + * connected, you have to wait for it to complete. If this is +diff --git a/drivers/scsi/esas2r/esas2r_main.c b/drivers/scsi/esas2r/esas2r_main.c +index f37f3e3..28fe6fe 100644 +--- a/drivers/scsi/esas2r/esas2r_main.c ++++ b/drivers/scsi/esas2r/esas2r_main.c +@@ -1057,7 +1057,7 @@ int esas2r_eh_abort(struct scsi_cmnd *cmd) + + cmd->scsi_done(cmd); + +- return 0; ++ return SUCCESS; + } + + spin_lock_irqsave(&a->queue_lock, flags); +diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c +index 816db12..52587ce 100644 +--- a/drivers/scsi/megaraid.c ++++ b/drivers/scsi/megaraid.c +@@ -1967,7 +1967,7 @@ megaraid_abort_and_reset(adapter_t *adapter, Scsi_Cmnd *cmd, int aor) + cmd->device->id, cmd->device->lun); + + if(list_empty(&adapter->pending_list)) +- return FALSE; ++ return FAILED; + + list_for_each_safe(pos, next, &adapter->pending_list) { + +@@ -1990,7 +1990,7 @@ megaraid_abort_and_reset(adapter_t *adapter, Scsi_Cmnd *cmd, int aor) + (aor==SCB_ABORT) ? "ABORTING":"RESET", + scb->idx); + +- return FALSE; ++ return FAILED; + } + else { + +@@ -2015,12 +2015,12 @@ megaraid_abort_and_reset(adapter_t *adapter, Scsi_Cmnd *cmd, int aor) + list_add_tail(SCSI_LIST(cmd), + &adapter->completed_list); + +- return TRUE; ++ return SUCCESS; + } + } + } + +- return FALSE; ++ return FAILED; + } + + static inline int +diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c +index 3b7ad10..c80afde 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_base.c ++++ b/drivers/scsi/megaraid/megaraid_sas_base.c +@@ -953,7 +953,7 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance, + cpu_to_le32(upper_32_bits(cmd_to_abort->frame_phys_addr)); + + cmd->sync_cmd = 1; +- cmd->cmd_status = 0xFF; ++ cmd->cmd_status = ENODATA; + + instance->instancet->issue_dcmd(instance, cmd); + +diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c +index 636bbe0..fc57c8a 100644 +--- a/drivers/scsi/sun3_NCR5380.c ++++ b/drivers/scsi/sun3_NCR5380.c +@@ -2597,15 +2597,15 @@ static void NCR5380_reselect (struct Scsi_Host *instance) + * Purpose : abort a command + * + * Inputs : cmd - the struct scsi_cmnd to abort, code - code to set the +- * host byte of the result field to, if zero DID_ABORTED is ++ * host byte of the result field to, if zero DID_ABORTED is + * used. + * +- * Returns : 0 - success, -1 on failure. ++ * Returns : SUCCESS - success, FAILED on failure. + * +- * XXX - there is no way to abort the command that is currently +- * connected, you have to wait for it to complete. If this is ++ * XXX - there is no way to abort the command that is currently ++ * connected, you have to wait for it to complete. If this is + * a problem, we could implement longjmp() / setjmp(), setjmp() +- * called where the loop started in NCR5380_main(). ++ * called where the loop started in NCR5380_main(). + */ + + static int NCR5380_abort(struct scsi_cmnd *cmd) +diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c +index 71b0ec0..284733e 100644 +--- a/drivers/thermal/thermal_core.c ++++ b/drivers/thermal/thermal_core.c +@@ -1824,10 +1824,10 @@ static int __init thermal_init(void) + + exit_netlink: + genetlink_exit(); +-unregister_governors: +- thermal_unregister_governors(); + unregister_class: + class_unregister(&thermal_class); ++unregister_governors: ++ thermal_unregister_governors(); + error: + idr_destroy(&thermal_tz_idr); + idr_destroy(&thermal_cdev_idr); +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index 370ef74..0db8ded 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -3978,12 +3978,6 @@ again: + if (ret) + break; + +- /* opt_discard */ +- if (btrfs_test_opt(root, DISCARD)) +- ret = btrfs_error_discard_extent(root, start, +- end + 1 - start, +- NULL); +- + clear_extent_dirty(unpin, start, end, GFP_NOFS); + btrfs_error_unpin_extent_range(root, start, end); + cond_resched(); +diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c +index 3ff98e2..d2f1c01 100644 +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -5503,7 +5503,8 @@ void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, + update_global_block_rsv(fs_info); + } + +-static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end) ++static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end, ++ const bool return_free_space) + { + struct btrfs_fs_info *fs_info = root->fs_info; + struct btrfs_block_group_cache *cache = NULL; +@@ -5527,7 +5528,8 @@ static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end) + + if (start < cache->last_byte_to_unpin) { + len = min(len, cache->last_byte_to_unpin - start); +- btrfs_add_free_space(cache, start, len); ++ if (return_free_space) ++ btrfs_add_free_space(cache, start, len); + } + + start += len; +@@ -5590,7 +5592,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, + end + 1 - start, NULL); + + clear_extent_dirty(unpin, start, end, GFP_NOFS); +- unpin_extent_range(root, start, end); ++ unpin_extent_range(root, start, end, true); + cond_resched(); + } + +@@ -8886,7 +8888,7 @@ out: + + int btrfs_error_unpin_extent_range(struct btrfs_root *root, u64 start, u64 end) + { +- return unpin_extent_range(root, start, end); ++ return unpin_extent_range(root, start, end, false); + } + + int btrfs_error_discard_extent(struct btrfs_root *root, u64 bytenr, +diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c +index 996ad56b..82845a6 100644 +--- a/fs/btrfs/extent_map.c ++++ b/fs/btrfs/extent_map.c +@@ -290,8 +290,6 @@ int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, + if (!em) + goto out; + +- if (!test_bit(EXTENT_FLAG_LOGGING, &em->flags)) +- list_move(&em->list, &tree->modified_extents); + em->generation = gen; + clear_bit(EXTENT_FLAG_PINNED, &em->flags); + em->mod_start = em->start; +diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c +index 2f6735d..31b148f 100644 +--- a/fs/ecryptfs/crypto.c ++++ b/fs/ecryptfs/crypto.c +@@ -1917,7 +1917,6 @@ ecryptfs_decode_from_filename(unsigned char *dst, size_t *dst_size, + break; + case 2: + dst[dst_byte_offset++] |= (src_byte); +- dst[dst_byte_offset] = 0; + current_bit_offset = 0; + break; + } +diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c +index b1eaa7a..03df502 100644 +--- a/fs/ecryptfs/file.c ++++ b/fs/ecryptfs/file.c +@@ -191,23 +191,11 @@ static int ecryptfs_open(struct inode *inode, struct file *file) + { + int rc = 0; + struct ecryptfs_crypt_stat *crypt_stat = NULL; +- struct ecryptfs_mount_crypt_stat *mount_crypt_stat; + struct dentry *ecryptfs_dentry = file->f_path.dentry; + /* Private value of ecryptfs_dentry allocated in + * ecryptfs_lookup() */ + struct ecryptfs_file_info *file_info; + +- mount_crypt_stat = &ecryptfs_superblock_to_private( +- ecryptfs_dentry->d_sb)->mount_crypt_stat; +- if ((mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) +- && ((file->f_flags & O_WRONLY) || (file->f_flags & O_RDWR) +- || (file->f_flags & O_CREAT) || (file->f_flags & O_TRUNC) +- || (file->f_flags & O_APPEND))) { +- printk(KERN_WARNING "Mount has encrypted view enabled; " +- "files may only be read\n"); +- rc = -EPERM; +- goto out; +- } + /* Released in ecryptfs_release or end of function if failure */ + file_info = kmem_cache_zalloc(ecryptfs_file_info_cache, GFP_KERNEL); + ecryptfs_set_file_private(file, file_info); +diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c +index 1b119d3..34eb843 100644 +--- a/fs/ecryptfs/main.c ++++ b/fs/ecryptfs/main.c +@@ -493,6 +493,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags + { + struct super_block *s; + struct ecryptfs_sb_info *sbi; ++ struct ecryptfs_mount_crypt_stat *mount_crypt_stat; + struct ecryptfs_dentry_info *root_info; + const char *err = "Getting sb failed"; + struct inode *inode; +@@ -511,6 +512,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags + err = "Error parsing options"; + goto out; + } ++ mount_crypt_stat = &sbi->mount_crypt_stat; + + s = sget(fs_type, NULL, set_anon_super, flags, NULL); + if (IS_ERR(s)) { +@@ -557,11 +559,19 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags + + /** + * Set the POSIX ACL flag based on whether they're enabled in the lower +- * mount. Force a read-only eCryptfs mount if the lower mount is ro. +- * Allow a ro eCryptfs mount even when the lower mount is rw. ++ * mount. + */ + s->s_flags = flags & ~MS_POSIXACL; +- s->s_flags |= path.dentry->d_sb->s_flags & (MS_RDONLY | MS_POSIXACL); ++ s->s_flags |= path.dentry->d_sb->s_flags & MS_POSIXACL; ++ ++ /** ++ * Force a read-only eCryptfs mount when: ++ * 1) The lower mount is ro ++ * 2) The ecryptfs_encrypted_view mount option is specified ++ */ ++ if (path.dentry->d_sb->s_flags & MS_RDONLY || ++ mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) ++ s->s_flags |= MS_RDONLY; + + s->s_maxbytes = path.dentry->d_sb->s_maxbytes; + s->s_blocksize = path.dentry->d_sb->s_blocksize; +diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c +index f488bba..735d752 100644 +--- a/fs/isofs/rock.c ++++ b/fs/isofs/rock.c +@@ -30,6 +30,7 @@ struct rock_state { + int cont_size; + int cont_extent; + int cont_offset; ++ int cont_loops; + struct inode *inode; + }; + +@@ -73,6 +74,9 @@ static void init_rock_state(struct rock_state *rs, struct inode *inode) + rs->inode = inode; + } + ++/* Maximum number of Rock Ridge continuation entries */ ++#define RR_MAX_CE_ENTRIES 32 ++ + /* + * Returns 0 if the caller should continue scanning, 1 if the scan must end + * and -ve on error. +@@ -105,6 +109,8 @@ static int rock_continue(struct rock_state *rs) + goto out; + } + ret = -EIO; ++ if (++rs->cont_loops >= RR_MAX_CE_ENTRIES) ++ goto out; + bh = sb_bread(rs->inode->i_sb, rs->cont_extent); + if (bh) { + memcpy(rs->buffer, bh->b_data + rs->cont_offset, +@@ -356,6 +362,9 @@ repeat: + rs.cont_size = isonum_733(rr->u.CE.size); + break; + case SIG('E', 'R'): ++ /* Invalid length of ER tag id? */ ++ if (rr->u.ER.len_id + offsetof(struct rock_ridge, u.ER.data) > rr->len) ++ goto out; + ISOFS_SB(inode->i_sb)->s_rock = 1; + printk(KERN_DEBUG "ISO 9660 Extensions: "); + { +diff --git a/fs/namespace.c b/fs/namespace.c +index d9bf3ef..039f380 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -1295,6 +1295,8 @@ void umount_tree(struct mount *mnt, int how) + } + if (last) { + last->mnt_hash.next = unmounted.first; ++ if (unmounted.first) ++ unmounted.first->pprev = &last->mnt_hash.next; + unmounted.first = tmp_list.first; + unmounted.first->pprev = &unmounted.first; + } +@@ -1439,6 +1441,9 @@ SYSCALL_DEFINE2(umount, char __user *, name, int, flags) + goto dput_and_out; + if (mnt->mnt.mnt_flags & MNT_LOCKED) + goto dput_and_out; ++ retval = -EPERM; ++ if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN)) ++ goto dput_and_out; + + retval = do_umount(mnt, flags); + dput_and_out: +@@ -1964,7 +1969,13 @@ static int do_remount(struct path *path, int flags, int mnt_flags, + } + if ((mnt->mnt.mnt_flags & MNT_LOCK_NODEV) && + !(mnt_flags & MNT_NODEV)) { +- return -EPERM; ++ /* Was the nodev implicitly added in mount? */ ++ if ((mnt->mnt_ns->user_ns != &init_user_ns) && ++ !(sb->s_type->fs_flags & FS_USERNS_DEV_MOUNT)) { ++ mnt_flags |= MNT_NODEV; ++ } else { ++ return -EPERM; ++ } + } + if ((mnt->mnt.mnt_flags & MNT_LOCK_NOSUID) && + !(mnt_flags & MNT_NOSUID)) { +diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c +index 60426cc..2f970de 100644 +--- a/fs/ncpfs/ioctl.c ++++ b/fs/ncpfs/ioctl.c +@@ -448,7 +448,6 @@ static long __ncp_ioctl(struct inode *inode, unsigned int cmd, unsigned long arg + result = -EIO; + } + } +- result = 0; + } + mutex_unlock(&server->root_setup_lock); + +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index bd01803..58258ad 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -7589,6 +7589,9 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) + + dprintk("--> %s\n", __func__); + ++ /* nfs4_layoutget_release calls pnfs_put_layout_hdr */ ++ pnfs_get_layout_hdr(NFS_I(inode)->layout); ++ + lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags); + if (!lgp->args.layout.pages) { + nfs4_layoutget_release(lgp); +@@ -7601,9 +7604,6 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) + lgp->res.seq_res.sr_slot = NULL; + nfs4_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0); + +- /* nfs4_layoutget_release calls pnfs_put_layout_hdr */ +- pnfs_get_layout_hdr(NFS_I(inode)->layout); +- + task = rpc_run_task(&task_setup_data); + if (IS_ERR(task)) + return ERR_CAST(task); +diff --git a/fs/proc/base.c b/fs/proc/base.c +index b976062..489ba8c 100644 +--- a/fs/proc/base.c ++++ b/fs/proc/base.c +@@ -2555,6 +2555,57 @@ static const struct file_operations proc_projid_map_operations = { + .llseek = seq_lseek, + .release = proc_id_map_release, + }; ++ ++static int proc_setgroups_open(struct inode *inode, struct file *file) ++{ ++ struct user_namespace *ns = NULL; ++ struct task_struct *task; ++ int ret; ++ ++ ret = -ESRCH; ++ task = get_proc_task(inode); ++ if (task) { ++ rcu_read_lock(); ++ ns = get_user_ns(task_cred_xxx(task, user_ns)); ++ rcu_read_unlock(); ++ put_task_struct(task); ++ } ++ if (!ns) ++ goto err; ++ ++ if (file->f_mode & FMODE_WRITE) { ++ ret = -EACCES; ++ if (!ns_capable(ns, CAP_SYS_ADMIN)) ++ goto err_put_ns; ++ } ++ ++ ret = single_open(file, &proc_setgroups_show, ns); ++ if (ret) ++ goto err_put_ns; ++ ++ return 0; ++err_put_ns: ++ put_user_ns(ns); ++err: ++ return ret; ++} ++ ++static int proc_setgroups_release(struct inode *inode, struct file *file) ++{ ++ struct seq_file *seq = file->private_data; ++ struct user_namespace *ns = seq->private; ++ int ret = single_release(inode, file); ++ put_user_ns(ns); ++ return ret; ++} ++ ++static const struct file_operations proc_setgroups_operations = { ++ .open = proc_setgroups_open, ++ .write = proc_setgroups_write, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = proc_setgroups_release, ++}; + #endif /* CONFIG_USER_NS */ + + static int proc_pid_personality(struct seq_file *m, struct pid_namespace *ns, +@@ -2663,6 +2714,7 @@ static const struct pid_entry tgid_base_stuff[] = { + REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations), + REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), + REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations), ++ REG("setgroups", S_IRUGO|S_IWUSR, proc_setgroups_operations), + #endif + #ifdef CONFIG_CHECKPOINT_RESTORE + REG("timers", S_IRUGO, proc_timers_operations), +@@ -2998,6 +3050,7 @@ static const struct pid_entry tid_base_stuff[] = { + REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations), + REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), + REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations), ++ REG("setgroups", S_IRUGO|S_IWUSR, proc_setgroups_operations), + #endif + }; + +diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c +index d7c6dbe..d89f324 100644 +--- a/fs/udf/symlink.c ++++ b/fs/udf/symlink.c +@@ -80,11 +80,17 @@ static int udf_symlink_filler(struct file *file, struct page *page) + struct inode *inode = page->mapping->host; + struct buffer_head *bh = NULL; + unsigned char *symlink; +- int err = -EIO; ++ int err; + unsigned char *p = kmap(page); + struct udf_inode_info *iinfo; + uint32_t pos; + ++ /* We don't support symlinks longer than one block */ ++ if (inode->i_size > inode->i_sb->s_blocksize) { ++ err = -ENAMETOOLONG; ++ goto out_unmap; ++ } ++ + iinfo = UDF_I(inode); + pos = udf_block_map(inode, 0); + +@@ -94,8 +100,10 @@ static int udf_symlink_filler(struct file *file, struct page *page) + } else { + bh = sb_bread(inode->i_sb, pos); + +- if (!bh) +- goto out; ++ if (!bh) { ++ err = -EIO; ++ goto out_unlock_inode; ++ } + + symlink = bh->b_data; + } +@@ -109,9 +117,10 @@ static int udf_symlink_filler(struct file *file, struct page *page) + unlock_page(page); + return 0; + +-out: ++out_unlock_inode: + up_read(&iinfo->i_data_sem); + SetPageError(page); ++out_unmap: + kunmap(page); + unlock_page(page); + return err; +diff --git a/include/linux/audit.h b/include/linux/audit.h +index ec1464d..419b7d7 100644 +--- a/include/linux/audit.h ++++ b/include/linux/audit.h +@@ -47,6 +47,7 @@ struct sk_buff; + + struct audit_krule { + int vers_ops; ++ u32 pflags; + u32 flags; + u32 listnr; + u32 action; +@@ -64,6 +65,9 @@ struct audit_krule { + u64 prio; + }; + ++/* Flag to indicate legacy AUDIT_LOGINUID unset usage */ ++#define AUDIT_LOGINUID_LEGACY 0x1 ++ + struct audit_field { + u32 type; + u32 val; +diff --git a/include/linux/cred.h b/include/linux/cred.h +index 04421e8..6c58dd7 100644 +--- a/include/linux/cred.h ++++ b/include/linux/cred.h +@@ -68,6 +68,7 @@ extern void groups_free(struct group_info *); + extern int set_current_groups(struct group_info *); + extern int set_groups(struct cred *, struct group_info *); + extern int groups_search(const struct group_info *, kgid_t); ++extern bool may_setgroups(void); + + /* access the groups "array" with this macro */ + #define GROUP_AT(gi, i) \ +diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h +index 4836ba3..e92abf9 100644 +--- a/include/linux/user_namespace.h ++++ b/include/linux/user_namespace.h +@@ -17,6 +17,10 @@ struct uid_gid_map { /* 64 bytes -- 1 cache line */ + } extent[UID_GID_MAP_MAX_EXTENTS]; + }; + ++#define USERNS_SETGROUPS_ALLOWED 1UL ++ ++#define USERNS_INIT_FLAGS USERNS_SETGROUPS_ALLOWED ++ + struct user_namespace { + struct uid_gid_map uid_map; + struct uid_gid_map gid_map; +@@ -27,6 +31,7 @@ struct user_namespace { + kuid_t owner; + kgid_t group; + unsigned int proc_inum; ++ unsigned long flags; + + /* Register of per-UID persistent keyrings for this namespace */ + #ifdef CONFIG_PERSISTENT_KEYRINGS +@@ -63,6 +68,9 @@ extern struct seq_operations proc_projid_seq_operations; + extern ssize_t proc_uid_map_write(struct file *, const char __user *, size_t, loff_t *); + extern ssize_t proc_gid_map_write(struct file *, const char __user *, size_t, loff_t *); + extern ssize_t proc_projid_map_write(struct file *, const char __user *, size_t, loff_t *); ++extern ssize_t proc_setgroups_write(struct file *, const char __user *, size_t, loff_t *); ++extern int proc_setgroups_show(struct seq_file *m, void *v); ++extern bool userns_may_setgroups(const struct user_namespace *ns); + #else + + static inline struct user_namespace *get_user_ns(struct user_namespace *ns) +@@ -87,6 +95,10 @@ static inline void put_user_ns(struct user_namespace *ns) + { + } + ++static inline bool userns_may_setgroups(const struct user_namespace *ns) ++{ ++ return true; ++} + #endif + + #endif /* _LINUX_USER_H */ +diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c +index 92062fd..598c1dc 100644 +--- a/kernel/auditfilter.c ++++ b/kernel/auditfilter.c +@@ -429,6 +429,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, + if ((f->type == AUDIT_LOGINUID) && (f->val == AUDIT_UID_UNSET)) { + f->type = AUDIT_LOGINUID_SET; + f->val = 0; ++ entry->rule.pflags |= AUDIT_LOGINUID_LEGACY; + } + + err = audit_field_valid(entry, f); +@@ -604,6 +605,13 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule) + data->buflen += data->values[i] = + audit_pack_string(&bufp, krule->filterkey); + break; ++ case AUDIT_LOGINUID_SET: ++ if (krule->pflags & AUDIT_LOGINUID_LEGACY && !f->val) { ++ data->fields[i] = AUDIT_LOGINUID; ++ data->values[i] = AUDIT_UID_UNSET; ++ break; ++ } ++ /* fallthrough if set */ + default: + data->values[i] = f->val; + } +@@ -620,6 +628,7 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b) + int i; + + if (a->flags != b->flags || ++ a->pflags != b->pflags || + a->listnr != b->listnr || + a->action != b->action || + a->field_count != b->field_count) +@@ -738,6 +747,7 @@ struct audit_entry *audit_dupe_rule(struct audit_krule *old) + new = &entry->rule; + new->vers_ops = old->vers_ops; + new->flags = old->flags; ++ new->pflags = old->pflags; + new->listnr = old->listnr; + new->action = old->action; + for (i = 0; i < AUDIT_BITMASK_SIZE; i++) +diff --git a/kernel/groups.c b/kernel/groups.c +index 90cf1c3..67b4ba3 100644 +--- a/kernel/groups.c ++++ b/kernel/groups.c +@@ -6,6 +6,7 @@ + #include <linux/slab.h> + #include <linux/security.h> + #include <linux/syscalls.h> ++#include <linux/user_namespace.h> + #include <asm/uaccess.h> + + /* init to 2 - one for init_task, one to ensure it is never freed */ +@@ -223,6 +224,14 @@ out: + return i; + } + ++bool may_setgroups(void) ++{ ++ struct user_namespace *user_ns = current_user_ns(); ++ ++ return ns_capable(user_ns, CAP_SETGID) && ++ userns_may_setgroups(user_ns); ++} ++ + /* + * SMP: Our groups are copy-on-write. We can set them safely + * without another task interfering. +@@ -233,7 +242,7 @@ SYSCALL_DEFINE2(setgroups, int, gidsetsize, gid_t __user *, grouplist) + struct group_info *group_info; + int retval; + +- if (!ns_capable(current_user_ns(), CAP_SETGID)) ++ if (!may_setgroups()) + return -EPERM; + if ((unsigned)gidsetsize > NGROUPS_MAX) + return -EINVAL; +diff --git a/kernel/pid.c b/kernel/pid.c +index 9b9a266..82430c8 100644 +--- a/kernel/pid.c ++++ b/kernel/pid.c +@@ -341,6 +341,8 @@ out: + + out_unlock: + spin_unlock_irq(&pidmap_lock); ++ put_pid_ns(ns); ++ + out_free: + while (++i <= ns->level) + free_pidmap(pid->numbers + i); +diff --git a/kernel/uid16.c b/kernel/uid16.c +index 602e5bb..d58cc4d 100644 +--- a/kernel/uid16.c ++++ b/kernel/uid16.c +@@ -176,7 +176,7 @@ SYSCALL_DEFINE2(setgroups16, int, gidsetsize, old_gid_t __user *, grouplist) + struct group_info *group_info; + int retval; + +- if (!ns_capable(current_user_ns(), CAP_SETGID)) ++ if (!may_setgroups()) + return -EPERM; + if ((unsigned)gidsetsize > NGROUPS_MAX) + return -EINVAL; +diff --git a/kernel/user.c b/kernel/user.c +index c006131..c2bbb50 100644 +--- a/kernel/user.c ++++ b/kernel/user.c +@@ -51,6 +51,7 @@ struct user_namespace init_user_ns = { + .owner = GLOBAL_ROOT_UID, + .group = GLOBAL_ROOT_GID, + .proc_inum = PROC_USER_INIT_INO, ++ .flags = USERNS_INIT_FLAGS, + #ifdef CONFIG_PERSISTENT_KEYRINGS + .persistent_keyring_register_sem = + __RWSEM_INITIALIZER(init_user_ns.persistent_keyring_register_sem), +diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c +index 80a57af..153971e 100644 +--- a/kernel/user_namespace.c ++++ b/kernel/user_namespace.c +@@ -24,6 +24,7 @@ + #include <linux/fs_struct.h> + + static struct kmem_cache *user_ns_cachep __read_mostly; ++static DEFINE_MUTEX(userns_state_mutex); + + static bool new_idmap_permitted(const struct file *file, + struct user_namespace *ns, int cap_setid, +@@ -99,6 +100,11 @@ int create_user_ns(struct cred *new) + ns->owner = owner; + ns->group = group; + ++ /* Inherit USERNS_SETGROUPS_ALLOWED from our parent */ ++ mutex_lock(&userns_state_mutex); ++ ns->flags = parent_ns->flags; ++ mutex_unlock(&userns_state_mutex); ++ + set_cred_user_ns(new, ns); + + #ifdef CONFIG_PERSISTENT_KEYRINGS +@@ -581,9 +587,6 @@ static bool mappings_overlap(struct uid_gid_map *new_map, struct uid_gid_extent + return false; + } + +- +-static DEFINE_MUTEX(id_map_mutex); +- + static ssize_t map_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos, + int cap_setid, +@@ -600,7 +603,7 @@ static ssize_t map_write(struct file *file, const char __user *buf, + ssize_t ret = -EINVAL; + + /* +- * The id_map_mutex serializes all writes to any given map. ++ * The userns_state_mutex serializes all writes to any given map. + * + * Any map is only ever written once. + * +@@ -618,7 +621,7 @@ static ssize_t map_write(struct file *file, const char __user *buf, + * order and smp_rmb() is guaranteed that we don't have crazy + * architectures returning stale data. + */ +- mutex_lock(&id_map_mutex); ++ mutex_lock(&userns_state_mutex); + + ret = -EPERM; + /* Only allow one successful write to the map */ +@@ -745,7 +748,7 @@ static ssize_t map_write(struct file *file, const char __user *buf, + *ppos = count; + ret = count; + out: +- mutex_unlock(&id_map_mutex); ++ mutex_unlock(&userns_state_mutex); + if (page) + free_page(page); + return ret; +@@ -804,17 +807,21 @@ static bool new_idmap_permitted(const struct file *file, + struct user_namespace *ns, int cap_setid, + struct uid_gid_map *new_map) + { +- /* Allow mapping to your own filesystem ids */ +- if ((new_map->nr_extents == 1) && (new_map->extent[0].count == 1)) { ++ const struct cred *cred = file->f_cred; ++ /* Don't allow mappings that would allow anything that wouldn't ++ * be allowed without the establishment of unprivileged mappings. ++ */ ++ if ((new_map->nr_extents == 1) && (new_map->extent[0].count == 1) && ++ uid_eq(ns->owner, cred->euid)) { + u32 id = new_map->extent[0].lower_first; + if (cap_setid == CAP_SETUID) { + kuid_t uid = make_kuid(ns->parent, id); +- if (uid_eq(uid, file->f_cred->fsuid)) ++ if (uid_eq(uid, cred->euid)) + return true; +- } +- else if (cap_setid == CAP_SETGID) { ++ } else if (cap_setid == CAP_SETGID) { + kgid_t gid = make_kgid(ns->parent, id); +- if (gid_eq(gid, file->f_cred->fsgid)) ++ if (!(ns->flags & USERNS_SETGROUPS_ALLOWED) && ++ gid_eq(gid, cred->egid)) + return true; + } + } +@@ -834,6 +841,100 @@ static bool new_idmap_permitted(const struct file *file, + return false; + } + ++int proc_setgroups_show(struct seq_file *seq, void *v) ++{ ++ struct user_namespace *ns = seq->private; ++ unsigned long userns_flags = ACCESS_ONCE(ns->flags); ++ ++ seq_printf(seq, "%s\n", ++ (userns_flags & USERNS_SETGROUPS_ALLOWED) ? ++ "allow" : "deny"); ++ return 0; ++} ++ ++ssize_t proc_setgroups_write(struct file *file, const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct seq_file *seq = file->private_data; ++ struct user_namespace *ns = seq->private; ++ char kbuf[8], *pos; ++ bool setgroups_allowed; ++ ssize_t ret; ++ ++ /* Only allow a very narrow range of strings to be written */ ++ ret = -EINVAL; ++ if ((*ppos != 0) || (count >= sizeof(kbuf))) ++ goto out; ++ ++ /* What was written? */ ++ ret = -EFAULT; ++ if (copy_from_user(kbuf, buf, count)) ++ goto out; ++ kbuf[count] = '\0'; ++ pos = kbuf; ++ ++ /* What is being requested? */ ++ ret = -EINVAL; ++ if (strncmp(pos, "allow", 5) == 0) { ++ pos += 5; ++ setgroups_allowed = true; ++ } ++ else if (strncmp(pos, "deny", 4) == 0) { ++ pos += 4; ++ setgroups_allowed = false; ++ } ++ else ++ goto out; ++ ++ /* Verify there is not trailing junk on the line */ ++ pos = skip_spaces(pos); ++ if (*pos != '\0') ++ goto out; ++ ++ ret = -EPERM; ++ mutex_lock(&userns_state_mutex); ++ if (setgroups_allowed) { ++ /* Enabling setgroups after setgroups has been disabled ++ * is not allowed. ++ */ ++ if (!(ns->flags & USERNS_SETGROUPS_ALLOWED)) ++ goto out_unlock; ++ } else { ++ /* Permanently disabling setgroups after setgroups has ++ * been enabled by writing the gid_map is not allowed. ++ */ ++ if (ns->gid_map.nr_extents != 0) ++ goto out_unlock; ++ ns->flags &= ~USERNS_SETGROUPS_ALLOWED; ++ } ++ mutex_unlock(&userns_state_mutex); ++ ++ /* Report a successful write */ ++ *ppos = count; ++ ret = count; ++out: ++ return ret; ++out_unlock: ++ mutex_unlock(&userns_state_mutex); ++ goto out; ++} ++ ++bool userns_may_setgroups(const struct user_namespace *ns) ++{ ++ bool allowed; ++ ++ mutex_lock(&userns_state_mutex); ++ /* It is not safe to use setgroups until a gid mapping in ++ * the user namespace has been established. ++ */ ++ allowed = ns->gid_map.nr_extents != 0; ++ /* Is setgroups allowed? */ ++ allowed = allowed && (ns->flags & USERNS_SETGROUPS_ALLOWED); ++ mutex_unlock(&userns_state_mutex); ++ ++ return allowed; ++} ++ + static void *userns_get(struct task_struct *task) + { + struct user_namespace *user_ns; +diff --git a/net/mac80211/key.c b/net/mac80211/key.c +index 6ff65a1..d78b37a 100644 +--- a/net/mac80211/key.c ++++ b/net/mac80211/key.c +@@ -652,7 +652,7 @@ void ieee80211_free_sta_keys(struct ieee80211_local *local, + int i; + + mutex_lock(&local->key_mtx); +- for (i = 0; i < NUM_DEFAULT_KEYS; i++) { ++ for (i = 0; i < ARRAY_SIZE(sta->gtk); i++) { + key = key_mtx_dereference(local, sta->gtk[i]); + if (!key) + continue; +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index 095c160..1e4dc4e 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1679,14 +1679,14 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + sc = le16_to_cpu(hdr->seq_ctrl); + frag = sc & IEEE80211_SCTL_FRAG; + +- if (likely(!ieee80211_has_morefrags(fc) && frag == 0)) +- goto out; +- + if (is_multicast_ether_addr(hdr->addr1)) { + rx->local->dot11MulticastReceivedFrameCount++; +- goto out; ++ goto out_no_led; + } + ++ if (likely(!ieee80211_has_morefrags(fc) && frag == 0)) ++ goto out; ++ + I802_DEBUG_INC(rx->local->rx_handlers_fragments); + + if (skb_linearize(rx->skb)) +@@ -1777,9 +1777,10 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + status->rx_flags |= IEEE80211_RX_FRAGMENTED; + + out: ++ ieee80211_led_rx(rx->local); ++ out_no_led: + if (rx->sta) + rx->sta->rx_packets++; +- ieee80211_led_rx(rx->local); + return RX_CONTINUE; + } + +diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c +index 9e1e005..c4c8df4 100644 +--- a/security/keys/encrypted-keys/encrypted.c ++++ b/security/keys/encrypted-keys/encrypted.c +@@ -1018,10 +1018,13 @@ static int __init init_encrypted(void) + ret = encrypted_shash_alloc(); + if (ret < 0) + return ret; ++ ret = aes_get_sizes(); ++ if (ret < 0) ++ goto out; + ret = register_key_type(&key_type_encrypted); + if (ret < 0) + goto out; +- return aes_get_sizes(); ++ return 0; + out: + encrypted_shash_release(); + return ret; +diff --git a/tools/testing/selftests/mount/unprivileged-remount-test.c b/tools/testing/selftests/mount/unprivileged-remount-test.c +index 1b3ff2f..5177850 100644 +--- a/tools/testing/selftests/mount/unprivileged-remount-test.c ++++ b/tools/testing/selftests/mount/unprivileged-remount-test.c +@@ -6,6 +6,8 @@ + #include <sys/types.h> + #include <sys/mount.h> + #include <sys/wait.h> ++#include <sys/vfs.h> ++#include <sys/statvfs.h> + #include <stdlib.h> + #include <unistd.h> + #include <fcntl.h> +@@ -32,11 +34,14 @@ + # define CLONE_NEWPID 0x20000000 + #endif + ++#ifndef MS_REC ++# define MS_REC 16384 ++#endif + #ifndef MS_RELATIME +-#define MS_RELATIME (1 << 21) ++# define MS_RELATIME (1 << 21) + #endif + #ifndef MS_STRICTATIME +-#define MS_STRICTATIME (1 << 24) ++# define MS_STRICTATIME (1 << 24) + #endif + + static void die(char *fmt, ...) +@@ -48,17 +53,14 @@ static void die(char *fmt, ...) + exit(EXIT_FAILURE); + } + +-static void write_file(char *filename, char *fmt, ...) ++static void vmaybe_write_file(bool enoent_ok, char *filename, char *fmt, va_list ap) + { + char buf[4096]; + int fd; + ssize_t written; + int buf_len; +- va_list ap; + +- va_start(ap, fmt); + buf_len = vsnprintf(buf, sizeof(buf), fmt, ap); +- va_end(ap); + if (buf_len < 0) { + die("vsnprintf failed: %s\n", + strerror(errno)); +@@ -69,6 +71,8 @@ static void write_file(char *filename, char *fmt, ...) + + fd = open(filename, O_WRONLY); + if (fd < 0) { ++ if ((errno == ENOENT) && enoent_ok) ++ return; + die("open of %s failed: %s\n", + filename, strerror(errno)); + } +@@ -87,6 +91,65 @@ static void write_file(char *filename, char *fmt, ...) + } + } + ++static void maybe_write_file(char *filename, char *fmt, ...) ++{ ++ va_list ap; ++ ++ va_start(ap, fmt); ++ vmaybe_write_file(true, filename, fmt, ap); ++ va_end(ap); ++ ++} ++ ++static void write_file(char *filename, char *fmt, ...) ++{ ++ va_list ap; ++ ++ va_start(ap, fmt); ++ vmaybe_write_file(false, filename, fmt, ap); ++ va_end(ap); ++ ++} ++ ++static int read_mnt_flags(const char *path) ++{ ++ int ret; ++ struct statvfs stat; ++ int mnt_flags; ++ ++ ret = statvfs(path, &stat); ++ if (ret != 0) { ++ die("statvfs of %s failed: %s\n", ++ path, strerror(errno)); ++ } ++ if (stat.f_flag & ~(ST_RDONLY | ST_NOSUID | ST_NODEV | \ ++ ST_NOEXEC | ST_NOATIME | ST_NODIRATIME | ST_RELATIME | \ ++ ST_SYNCHRONOUS | ST_MANDLOCK)) { ++ die("Unrecognized mount flags\n"); ++ } ++ mnt_flags = 0; ++ if (stat.f_flag & ST_RDONLY) ++ mnt_flags |= MS_RDONLY; ++ if (stat.f_flag & ST_NOSUID) ++ mnt_flags |= MS_NOSUID; ++ if (stat.f_flag & ST_NODEV) ++ mnt_flags |= MS_NODEV; ++ if (stat.f_flag & ST_NOEXEC) ++ mnt_flags |= MS_NOEXEC; ++ if (stat.f_flag & ST_NOATIME) ++ mnt_flags |= MS_NOATIME; ++ if (stat.f_flag & ST_NODIRATIME) ++ mnt_flags |= MS_NODIRATIME; ++ if (stat.f_flag & ST_RELATIME) ++ mnt_flags |= MS_RELATIME; ++ if (stat.f_flag & ST_SYNCHRONOUS) ++ mnt_flags |= MS_SYNCHRONOUS; ++ if (stat.f_flag & ST_MANDLOCK) ++ mnt_flags |= ST_MANDLOCK; ++ ++ return mnt_flags; ++} ++ + static void create_and_enter_userns(void) + { + uid_t uid; +@@ -100,13 +163,10 @@ static void create_and_enter_userns(void) + strerror(errno)); + } + ++ maybe_write_file("/proc/self/setgroups", "deny"); + write_file("/proc/self/uid_map", "0 %d 1", uid); + write_file("/proc/self/gid_map", "0 %d 1", gid); + +- if (setgroups(0, NULL) != 0) { +- die("setgroups failed: %s\n", +- strerror(errno)); +- } + if (setgid(0) != 0) { + die ("setgid(0) failed %s\n", + strerror(errno)); +@@ -118,7 +178,8 @@ static void create_and_enter_userns(void) + } + + static +-bool test_unpriv_remount(int mount_flags, int remount_flags, int invalid_flags) ++bool test_unpriv_remount(const char *fstype, const char *mount_options, ++ int mount_flags, int remount_flags, int invalid_flags) + { + pid_t child; + +@@ -151,9 +212,11 @@ bool test_unpriv_remount(int mount_flags, int remount_flags, int invalid_flags) + strerror(errno)); + } + +- if (mount("testing", "/tmp", "ramfs", mount_flags, NULL) != 0) { +- die("mount of /tmp failed: %s\n", +- strerror(errno)); ++ if (mount("testing", "/tmp", fstype, mount_flags, mount_options) != 0) { ++ die("mount of %s with options '%s' on /tmp failed: %s\n", ++ fstype, ++ mount_options? mount_options : "", ++ strerror(errno)); + } + + create_and_enter_userns(); +@@ -181,62 +244,127 @@ bool test_unpriv_remount(int mount_flags, int remount_flags, int invalid_flags) + + static bool test_unpriv_remount_simple(int mount_flags) + { +- return test_unpriv_remount(mount_flags, mount_flags, 0); ++ return test_unpriv_remount("ramfs", NULL, mount_flags, mount_flags, 0); + } + + static bool test_unpriv_remount_atime(int mount_flags, int invalid_flags) + { +- return test_unpriv_remount(mount_flags, mount_flags, invalid_flags); ++ return test_unpriv_remount("ramfs", NULL, mount_flags, mount_flags, ++ invalid_flags); ++} ++ ++static bool test_priv_mount_unpriv_remount(void) ++{ ++ pid_t child; ++ int ret; ++ const char *orig_path = "/dev"; ++ const char *dest_path = "/tmp"; ++ int orig_mnt_flags, remount_mnt_flags; ++ ++ child = fork(); ++ if (child == -1) { ++ die("fork failed: %s\n", ++ strerror(errno)); ++ } ++ if (child != 0) { /* parent */ ++ pid_t pid; ++ int status; ++ pid = waitpid(child, &status, 0); ++ if (pid == -1) { ++ die("waitpid failed: %s\n", ++ strerror(errno)); ++ } ++ if (pid != child) { ++ die("waited for %d got %d\n", ++ child, pid); ++ } ++ if (!WIFEXITED(status)) { ++ die("child did not terminate cleanly\n"); ++ } ++ return WEXITSTATUS(status) == EXIT_SUCCESS ? true : false; ++ } ++ ++ orig_mnt_flags = read_mnt_flags(orig_path); ++ ++ create_and_enter_userns(); ++ ret = unshare(CLONE_NEWNS); ++ if (ret != 0) { ++ die("unshare(CLONE_NEWNS) failed: %s\n", ++ strerror(errno)); ++ } ++ ++ ret = mount(orig_path, dest_path, "bind", MS_BIND | MS_REC, NULL); ++ if (ret != 0) { ++ die("recursive bind mount of %s onto %s failed: %s\n", ++ orig_path, dest_path, strerror(errno)); ++ } ++ ++ ret = mount(dest_path, dest_path, "none", ++ MS_REMOUNT | MS_BIND | orig_mnt_flags , NULL); ++ if (ret != 0) { ++ /* system("cat /proc/self/mounts"); */ ++ die("remount of /tmp failed: %s\n", ++ strerror(errno)); ++ } ++ ++ remount_mnt_flags = read_mnt_flags(dest_path); ++ if (orig_mnt_flags != remount_mnt_flags) { ++ die("Mount flags unexpectedly changed during remount of %s originally mounted on %s\n", ++ dest_path, orig_path); ++ } ++ exit(EXIT_SUCCESS); + } + + int main(int argc, char **argv) + { +- if (!test_unpriv_remount_simple(MS_RDONLY|MS_NODEV)) { ++ if (!test_unpriv_remount_simple(MS_RDONLY)) { + die("MS_RDONLY malfunctions\n"); + } +- if (!test_unpriv_remount_simple(MS_NODEV)) { ++ if (!test_unpriv_remount("devpts", "newinstance", MS_NODEV, MS_NODEV, 0)) { + die("MS_NODEV malfunctions\n"); + } +- if (!test_unpriv_remount_simple(MS_NOSUID|MS_NODEV)) { ++ if (!test_unpriv_remount_simple(MS_NOSUID)) { + die("MS_NOSUID malfunctions\n"); + } +- if (!test_unpriv_remount_simple(MS_NOEXEC|MS_NODEV)) { ++ if (!test_unpriv_remount_simple(MS_NOEXEC)) { + die("MS_NOEXEC malfunctions\n"); + } +- if (!test_unpriv_remount_atime(MS_RELATIME|MS_NODEV, +- MS_NOATIME|MS_NODEV)) ++ if (!test_unpriv_remount_atime(MS_RELATIME, ++ MS_NOATIME)) + { + die("MS_RELATIME malfunctions\n"); + } +- if (!test_unpriv_remount_atime(MS_STRICTATIME|MS_NODEV, +- MS_NOATIME|MS_NODEV)) ++ if (!test_unpriv_remount_atime(MS_STRICTATIME, ++ MS_NOATIME)) + { + die("MS_STRICTATIME malfunctions\n"); + } +- if (!test_unpriv_remount_atime(MS_NOATIME|MS_NODEV, +- MS_STRICTATIME|MS_NODEV)) ++ if (!test_unpriv_remount_atime(MS_NOATIME, ++ MS_STRICTATIME)) + { +- die("MS_RELATIME malfunctions\n"); ++ die("MS_NOATIME malfunctions\n"); + } +- if (!test_unpriv_remount_atime(MS_RELATIME|MS_NODIRATIME|MS_NODEV, +- MS_NOATIME|MS_NODEV)) ++ if (!test_unpriv_remount_atime(MS_RELATIME|MS_NODIRATIME, ++ MS_NOATIME)) + { +- die("MS_RELATIME malfunctions\n"); ++ die("MS_RELATIME|MS_NODIRATIME malfunctions\n"); + } +- if (!test_unpriv_remount_atime(MS_STRICTATIME|MS_NODIRATIME|MS_NODEV, +- MS_NOATIME|MS_NODEV)) ++ if (!test_unpriv_remount_atime(MS_STRICTATIME|MS_NODIRATIME, ++ MS_NOATIME)) + { +- die("MS_RELATIME malfunctions\n"); ++ die("MS_STRICTATIME|MS_NODIRATIME malfunctions\n"); + } +- if (!test_unpriv_remount_atime(MS_NOATIME|MS_NODIRATIME|MS_NODEV, +- MS_STRICTATIME|MS_NODEV)) ++ if (!test_unpriv_remount_atime(MS_NOATIME|MS_NODIRATIME, ++ MS_STRICTATIME)) + { +- die("MS_RELATIME malfunctions\n"); ++ die("MS_NOATIME|MS_DIRATIME malfunctions\n"); + } +- if (!test_unpriv_remount(MS_STRICTATIME|MS_NODEV, MS_NODEV, +- MS_NOATIME|MS_NODEV)) ++ if (!test_unpriv_remount("ramfs", NULL, MS_STRICTATIME, 0, MS_NOATIME)) + { + die("Default atime malfunctions\n"); + } ++ if (!test_priv_mount_unpriv_remount()) { ++ die("Mount flags unexpectedly changed after remount\n"); ++ } + return EXIT_SUCCESS; + } diff --git a/3.14.27/4420_grsecurity-3.0-3.14.27-201501042018.patch b/3.14.28/4420_grsecurity-3.0-3.14.28-201501120819.patch similarity index 99% rename from 3.14.27/4420_grsecurity-3.0-3.14.27-201501042018.patch rename to 3.14.28/4420_grsecurity-3.0-3.14.28-201501120819.patch index c044d35..2e17d75 100644 --- a/3.14.27/4420_grsecurity-3.0-3.14.27-201501042018.patch +++ b/3.14.28/4420_grsecurity-3.0-3.14.28-201501120819.patch @@ -292,7 +292,7 @@ index 7116fda..2f71588 100644 pcd. [PARIDE] diff --git a/Makefile b/Makefile -index 944db23..f799f3e 100644 +index a2e572b..b0e0734 100644 --- a/Makefile +++ b/Makefile @@ -244,8 +244,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ @@ -20522,24 +20522,6 @@ index bbae024..e1528f9 100644 #define BIOS_END 0x00100000 #define BIOS_ROM_BASE 0xffe00000 -diff --git a/arch/x86/include/uapi/asm/ldt.h b/arch/x86/include/uapi/asm/ldt.h -index 46727eb..6e1aaf7 100644 ---- a/arch/x86/include/uapi/asm/ldt.h -+++ b/arch/x86/include/uapi/asm/ldt.h -@@ -28,6 +28,13 @@ struct user_desc { - unsigned int seg_not_present:1; - unsigned int useable:1; - #ifdef __x86_64__ -+ /* -+ * Because this bit is not present in 32-bit user code, user -+ * programs can pass uninitialized values here. Therefore, in -+ * any context in which a user_desc comes from a 32-bit program, -+ * the kernel must act as though lm == 0, regardless of the -+ * actual value. -+ */ - unsigned int lm:1; - #endif - }; diff --git a/arch/x86/include/uapi/asm/ptrace-abi.h b/arch/x86/include/uapi/asm/ptrace-abi.h index 7b0a55a..ad115bf 100644 --- a/arch/x86/include/uapi/asm/ptrace-abi.h @@ -25884,38 +25866,6 @@ index c2bedae..25e7ab60 100644 .attr = { .name = "data", .mode = S_IRUGO, -diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c -index 713f1b3..0b1e1d5 100644 ---- a/arch/x86/kernel/kvm.c -+++ b/arch/x86/kernel/kvm.c -@@ -280,7 +280,14 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code) - static void __init paravirt_ops_setup(void) - { - pv_info.name = "KVM"; -- pv_info.paravirt_enabled = 1; -+ -+ /* -+ * KVM isn't paravirt in the sense of paravirt_enabled. A KVM -+ * guest kernel works like a bare metal kernel with additional -+ * features, and paravirt_enabled is about features that are -+ * missing. -+ */ -+ pv_info.paravirt_enabled = 0; - - if (kvm_para_has_feature(KVM_FEATURE_NOP_IO_DELAY)) - pv_cpu_ops.io_delay = kvm_io_delay; -diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c -index e604109..c8e98cd 100644 ---- a/arch/x86/kernel/kvmclock.c -+++ b/arch/x86/kernel/kvmclock.c -@@ -263,7 +263,6 @@ void __init kvmclock_init(void) - #endif - kvm_get_preset_lpj(); - clocksource_register_hz(&kvm_clock, NSEC_PER_SEC); -- pv_info.paravirt_enabled = 1; - pv_info.name = "KVM"; - - if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE_STABLE_BIT)) diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index c37886d..d851d32 100644 --- a/arch/x86/kernel/ldt.c @@ -26728,7 +26678,7 @@ index 0de43e9..056b840 100644 } - diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c -index 9c0280f..5bbb1c0 100644 +index e2d26ce..10f7ec2 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -158,10 +158,11 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, @@ -26762,17 +26712,18 @@ index 9c0280f..5bbb1c0 100644 unsigned fsindex, gsindex; fpu_switch_t fpu; -@@ -303,6 +306,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) +@@ -334,6 +337,10 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) if (unlikely(next->ds | prev->ds)) loadsegment(ds, next->ds); + savesegment(ss, prev->ss); + if (unlikely(next->ss != prev->ss)) + loadsegment(ss, next->ss); - - /* We must save %fs and %gs before load_TLS() because - * %fs and %gs may be cleared by load_TLS(). -@@ -362,6 +368,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) ++ + /* + * Switch FS and GS. + * +@@ -407,6 +414,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) prev->usersp = this_cpu_read(old_rsp); this_cpu_write(old_rsp, next->usersp); this_cpu_write(current_task, next_p); @@ -26780,7 +26731,7 @@ index 9c0280f..5bbb1c0 100644 /* * If it were not for PREEMPT_ACTIVE we could guarantee that the -@@ -371,9 +378,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) +@@ -416,9 +424,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) task_thread_info(prev_p)->saved_preempt_count = this_cpu_read(__preempt_count); this_cpu_write(__preempt_count, task_thread_info(next_p)->saved_preempt_count); @@ -26791,7 +26742,7 @@ index 9c0280f..5bbb1c0 100644 /* * Now maybe reload the debug registers and handle I/O bitmaps -@@ -442,12 +447,11 @@ unsigned long get_wchan(struct task_struct *p) +@@ -487,12 +493,11 @@ unsigned long get_wchan(struct task_struct *p) if (!p || p == current || p->state == TASK_RUNNING) return 0; stack = (unsigned long)task_stack_page(p); @@ -27884,58 +27835,10 @@ index 24d3c91..d06b473 100644 return pc; } diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c -index f7fec09..d0f623f 100644 +index 4e942f3..d0f623f 100644 --- a/arch/x86/kernel/tls.c +++ b/arch/x86/kernel/tls.c -@@ -27,6 +27,37 @@ static int get_free_idx(void) - return -ESRCH; - } - -+static bool tls_desc_okay(const struct user_desc *info) -+{ -+ if (LDT_empty(info)) -+ return true; -+ -+ /* -+ * espfix is required for 16-bit data segments, but espfix -+ * only works for LDT segments. -+ */ -+ if (!info->seg_32bit) -+ return false; -+ -+ /* Only allow data segments in the TLS array. */ -+ if (info->contents > 1) -+ return false; -+ -+ /* -+ * Non-present segments with DPL 3 present an interesting attack -+ * surface. The kernel should handle such segments correctly, -+ * but TLS is very difficult to protect in a sandbox, so prevent -+ * such segments from being created. -+ * -+ * If userspace needs to remove a TLS entry, it can still delete -+ * it outright. -+ */ -+ if (info->seg_not_present) -+ return false; -+ -+ return true; -+} -+ - static void set_tls_desc(struct task_struct *p, int idx, - const struct user_desc *info, int n) - { -@@ -66,6 +97,9 @@ int do_set_thread_area(struct task_struct *p, int idx, - if (copy_from_user(&info, u_info, sizeof(info))) - return -EFAULT; - -+ if (!tls_desc_okay(&info)) -+ return -EINVAL; -+ - if (idx == -1) - idx = info.entry_number; - -@@ -84,6 +118,11 @@ int do_set_thread_area(struct task_struct *p, int idx, +@@ -118,6 +118,11 @@ int do_set_thread_area(struct task_struct *p, int idx, if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) return -EINVAL; @@ -27947,15 +27850,7 @@ index f7fec09..d0f623f 100644 set_tls_desc(p, idx, &info, 1); return 0; -@@ -192,6 +231,7 @@ int regset_tls_set(struct task_struct *target, const struct user_regset *regset, - { - struct user_desc infobuf[GDT_ENTRY_TLS_ENTRIES]; - const struct user_desc *info; -+ int i; - - if (pos >= GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) || - (pos % sizeof(struct user_desc)) != 0 || -@@ -200,11 +240,15 @@ int regset_tls_set(struct task_struct *target, const struct user_regset *regset, +@@ -235,7 +240,7 @@ int regset_tls_set(struct task_struct *target, const struct user_regset *regset, if (kbuf) info = kbuf; @@ -27964,14 +27859,6 @@ index f7fec09..d0f623f 100644 return -EFAULT; else info = infobuf; - -+ for (i = 0; i < count / sizeof(struct user_desc); i++) -+ if (!tls_desc_okay(info + i)) -+ return -EINVAL; -+ - set_tls_desc(target, - GDT_ENTRY_TLS_MIN + (pos / sizeof(struct user_desc)), - info, count / sizeof(struct user_desc)); diff --git a/arch/x86/kernel/tracepoint.c b/arch/x86/kernel/tracepoint.c index 1c113db..287b42e 100644 --- a/arch/x86/kernel/tracepoint.c @@ -44228,7 +44115,7 @@ index c9a02fe..0debc75 100644 INIT_LIST_HEAD(&serio_raw->client_list); init_waitqueue_head(&serio_raw->wait); diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c -index 9cbef59..76d5cd3 100644 +index 9cbef59..26db8e4 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -878,11 +878,21 @@ static void copy_cmd_to_buffer(struct amd_iommu *iommu, @@ -44243,7 +44130,7 @@ index 9cbef59..76d5cd3 100644 - cmd->data[1] = upper_32_bits(__pa(address)); + +#ifdef CONFIG_GRKERNSEC_KSTACKOVERFLOW -+ if (object_starts_on_stack(address)) { ++ if (object_starts_on_stack((void *)address)) { + void *adjbuf = (void *)address - current->stack + current->lowmem_stack; + physaddr = __pa((u64)adjbuf); + } else @@ -44933,10 +44820,10 @@ index 7ef7461..5a09dac 100644 cl->fn = fn; cl->wq = wq; diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c -index 4195a01..42527ac 100644 +index 8e51b3a..bc6febf 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c -@@ -1779,7 +1779,7 @@ void bitmap_status(struct seq_file *seq, struct bitmap *bitmap) +@@ -1775,7 +1775,7 @@ void bitmap_status(struct seq_file *seq, struct bitmap *bitmap) chunk_kb ? "KB" : "B"); if (bitmap->storage.file) { seq_printf(seq, ", file: "); @@ -45341,10 +45228,10 @@ index 07bba96..2d6788c 100644 struct md_personality diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/md/persistent-data/dm-space-map-metadata.c -index 786b689..ea8c956 100644 +index f4e22bc..8f83114 100644 --- a/drivers/md/persistent-data/dm-space-map-metadata.c +++ b/drivers/md/persistent-data/dm-space-map-metadata.c -@@ -679,7 +679,7 @@ static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks) +@@ -681,7 +681,7 @@ static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks) * Flick into a mode where all blocks get allocated in the new area. */ smm->begin = old_len; @@ -45353,7 +45240,7 @@ index 786b689..ea8c956 100644 /* * Extend. -@@ -710,7 +710,7 @@ out: +@@ -712,7 +712,7 @@ out: /* * Switch back to normal behaviour. */ @@ -47530,7 +47417,7 @@ index 82dc574..8539ab2 100644 break; diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c -index 7b5424f..ed1d6ac 100644 +index df72c47..7e2aad4 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -575,7 +575,7 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, @@ -63686,47 +63573,6 @@ index e846a32..bb06bd0 100644 put_cpu_var(last_ino); return res; } -diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c -index f488bba..735d752 100644 ---- a/fs/isofs/rock.c -+++ b/fs/isofs/rock.c -@@ -30,6 +30,7 @@ struct rock_state { - int cont_size; - int cont_extent; - int cont_offset; -+ int cont_loops; - struct inode *inode; - }; - -@@ -73,6 +74,9 @@ static void init_rock_state(struct rock_state *rs, struct inode *inode) - rs->inode = inode; - } - -+/* Maximum number of Rock Ridge continuation entries */ -+#define RR_MAX_CE_ENTRIES 32 -+ - /* - * Returns 0 if the caller should continue scanning, 1 if the scan must end - * and -ve on error. -@@ -105,6 +109,8 @@ static int rock_continue(struct rock_state *rs) - goto out; - } - ret = -EIO; -+ if (++rs->cont_loops >= RR_MAX_CE_ENTRIES) -+ goto out; - bh = sb_bread(rs->inode->i_sb, rs->cont_extent); - if (bh) { - memcpy(rs->buffer, bh->b_data + rs->cont_offset, -@@ -356,6 +362,9 @@ repeat: - rs.cont_size = isonum_733(rr->u.CE.size); - break; - case SIG('E', 'R'): -+ /* Invalid length of ER tag id? */ -+ if (rr->u.ER.len_id + offsetof(struct rock_ridge, u.ER.data) > rr->len) -+ goto out; - ISOFS_SB(inode->i_sb)->s_rock = 1; - printk(KERN_DEBUG "ISO 9660 Extensions: "); - { diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c index 4a6cf28..d3a29d3 100644 --- a/fs/jffs2/erase.c @@ -63769,7 +63615,7 @@ index e2b7483..855bca3 100644 if (jfs_inode_cachep == NULL) return -ENOMEM; diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c -index 39c0143..829bfe5 100644 +index 39c0143..79e8b68 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -28,7 +28,7 @@ DEFINE_MUTEX(kernfs_mutex); @@ -63781,7 +63627,7 @@ index 39c0143..829bfe5 100644 { unsigned long hash = init_name_hash(); unsigned int len = strlen(name); -@@ -729,11 +729,17 @@ static int kernfs_iop_mkdir(struct inode *dir, struct dentry *dentry, +@@ -729,11 +729,19 @@ static int kernfs_iop_mkdir(struct inode *dir, struct dentry *dentry, { struct kernfs_node *parent = dir->i_private; struct kernfs_dir_ops *kdops = kernfs_root(parent)->dir_ops; @@ -63793,8 +63639,10 @@ index 39c0143..829bfe5 100644 - return kdops->mkdir(parent, dentry->d_name.name, mode); + ret = kdops->mkdir(parent, dentry->d_name.name, mode); + -+ if (!ret) -+ ret = kernfs_iop_lookup(dir, dentry, 0); ++ if (!ret) { ++ struct dentry *dentry_ret = kernfs_iop_lookup(dir, dentry, 0); ++ ret = PTR_ERR_OR_ZERO(dentry_ret); ++ } + + return ret; } @@ -64597,19 +64445,10 @@ index 0dd72c8..34dd17d 100644 out: return len; diff --git a/fs/namespace.c b/fs/namespace.c -index d9bf3ef..359b08c 100644 +index 039f380..4239636 100644 --- a/fs/namespace.c +++ b/fs/namespace.c -@@ -1295,6 +1295,8 @@ void umount_tree(struct mount *mnt, int how) - } - if (last) { - last->mnt_hash.next = unmounted.first; -+ if (unmounted.first) -+ unmounted.first->pprev = &last->mnt_hash.next; - unmounted.first = tmp_list.first; - unmounted.first->pprev = &unmounted.first; - } -@@ -1371,6 +1373,9 @@ static int do_umount(struct mount *mnt, int flags) +@@ -1373,6 +1373,9 @@ static int do_umount(struct mount *mnt, int flags) if (!(sb->s_flags & MS_RDONLY)) retval = do_remount_sb(sb, MS_RDONLY, NULL, 0); up_write(&sb->s_umount); @@ -64619,7 +64458,7 @@ index d9bf3ef..359b08c 100644 return retval; } -@@ -1393,6 +1398,9 @@ static int do_umount(struct mount *mnt, int flags) +@@ -1395,6 +1398,9 @@ static int do_umount(struct mount *mnt, int flags) } unlock_mount_hash(); namespace_unlock(); @@ -64629,7 +64468,7 @@ index d9bf3ef..359b08c 100644 return retval; } -@@ -1412,7 +1420,7 @@ static inline bool may_mount(void) +@@ -1414,7 +1420,7 @@ static inline bool may_mount(void) * unixes. Our API is identical to OSF/1 to avoid making a mess of AMD */ @@ -64638,7 +64477,7 @@ index d9bf3ef..359b08c 100644 { struct path path; struct mount *mnt; -@@ -1454,7 +1462,7 @@ out: +@@ -1459,7 +1465,7 @@ out: /* * The 2.0 compatible umount. No flags. */ @@ -64647,7 +64486,7 @@ index d9bf3ef..359b08c 100644 { return sys_umount(name, 0); } -@@ -2503,6 +2511,16 @@ long do_mount(const char *dev_name, const char *dir_name, +@@ -2514,6 +2520,16 @@ long do_mount(const char *dev_name, const char *dir_name, MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT | MS_STRICTATIME); @@ -64664,7 +64503,7 @@ index d9bf3ef..359b08c 100644 if (flags & MS_REMOUNT) retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags, data_page); -@@ -2517,6 +2535,9 @@ long do_mount(const char *dev_name, const char *dir_name, +@@ -2528,6 +2544,9 @@ long do_mount(const char *dev_name, const char *dir_name, dev_name, data_page); dput_out: path_put(&path); @@ -64674,7 +64513,7 @@ index d9bf3ef..359b08c 100644 return retval; } -@@ -2534,7 +2555,7 @@ static void free_mnt_ns(struct mnt_namespace *ns) +@@ -2545,7 +2564,7 @@ static void free_mnt_ns(struct mnt_namespace *ns) * number incrementing at 10Ghz will take 12,427 years to wrap which * is effectively never, so we can ignore the possibility. */ @@ -64683,7 +64522,7 @@ index d9bf3ef..359b08c 100644 static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns) { -@@ -2549,7 +2570,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns) +@@ -2560,7 +2579,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns) kfree(new_ns); return ERR_PTR(ret); } @@ -64692,7 +64531,7 @@ index d9bf3ef..359b08c 100644 atomic_set(&new_ns->count, 1); new_ns->root = NULL; INIT_LIST_HEAD(&new_ns->list); -@@ -2559,7 +2580,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns) +@@ -2570,7 +2589,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns) return new_ns; } @@ -64701,7 +64540,7 @@ index d9bf3ef..359b08c 100644 struct user_namespace *user_ns, struct fs_struct *new_fs) { struct mnt_namespace *new_ns; -@@ -2680,8 +2701,8 @@ struct dentry *mount_subtree(struct vfsmount *mnt, const char *name) +@@ -2691,8 +2710,8 @@ struct dentry *mount_subtree(struct vfsmount *mnt, const char *name) } EXPORT_SYMBOL(mount_subtree); @@ -64712,7 +64551,7 @@ index d9bf3ef..359b08c 100644 { int ret; char *kernel_type; -@@ -2794,6 +2815,11 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, +@@ -2805,6 +2824,11 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, if (error) goto out2; @@ -64724,7 +64563,7 @@ index d9bf3ef..359b08c 100644 get_fs_root(current->fs, &root); old_mp = lock_mount(&old); error = PTR_ERR(old_mp); -@@ -3065,7 +3091,7 @@ static int mntns_install(struct nsproxy *nsproxy, void *ns) +@@ -3076,7 +3100,7 @@ static int mntns_install(struct nsproxy *nsproxy, void *ns) !ns_capable(current_user_ns(), CAP_SYS_ADMIN)) return -EPERM; @@ -65830,7 +65669,7 @@ index baf3464..5b394ec 100644 static struct pid * get_children_pid(struct inode *inode, struct pid *pid_prev, loff_t pos) diff --git a/fs/proc/base.c b/fs/proc/base.c -index b976062..584d0bc 100644 +index 489ba8c..72265d6 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -113,6 +113,14 @@ struct pid_entry { @@ -66159,7 +65998,7 @@ index b976062..584d0bc 100644 if (!dir_emit_dots(file, ctx)) goto out; -@@ -2597,7 +2721,7 @@ static const struct pid_entry tgid_base_stuff[] = { +@@ -2648,7 +2772,7 @@ static const struct pid_entry tgid_base_stuff[] = { REG("autogroup", S_IRUGO|S_IWUSR, proc_pid_sched_autogroup_operations), #endif REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations), @@ -66168,7 +66007,7 @@ index b976062..584d0bc 100644 INF("syscall", S_IRUGO, proc_pid_syscall), #endif INF("cmdline", S_IRUGO, proc_pid_cmdline), -@@ -2622,10 +2746,10 @@ static const struct pid_entry tgid_base_stuff[] = { +@@ -2673,10 +2797,10 @@ static const struct pid_entry tgid_base_stuff[] = { #ifdef CONFIG_SECURITY DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations), #endif @@ -66181,7 +66020,7 @@ index b976062..584d0bc 100644 ONE("stack", S_IRUGO, proc_pid_stack), #endif #ifdef CONFIG_SCHEDSTATS -@@ -2659,6 +2783,9 @@ static const struct pid_entry tgid_base_stuff[] = { +@@ -2710,6 +2834,9 @@ static const struct pid_entry tgid_base_stuff[] = { #ifdef CONFIG_HARDWALL INF("hardwall", S_IRUGO, proc_pid_hardwall), #endif @@ -66191,7 +66030,7 @@ index b976062..584d0bc 100644 #ifdef CONFIG_USER_NS REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations), REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), -@@ -2789,7 +2916,14 @@ static int proc_pid_instantiate(struct inode *dir, +@@ -2841,7 +2968,14 @@ static int proc_pid_instantiate(struct inode *dir, if (!inode) goto out; @@ -66206,7 +66045,7 @@ index b976062..584d0bc 100644 inode->i_op = &proc_tgid_base_inode_operations; inode->i_fop = &proc_tgid_base_operations; inode->i_flags|=S_IMMUTABLE; -@@ -2827,7 +2961,11 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsign +@@ -2879,7 +3013,11 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsign if (!task) goto out; @@ -66218,7 +66057,7 @@ index b976062..584d0bc 100644 put_task_struct(task); out: return ERR_PTR(result); -@@ -2933,7 +3071,7 @@ static const struct pid_entry tid_base_stuff[] = { +@@ -2985,7 +3123,7 @@ static const struct pid_entry tid_base_stuff[] = { REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), #endif REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations), @@ -66227,7 +66066,7 @@ index b976062..584d0bc 100644 INF("syscall", S_IRUGO, proc_pid_syscall), #endif INF("cmdline", S_IRUGO, proc_pid_cmdline), -@@ -2960,10 +3098,10 @@ static const struct pid_entry tid_base_stuff[] = { +@@ -3012,10 +3150,10 @@ static const struct pid_entry tid_base_stuff[] = { #ifdef CONFIG_SECURITY DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations), #endif @@ -68517,7 +68356,7 @@ index 3306b9f..a1e0eda 100644 } diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c -index d7c6dbe..0422b7b 100644 +index d89f324..0422b7b 100644 --- a/fs/udf/symlink.c +++ b/fs/udf/symlink.c @@ -30,49 +30,73 @@ @@ -68600,36 +68439,7 @@ index d7c6dbe..0422b7b 100644 } static int udf_symlink_filler(struct file *file, struct page *page) -@@ -80,11 +104,17 @@ static int udf_symlink_filler(struct file *file, struct page *page) - struct inode *inode = page->mapping->host; - struct buffer_head *bh = NULL; - unsigned char *symlink; -- int err = -EIO; -+ int err; - unsigned char *p = kmap(page); - struct udf_inode_info *iinfo; - uint32_t pos; - -+ /* We don't support symlinks longer than one block */ -+ if (inode->i_size > inode->i_sb->s_blocksize) { -+ err = -ENAMETOOLONG; -+ goto out_unmap; -+ } -+ - iinfo = UDF_I(inode); - pos = udf_block_map(inode, 0); - -@@ -94,14 +124,18 @@ static int udf_symlink_filler(struct file *file, struct page *page) - } else { - bh = sb_bread(inode->i_sb, pos); - -- if (!bh) -- goto out; -+ if (!bh) { -+ err = -EIO; -+ goto out_unlock_inode; -+ } - +@@ -108,8 +132,10 @@ static int udf_symlink_filler(struct file *file, struct page *page) symlink = bh->b_data; } @@ -68641,18 +68451,6 @@ index d7c6dbe..0422b7b 100644 up_read(&iinfo->i_data_sem); SetPageUptodate(page); -@@ -109,9 +143,10 @@ static int udf_symlink_filler(struct file *file, struct page *page) - unlock_page(page); - return 0; - --out: -+out_unlock_inode: - up_read(&iinfo->i_data_sem); - SetPageError(page); -+out_unmap: - kunmap(page); - unlock_page(page); - return err; diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index be7dabb..6b10c98 100644 --- a/fs/udf/udfdecl.h @@ -80916,10 +80714,10 @@ index c1da539..1dcec55 100644 struct atmphy_ops { int (*start)(struct atm_dev *dev); diff --git a/include/linux/audit.h b/include/linux/audit.h -index ec1464d..833274b 100644 +index 419b7d7..b79b4f2 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h -@@ -196,7 +196,7 @@ static inline void audit_ptrace(struct task_struct *t) +@@ -200,7 +200,7 @@ static inline void audit_ptrace(struct task_struct *t) extern unsigned int audit_serial(void); extern int auditsc_get_stamp(struct audit_context *ctx, struct timespec *t, unsigned int *serial); @@ -81419,7 +81217,7 @@ index d08e4d2..95fad61 100644 /** diff --git a/include/linux/cred.h b/include/linux/cred.h -index 04421e8..a85afd4 100644 +index 6c58dd7..80d1d95 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h @@ -35,7 +35,7 @@ struct group_info { @@ -81431,7 +81229,7 @@ index 04421e8..a85afd4 100644 /** * get_group_info - Get a reference to a group info structure -@@ -136,7 +136,7 @@ struct cred { +@@ -137,7 +137,7 @@ struct cred { struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */ struct group_info *group_info; /* supplementary groups for euid/fsgid */ struct rcu_head rcu; /* RCU deletion hook */ @@ -81440,7 +81238,7 @@ index 04421e8..a85afd4 100644 extern void __put_cred(struct cred *); extern void exit_creds(struct task_struct *); -@@ -194,6 +194,9 @@ static inline void validate_creds_for_do_exit(struct task_struct *tsk) +@@ -195,6 +195,9 @@ static inline void validate_creds_for_do_exit(struct task_struct *tsk) static inline void validate_process_creds(void) { } @@ -81450,7 +81248,7 @@ index 04421e8..a85afd4 100644 #endif /** -@@ -322,6 +325,7 @@ static inline void put_cred(const struct cred *_cred) +@@ -323,6 +326,7 @@ static inline void put_cred(const struct cred *_cred) #define task_uid(task) (task_cred_xxx((task), uid)) #define task_euid(task) (task_cred_xxx((task), euid)) @@ -86518,10 +86316,10 @@ index e452ba6..78f8e80 100644 /* * callback functions for platform diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h -index 4836ba3..603f6ee 100644 +index e92abf9..b802b30 100644 --- a/include/linux/user_namespace.h +++ b/include/linux/user_namespace.h -@@ -33,7 +33,7 @@ struct user_namespace { +@@ -38,7 +38,7 @@ struct user_namespace { struct key *persistent_keyring_register; struct rw_semaphore persistent_keyring_register_sem; #endif @@ -91994,7 +91792,7 @@ index 6d63003..486a109 100644 } EXPORT_SYMBOL(__stack_chk_fail); diff --git a/kernel/pid.c b/kernel/pid.c -index 9b9a266..c20ef80 100644 +index 82430c8..53d7793 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -33,6 +33,7 @@ @@ -92014,7 +91812,7 @@ index 9b9a266..c20ef80 100644 int pid_max_min = RESERVED_PIDS + 1; int pid_max_max = PID_MAX_LIMIT; -@@ -445,10 +446,18 @@ EXPORT_SYMBOL(pid_task); +@@ -447,10 +448,18 @@ EXPORT_SYMBOL(pid_task); */ struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns) { @@ -92034,7 +91832,7 @@ index 9b9a266..c20ef80 100644 } struct task_struct *find_task_by_vpid(pid_t vnr) -@@ -456,6 +465,14 @@ struct task_struct *find_task_by_vpid(pid_t vnr) +@@ -458,6 +467,14 @@ struct task_struct *find_task_by_vpid(pid_t vnr) return find_task_by_pid_ns(vnr, task_active_pid_ns(current)); } @@ -94930,10 +94728,10 @@ index 7e3cd7a..5156a5fe 100644 mutex_lock(&syscall_trace_lock); sys_perf_refcount_exit--; diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c -index 80a57af..7f5a7ff 100644 +index 153971e..ac4be58 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c -@@ -82,6 +82,21 @@ int create_user_ns(struct cred *new) +@@ -83,6 +83,21 @@ int create_user_ns(struct cred *new) !kgid_has_mapping(parent_ns, group)) return -EPERM; @@ -94955,7 +94753,7 @@ index 80a57af..7f5a7ff 100644 ns = kmem_cache_zalloc(user_ns_cachep, GFP_KERNEL); if (!ns) return -ENOMEM; -@@ -865,7 +880,7 @@ static int userns_install(struct nsproxy *nsproxy, void *ns) +@@ -966,7 +981,7 @@ static int userns_install(struct nsproxy *nsproxy, void *ns) if (atomic_read(¤t->mm->mm_users) > 1) return -EINVAL; @@ -118556,10 +118354,10 @@ index 0000000..4378111 +} diff --git a/tools/gcc/size_overflow_plugin/size_overflow_hash.data b/tools/gcc/size_overflow_plugin/size_overflow_hash.data new file mode 100644 -index 0000000..bbd5d8e +index 0000000..19cb000 --- /dev/null +++ b/tools/gcc/size_overflow_plugin/size_overflow_hash.data -@@ -0,0 +1,6034 @@ +@@ -0,0 +1,6035 @@ +intel_fake_agp_alloc_by_type_1 intel_fake_agp_alloc_by_type 1 1 NULL +ocfs2_get_refcount_tree_3 ocfs2_get_refcount_tree 0 3 NULL +storvsc_connect_to_vsp_22 storvsc_connect_to_vsp 2 22 NULL @@ -121784,6 +121582,7 @@ index 0000000..bbd5d8e +l2cap_skbuff_fromiovec_35003 l2cap_skbuff_fromiovec 4-3 35003 NULL +sisusb_copy_memory_35016 sisusb_copy_memory 4 35016 NULL +coda_psdev_read_35029 coda_psdev_read 3 35029 NULL ++proc_setgroups_write_35039 proc_setgroups_write 3 35039 NULL +xfs_rtallocate_extent_35052 xfs_rtallocate_extent 0 35052 NULL +pwr_connection_out_of_sync_read_35061 pwr_connection_out_of_sync_read 3 35061 NULL +ntfs_attr_extend_initialized_35084 ntfs_attr_extend_initialized 0 35084 NULL diff --git a/3.18.1/4425_grsec_remove_EI_PAX.patch b/3.14.28/4425_grsec_remove_EI_PAX.patch similarity index 100% rename from 3.18.1/4425_grsec_remove_EI_PAX.patch rename to 3.14.28/4425_grsec_remove_EI_PAX.patch diff --git a/3.14.27/4427_force_XATTR_PAX_tmpfs.patch b/3.14.28/4427_force_XATTR_PAX_tmpfs.patch similarity index 100% rename from 3.14.27/4427_force_XATTR_PAX_tmpfs.patch rename to 3.14.28/4427_force_XATTR_PAX_tmpfs.patch diff --git a/3.18.1/4430_grsec-remove-localversion-grsec.patch b/3.14.28/4430_grsec-remove-localversion-grsec.patch similarity index 100% rename from 3.18.1/4430_grsec-remove-localversion-grsec.patch rename to 3.14.28/4430_grsec-remove-localversion-grsec.patch diff --git a/3.14.27/4435_grsec-mute-warnings.patch b/3.14.28/4435_grsec-mute-warnings.patch similarity index 100% rename from 3.14.27/4435_grsec-mute-warnings.patch rename to 3.14.28/4435_grsec-mute-warnings.patch diff --git a/3.18.1/4440_grsec-remove-protected-paths.patch b/3.14.28/4440_grsec-remove-protected-paths.patch similarity index 100% rename from 3.18.1/4440_grsec-remove-protected-paths.patch rename to 3.14.28/4440_grsec-remove-protected-paths.patch diff --git a/3.14.27/4450_grsec-kconfig-default-gids.patch b/3.14.28/4450_grsec-kconfig-default-gids.patch similarity index 100% rename from 3.14.27/4450_grsec-kconfig-default-gids.patch rename to 3.14.28/4450_grsec-kconfig-default-gids.patch diff --git a/3.14.27/4465_selinux-avc_audit-log-curr_ip.patch b/3.14.28/4465_selinux-avc_audit-log-curr_ip.patch similarity index 100% rename from 3.14.27/4465_selinux-avc_audit-log-curr_ip.patch rename to 3.14.28/4465_selinux-avc_audit-log-curr_ip.patch diff --git a/3.14.27/4470_disable-compat_vdso.patch b/3.14.28/4470_disable-compat_vdso.patch similarity index 100% rename from 3.14.27/4470_disable-compat_vdso.patch rename to 3.14.28/4470_disable-compat_vdso.patch diff --git a/3.18.1/4475_emutramp_default_on.patch b/3.14.28/4475_emutramp_default_on.patch similarity index 100% rename from 3.18.1/4475_emutramp_default_on.patch rename to 3.14.28/4475_emutramp_default_on.patch diff --git a/3.18.1/0000_README b/3.18.2/0000_README similarity index 96% rename from 3.18.1/0000_README rename to 3.18.2/0000_README index dae7762..a8cc951 100644 --- a/3.18.1/0000_README +++ b/3.18.2/0000_README @@ -2,7 +2,7 @@ README ----------------------------------------------------------------------------- Individual Patch Descriptions: ----------------------------------------------------------------------------- -Patch: 4420_grsecurity-3.0-3.18.1-201501042021.patch +Patch: 4420_grsecurity-3.0-3.18.2-201501120821.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.18.1/4420_grsecurity-3.0-3.18.1-201501042021.patch b/3.18.2/4420_grsecurity-3.0-3.18.2-201501120821.patch similarity index 99% rename from 3.18.1/4420_grsecurity-3.0-3.18.1-201501042021.patch rename to 3.18.2/4420_grsecurity-3.0-3.18.2-201501120821.patch index 9090c69..7f13fdf 100644 --- a/3.18.1/4420_grsecurity-3.0-3.18.1-201501042021.patch +++ b/3.18.2/4420_grsecurity-3.0-3.18.2-201501120821.patch @@ -370,7 +370,7 @@ index 479f332..2475ac2 100644 pcd. [PARIDE] diff --git a/Makefile b/Makefile -index 3f84029..3c5b65e 100644 +index 8f73b41..320950a 100644 --- a/Makefile +++ b/Makefile @@ -298,7 +298,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ @@ -3525,7 +3525,7 @@ index 7f352de..6dc0929 100644 static int keystone_platform_notifier(struct notifier_block *nb, diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c -index 044b511..afd1da8 100644 +index c31f4c0..c86224d 100644 --- a/arch/arm/mach-mvebu/coherency.c +++ b/arch/arm/mach-mvebu/coherency.c @@ -316,7 +316,7 @@ static void __init armada_370_coherency_init(struct device_node *np) @@ -20565,24 +20565,6 @@ index d993e33..8db1b18 100644 #define BIOS_END 0x00100000 #define BIOS_ROM_BASE 0xffe00000 -diff --git a/arch/x86/include/uapi/asm/ldt.h b/arch/x86/include/uapi/asm/ldt.h -index 46727eb..6e1aaf7 100644 ---- a/arch/x86/include/uapi/asm/ldt.h -+++ b/arch/x86/include/uapi/asm/ldt.h -@@ -28,6 +28,13 @@ struct user_desc { - unsigned int seg_not_present:1; - unsigned int useable:1; - #ifdef __x86_64__ -+ /* -+ * Because this bit is not present in 32-bit user code, user -+ * programs can pass uninitialized values here. Therefore, in -+ * any context in which a user_desc comes from a 32-bit program, -+ * the kernel must act as though lm == 0, regardless of the -+ * actual value. -+ */ - unsigned int lm:1; - #endif - }; diff --git a/arch/x86/include/uapi/asm/ptrace-abi.h b/arch/x86/include/uapi/asm/ptrace-abi.h index 7b0a55a..ad115bf 100644 --- a/arch/x86/include/uapi/asm/ptrace-abi.h @@ -21651,10 +21633,10 @@ index 7dc5564..1273569 100644 wmb(); diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c -index 08fe6e8..35885b0 100644 +index 15c2909..2cef20c 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c -@@ -526,7 +526,7 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) +@@ -518,7 +518,7 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) return NOTIFY_OK; } @@ -25759,38 +25741,6 @@ index c2bedae..25e7ab60 100644 .attr = { .name = "data", .mode = S_IRUGO, -diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c -index f6945bef..94f6434 100644 ---- a/arch/x86/kernel/kvm.c -+++ b/arch/x86/kernel/kvm.c -@@ -283,7 +283,14 @@ NOKPROBE_SYMBOL(do_async_page_fault); - static void __init paravirt_ops_setup(void) - { - pv_info.name = "KVM"; -- pv_info.paravirt_enabled = 1; -+ -+ /* -+ * KVM isn't paravirt in the sense of paravirt_enabled. A KVM -+ * guest kernel works like a bare metal kernel with additional -+ * features, and paravirt_enabled is about features that are -+ * missing. -+ */ -+ pv_info.paravirt_enabled = 0; - - if (kvm_para_has_feature(KVM_FEATURE_NOP_IO_DELAY)) - pv_cpu_ops.io_delay = kvm_io_delay; -diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c -index d9156ce..a2de9bc 100644 ---- a/arch/x86/kernel/kvmclock.c -+++ b/arch/x86/kernel/kvmclock.c -@@ -263,7 +263,6 @@ void __init kvmclock_init(void) - #endif - kvm_get_preset_lpj(); - clocksource_register_hz(&kvm_clock, NSEC_PER_SEC); -- pv_info.paravirt_enabled = 1; - pv_info.name = "KVM"; - - if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE_STABLE_BIT)) diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index c37886d..d851d32 100644 --- a/arch/x86/kernel/ldt.c @@ -26714,7 +26664,7 @@ index 8f3ebfe..e6ced5a 100644 } - diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c -index 3ed4a68..ee8f337 100644 +index 5a2c029..a7f67d3 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -158,10 +158,11 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, @@ -26748,17 +26698,18 @@ index 3ed4a68..ee8f337 100644 unsigned fsindex, gsindex; fpu_switch_t fpu; -@@ -300,6 +303,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) +@@ -331,6 +334,10 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) if (unlikely(next->ds | prev->ds)) loadsegment(ds, next->ds); + savesegment(ss, prev->ss); + if (unlikely(next->ss != prev->ss)) + loadsegment(ss, next->ss); - - /* We must save %fs and %gs before load_TLS() because - * %fs and %gs may be cleared by load_TLS(). -@@ -359,6 +365,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) ++ + /* + * Switch FS and GS. + * +@@ -404,6 +411,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) prev->usersp = this_cpu_read(old_rsp); this_cpu_write(old_rsp, next->usersp); this_cpu_write(current_task, next_p); @@ -26766,7 +26717,7 @@ index 3ed4a68..ee8f337 100644 /* * If it were not for PREEMPT_ACTIVE we could guarantee that the -@@ -368,9 +375,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) +@@ -413,9 +421,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) task_thread_info(prev_p)->saved_preempt_count = this_cpu_read(__preempt_count); this_cpu_write(__preempt_count, task_thread_info(next_p)->saved_preempt_count); @@ -26777,7 +26728,7 @@ index 3ed4a68..ee8f337 100644 /* * Now maybe reload the debug registers and handle I/O bitmaps -@@ -440,12 +445,11 @@ unsigned long get_wchan(struct task_struct *p) +@@ -485,12 +491,11 @@ unsigned long get_wchan(struct task_struct *p) if (!p || p == current || p->state == TASK_RUNNING) return 0; stack = (unsigned long)task_stack_page(p); @@ -27863,58 +27814,10 @@ index 0fa2960..91eabbe 100644 return pc; } diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c -index f7fec09..d0f623f 100644 +index 4e942f3..d0f623f 100644 --- a/arch/x86/kernel/tls.c +++ b/arch/x86/kernel/tls.c -@@ -27,6 +27,37 @@ static int get_free_idx(void) - return -ESRCH; - } - -+static bool tls_desc_okay(const struct user_desc *info) -+{ -+ if (LDT_empty(info)) -+ return true; -+ -+ /* -+ * espfix is required for 16-bit data segments, but espfix -+ * only works for LDT segments. -+ */ -+ if (!info->seg_32bit) -+ return false; -+ -+ /* Only allow data segments in the TLS array. */ -+ if (info->contents > 1) -+ return false; -+ -+ /* -+ * Non-present segments with DPL 3 present an interesting attack -+ * surface. The kernel should handle such segments correctly, -+ * but TLS is very difficult to protect in a sandbox, so prevent -+ * such segments from being created. -+ * -+ * If userspace needs to remove a TLS entry, it can still delete -+ * it outright. -+ */ -+ if (info->seg_not_present) -+ return false; -+ -+ return true; -+} -+ - static void set_tls_desc(struct task_struct *p, int idx, - const struct user_desc *info, int n) - { -@@ -66,6 +97,9 @@ int do_set_thread_area(struct task_struct *p, int idx, - if (copy_from_user(&info, u_info, sizeof(info))) - return -EFAULT; - -+ if (!tls_desc_okay(&info)) -+ return -EINVAL; -+ - if (idx == -1) - idx = info.entry_number; - -@@ -84,6 +118,11 @@ int do_set_thread_area(struct task_struct *p, int idx, +@@ -118,6 +118,11 @@ int do_set_thread_area(struct task_struct *p, int idx, if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) return -EINVAL; @@ -27926,15 +27829,7 @@ index f7fec09..d0f623f 100644 set_tls_desc(p, idx, &info, 1); return 0; -@@ -192,6 +231,7 @@ int regset_tls_set(struct task_struct *target, const struct user_regset *regset, - { - struct user_desc infobuf[GDT_ENTRY_TLS_ENTRIES]; - const struct user_desc *info; -+ int i; - - if (pos >= GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) || - (pos % sizeof(struct user_desc)) != 0 || -@@ -200,11 +240,15 @@ int regset_tls_set(struct task_struct *target, const struct user_regset *regset, +@@ -235,7 +240,7 @@ int regset_tls_set(struct task_struct *target, const struct user_regset *regset, if (kbuf) info = kbuf; @@ -27943,14 +27838,6 @@ index f7fec09..d0f623f 100644 return -EFAULT; else info = infobuf; - -+ for (i = 0; i < count / sizeof(struct user_desc); i++) -+ if (!tls_desc_okay(info + i)) -+ return -EINVAL; -+ - set_tls_desc(target, - GDT_ENTRY_TLS_MIN + (pos / sizeof(struct user_desc)), - info, count / sizeof(struct user_desc)); diff --git a/arch/x86/kernel/tracepoint.c b/arch/x86/kernel/tracepoint.c index 1c113db..287b42e 100644 --- a/arch/x86/kernel/tracepoint.c @@ -27970,7 +27857,7 @@ index 1c113db..287b42e 100644 static int trace_irq_vector_refcount; static DEFINE_MUTEX(irq_vector_mutex); diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c -index de801f2..4a4c4af 100644 +index 07ab8e9..99c8456 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -67,7 +67,7 @@ @@ -28132,8 +28019,8 @@ index de801f2..4a4c4af 100644 + BUG_ON(!user_mode(&new_stack->regs)); return new_stack; } - #endif -@@ -518,7 +562,7 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code) + NOKPROBE_SYMBOL(fixup_bad_iret); +@@ -519,7 +563,7 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code) /* It's safe to allow irq's after DR6 has been saved */ preempt_conditional_sti(regs); @@ -28142,7 +28029,7 @@ index de801f2..4a4c4af 100644 handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, X86_TRAP_DB); preempt_conditional_cli(regs); -@@ -533,7 +577,7 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code) +@@ -534,7 +578,7 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code) * We already checked v86 mode above, so we can check for kernel mode * by just checking the CPL of CS. */ @@ -28151,7 +28038,7 @@ index de801f2..4a4c4af 100644 tsk->thread.debugreg6 &= ~DR_STEP; set_tsk_thread_flag(tsk, TIF_SINGLESTEP); regs->flags &= ~X86_EFLAGS_TF; -@@ -566,7 +610,7 @@ static void math_error(struct pt_regs *regs, int error_code, int trapnr) +@@ -567,7 +611,7 @@ static void math_error(struct pt_regs *regs, int error_code, int trapnr) return; conditional_sti(regs); @@ -43701,7 +43588,7 @@ index c9a02fe..0debc75 100644 INIT_LIST_HEAD(&serio_raw->client_list); init_waitqueue_head(&serio_raw->wait); diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c -index 505a9ad..f0b1b6e 100644 +index 505a9ad..356734c 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -823,11 +823,21 @@ static void copy_cmd_to_buffer(struct amd_iommu *iommu, @@ -43716,7 +43603,7 @@ index 505a9ad..f0b1b6e 100644 - cmd->data[1] = upper_32_bits(__pa(address)); + +#ifdef CONFIG_GRKERNSEC_KSTACKOVERFLOW -+ if (object_starts_on_stack(address)) { ++ if (object_starts_on_stack((void *)address)) { + void *adjbuf = (void *)address - current->stack + current->lowmem_stack; + physaddr = __pa((u64)adjbuf); + } else @@ -44786,10 +44673,10 @@ index 03cec5b..0a658c1 100644 struct md_personality diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/md/persistent-data/dm-space-map-metadata.c -index 786b689..ea8c956 100644 +index f4e22bc..8f83114 100644 --- a/drivers/md/persistent-data/dm-space-map-metadata.c +++ b/drivers/md/persistent-data/dm-space-map-metadata.c -@@ -679,7 +679,7 @@ static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks) +@@ -681,7 +681,7 @@ static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks) * Flick into a mode where all blocks get allocated in the new area. */ smm->begin = old_len; @@ -44798,7 +44685,7 @@ index 786b689..ea8c956 100644 /* * Extend. -@@ -710,7 +710,7 @@ out: +@@ -712,7 +712,7 @@ out: /* * Switch back to normal behaviour. */ @@ -46991,7 +46878,7 @@ index 82dc574..8539ab2 100644 break; diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c -index 1fa4c80..59447c9 100644 +index a11451f..9e1bbad 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -574,7 +574,7 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, @@ -47043,10 +46930,10 @@ index 43af791..86f4c48 100644 mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; mmc->max_busy_timeout = 0; diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c -index df27bb4..2085f0b 100644 +index 9c2b9cb..cebb09a 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c -@@ -2111,7 +2111,9 @@ static int omap_hsmmc_probe(struct platform_device *pdev) +@@ -2113,7 +2113,9 @@ static int omap_hsmmc_probe(struct platform_device *pdev) if (host->pdata->controller_flags & OMAP_HSMMC_BROKEN_MULTIBLOCK_READ) { dev_info(&pdev->dev, "multiblock reads disabled due to 35xx erratum 2.1.1.128; MMC read performance may suffer\n"); @@ -59358,7 +59245,7 @@ index 4399f0c..a34d8b4 100644 up_read(&info->groups_sem); } diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c -index 54bd91e..aefa810 100644 +index cde9c03..ad4d4db 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -271,7 +271,7 @@ void __btrfs_abort_transaction(struct btrfs_trans_handle *trans, @@ -60440,7 +60327,7 @@ index b5c86ff..0dac262 100644 return 0; while (nr) { diff --git a/fs/dcache.c b/fs/dcache.c -index 71acf8d..815e743 100644 +index 03dca3c..f66c622 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -508,7 +508,7 @@ static void __dentry_kill(struct dentry *dentry) @@ -60594,7 +60481,7 @@ index 71acf8d..815e743 100644 if (!spin_trylock(&inode->i_lock)) { spin_unlock(&dentry->d_lock); cpu_relax(); -@@ -3306,7 +3306,7 @@ static enum d_walk_ret d_genocide_kill(void *data, struct dentry *dentry) +@@ -3308,7 +3308,7 @@ static enum d_walk_ret d_genocide_kill(void *data, struct dentry *dentry) if (!(dentry->d_flags & DCACHE_GENOCIDE)) { dentry->d_flags |= DCACHE_GENOCIDE; @@ -60603,7 +60490,7 @@ index 71acf8d..815e743 100644 } } return D_WALK_CONTINUE; -@@ -3422,7 +3422,8 @@ void __init vfs_caches_init(unsigned long mempages) +@@ -3424,7 +3424,8 @@ void __init vfs_caches_init(unsigned long mempages) mempages -= reserve; names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0, @@ -63560,47 +63447,6 @@ index 26753ba..d19eb34 100644 put_cpu_var(last_ino); return res; } -diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c -index f488bba..735d752 100644 ---- a/fs/isofs/rock.c -+++ b/fs/isofs/rock.c -@@ -30,6 +30,7 @@ struct rock_state { - int cont_size; - int cont_extent; - int cont_offset; -+ int cont_loops; - struct inode *inode; - }; - -@@ -73,6 +74,9 @@ static void init_rock_state(struct rock_state *rs, struct inode *inode) - rs->inode = inode; - } - -+/* Maximum number of Rock Ridge continuation entries */ -+#define RR_MAX_CE_ENTRIES 32 -+ - /* - * Returns 0 if the caller should continue scanning, 1 if the scan must end - * and -ve on error. -@@ -105,6 +109,8 @@ static int rock_continue(struct rock_state *rs) - goto out; - } - ret = -EIO; -+ if (++rs->cont_loops >= RR_MAX_CE_ENTRIES) -+ goto out; - bh = sb_bread(rs->inode->i_sb, rs->cont_extent); - if (bh) { - memcpy(rs->buffer, bh->b_data + rs->cont_offset, -@@ -356,6 +362,9 @@ repeat: - rs.cont_size = isonum_733(rr->u.CE.size); - break; - case SIG('E', 'R'): -+ /* Invalid length of ER tag id? */ -+ if (rr->u.ER.len_id + offsetof(struct rock_ridge, u.ER.data) > rr->len) -+ goto out; - ISOFS_SB(inode->i_sb)->s_rock = 1; - printk(KERN_DEBUG "ISO 9660 Extensions: "); - { diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c index 4a6cf28..d3a29d3 100644 --- a/fs/jffs2/erase.c @@ -63643,7 +63489,7 @@ index 93e897e..a863de4 100644 if (jfs_inode_cachep == NULL) return -ENOMEM; diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c -index 1c77193..5cfb7b57 100644 +index 1c77193..ba73e66 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -182,7 +182,7 @@ struct kernfs_node *kernfs_get_parent(struct kernfs_node *kn) @@ -63655,13 +63501,15 @@ index 1c77193..5cfb7b57 100644 { unsigned long hash = init_name_hash(); unsigned int len = strlen(name); -@@ -829,6 +829,10 @@ static int kernfs_iop_mkdir(struct inode *dir, struct dentry *dentry, +@@ -829,6 +829,12 @@ static int kernfs_iop_mkdir(struct inode *dir, struct dentry *dentry, ret = scops->mkdir(parent, dentry->d_name.name, mode); kernfs_put_active(parent); + -+ if (!ret) -+ ret = kernfs_iop_lookup(dir, dentry, 0); ++ if (!ret) { ++ struct dentry *dentry_ret = kernfs_iop_lookup(dir, dentry, 0); ++ ret = PTR_ERR_OR_ZERO(dentry_ret); ++ } + return ret; } @@ -64402,19 +64250,10 @@ index db5fe86..d3dcc14 100644 out: return len; diff --git a/fs/namespace.c b/fs/namespace.c -index 5b66b2b..4d8290d 100644 +index bbde147..f4deeba 100644 --- a/fs/namespace.c +++ b/fs/namespace.c -@@ -1369,6 +1369,8 @@ void umount_tree(struct mount *mnt, int how) - } - if (last) { - last->mnt_hash.next = unmounted.first; -+ if (unmounted.first) -+ unmounted.first->pprev = &last->mnt_hash.next; - unmounted.first = tmp_list.first; - unmounted.first->pprev = &unmounted.first; - } -@@ -1445,6 +1447,9 @@ static int do_umount(struct mount *mnt, int flags) +@@ -1447,6 +1447,9 @@ static int do_umount(struct mount *mnt, int flags) if (!(sb->s_flags & MS_RDONLY)) retval = do_remount_sb(sb, MS_RDONLY, NULL, 0); up_write(&sb->s_umount); @@ -64424,7 +64263,7 @@ index 5b66b2b..4d8290d 100644 return retval; } -@@ -1467,6 +1472,9 @@ static int do_umount(struct mount *mnt, int flags) +@@ -1469,6 +1472,9 @@ static int do_umount(struct mount *mnt, int flags) } unlock_mount_hash(); namespace_unlock(); @@ -64434,7 +64273,7 @@ index 5b66b2b..4d8290d 100644 return retval; } -@@ -1517,7 +1525,7 @@ static inline bool may_mount(void) +@@ -1519,7 +1525,7 @@ static inline bool may_mount(void) * unixes. Our API is identical to OSF/1 to avoid making a mess of AMD */ @@ -64443,7 +64282,7 @@ index 5b66b2b..4d8290d 100644 { struct path path; struct mount *mnt; -@@ -1559,7 +1567,7 @@ out: +@@ -1564,7 +1570,7 @@ out: /* * The 2.0 compatible umount. No flags. */ @@ -64452,7 +64291,7 @@ index 5b66b2b..4d8290d 100644 { return sys_umount(name, 0); } -@@ -2621,6 +2629,16 @@ long do_mount(const char *dev_name, const char __user *dir_name, +@@ -2632,6 +2638,16 @@ long do_mount(const char *dev_name, const char __user *dir_name, MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT | MS_STRICTATIME); @@ -64469,7 +64308,7 @@ index 5b66b2b..4d8290d 100644 if (flags & MS_REMOUNT) retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags, data_page); -@@ -2634,7 +2652,10 @@ long do_mount(const char *dev_name, const char __user *dir_name, +@@ -2645,7 +2661,10 @@ long do_mount(const char *dev_name, const char __user *dir_name, retval = do_new_mount(&path, type_page, flags, mnt_flags, dev_name, data_page); dput_out: @@ -64480,7 +64319,7 @@ index 5b66b2b..4d8290d 100644 return retval; } -@@ -2652,7 +2673,7 @@ static void free_mnt_ns(struct mnt_namespace *ns) +@@ -2663,7 +2682,7 @@ static void free_mnt_ns(struct mnt_namespace *ns) * number incrementing at 10Ghz will take 12,427 years to wrap which * is effectively never, so we can ignore the possibility. */ @@ -64489,7 +64328,7 @@ index 5b66b2b..4d8290d 100644 static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns) { -@@ -2667,7 +2688,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns) +@@ -2678,7 +2697,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns) kfree(new_ns); return ERR_PTR(ret); } @@ -64498,7 +64337,7 @@ index 5b66b2b..4d8290d 100644 atomic_set(&new_ns->count, 1); new_ns->root = NULL; INIT_LIST_HEAD(&new_ns->list); -@@ -2677,7 +2698,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns) +@@ -2688,7 +2707,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns) return new_ns; } @@ -64507,7 +64346,7 @@ index 5b66b2b..4d8290d 100644 struct user_namespace *user_ns, struct fs_struct *new_fs) { struct mnt_namespace *new_ns; -@@ -2798,8 +2819,8 @@ struct dentry *mount_subtree(struct vfsmount *mnt, const char *name) +@@ -2809,8 +2828,8 @@ struct dentry *mount_subtree(struct vfsmount *mnt, const char *name) } EXPORT_SYMBOL(mount_subtree); @@ -64518,7 +64357,7 @@ index 5b66b2b..4d8290d 100644 { int ret; char *kernel_type; -@@ -2905,6 +2926,11 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, +@@ -2916,6 +2935,11 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, if (error) goto out2; @@ -64530,7 +64369,7 @@ index 5b66b2b..4d8290d 100644 get_fs_root(current->fs, &root); old_mp = lock_mount(&old); error = PTR_ERR(old_mp); -@@ -3176,7 +3202,7 @@ static int mntns_install(struct nsproxy *nsproxy, void *ns) +@@ -3187,7 +3211,7 @@ static int mntns_install(struct nsproxy *nsproxy, void *ns) !ns_capable(current_user_ns(), CAP_SYS_ADMIN)) return -EPERM; @@ -65602,7 +65441,7 @@ index cd3653e..9b9b79a 100644 static struct pid * get_children_pid(struct inode *inode, struct pid *pid_prev, loff_t pos) diff --git a/fs/proc/base.c b/fs/proc/base.c -index 772efa4..e7f1a5c 100644 +index 7dc3ea8..4cfe92f 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -113,6 +113,14 @@ struct pid_entry { @@ -65919,7 +65758,7 @@ index 772efa4..e7f1a5c 100644 if (!dir_emit_dots(file, ctx)) goto out; -@@ -2506,7 +2625,7 @@ static const struct pid_entry tgid_base_stuff[] = { +@@ -2557,7 +2676,7 @@ static const struct pid_entry tgid_base_stuff[] = { REG("autogroup", S_IRUGO|S_IWUSR, proc_pid_sched_autogroup_operations), #endif REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations), @@ -65928,7 +65767,7 @@ index 772efa4..e7f1a5c 100644 ONE("syscall", S_IRUSR, proc_pid_syscall), #endif ONE("cmdline", S_IRUGO, proc_pid_cmdline), -@@ -2531,10 +2650,10 @@ static const struct pid_entry tgid_base_stuff[] = { +@@ -2582,10 +2701,10 @@ static const struct pid_entry tgid_base_stuff[] = { #ifdef CONFIG_SECURITY DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations), #endif @@ -65941,7 +65780,7 @@ index 772efa4..e7f1a5c 100644 ONE("stack", S_IRUSR, proc_pid_stack), #endif #ifdef CONFIG_SCHEDSTATS -@@ -2568,6 +2687,9 @@ static const struct pid_entry tgid_base_stuff[] = { +@@ -2619,6 +2738,9 @@ static const struct pid_entry tgid_base_stuff[] = { #ifdef CONFIG_HARDWALL ONE("hardwall", S_IRUGO, proc_pid_hardwall), #endif @@ -65951,7 +65790,7 @@ index 772efa4..e7f1a5c 100644 #ifdef CONFIG_USER_NS REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations), REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), -@@ -2696,7 +2818,14 @@ static int proc_pid_instantiate(struct inode *dir, +@@ -2748,7 +2870,14 @@ static int proc_pid_instantiate(struct inode *dir, if (!inode) goto out; @@ -65966,7 +65805,7 @@ index 772efa4..e7f1a5c 100644 inode->i_op = &proc_tgid_base_inode_operations; inode->i_fop = &proc_tgid_base_operations; inode->i_flags|=S_IMMUTABLE; -@@ -2734,7 +2863,11 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsign +@@ -2786,7 +2915,11 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsign if (!task) goto out; @@ -65978,7 +65817,7 @@ index 772efa4..e7f1a5c 100644 put_task_struct(task); out: return ERR_PTR(result); -@@ -2848,7 +2981,7 @@ static const struct pid_entry tid_base_stuff[] = { +@@ -2900,7 +3033,7 @@ static const struct pid_entry tid_base_stuff[] = { REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), #endif REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations), @@ -65987,7 +65826,7 @@ index 772efa4..e7f1a5c 100644 ONE("syscall", S_IRUSR, proc_pid_syscall), #endif ONE("cmdline", S_IRUGO, proc_pid_cmdline), -@@ -2875,10 +3008,10 @@ static const struct pid_entry tid_base_stuff[] = { +@@ -2927,10 +3060,10 @@ static const struct pid_entry tid_base_stuff[] = { #ifdef CONFIG_SECURITY DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations), #endif @@ -67714,45 +67553,6 @@ index fb08b0c..65fcc7e 100644 { int err; -diff --git a/fs/udf/dir.c b/fs/udf/dir.c -index a012c51..a7690b4 100644 ---- a/fs/udf/dir.c -+++ b/fs/udf/dir.c -@@ -167,7 +167,8 @@ static int udf_readdir(struct file *file, struct dir_context *ctx) - continue; - } - -- flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi); -+ flen = udf_get_filename(dir->i_sb, nameptr, lfi, fname, -+ UDF_NAME_LEN); - if (!flen) - continue; - -diff --git a/fs/udf/inode.c b/fs/udf/inode.c -index c9b4df5..5bc71d9 100644 ---- a/fs/udf/inode.c -+++ b/fs/udf/inode.c -@@ -1489,6 +1489,20 @@ reread: - } - inode->i_generation = iinfo->i_unique; - -+ /* Sanity checks for files in ICB so that we don't get confused later */ -+ if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { -+ /* -+ * For file in ICB data is stored in allocation descriptor -+ * so sizes should match -+ */ -+ if (iinfo->i_lenAlloc != inode->i_size) -+ goto out; -+ /* File in ICB has to fit in there... */ -+ if (inode->i_size > inode->i_sb->s_blocksize - -+ udf_file_entry_alloc_offset(inode)) -+ goto out; -+ } -+ - switch (fe->icbTag.fileType) { - case ICBTAG_FILE_TYPE_DIRECTORY: - inode->i_op = &udf_dir_inode_operations; diff --git a/fs/udf/misc.c b/fs/udf/misc.c index c175b4d..8f36a16 100644 --- a/fs/udf/misc.c @@ -67766,257 +67566,6 @@ index c175b4d..8f36a16 100644 u8 checksum = 0; int i; for (i = 0; i < sizeof(struct tag); ++i) -diff --git a/fs/udf/namei.c b/fs/udf/namei.c -index c12e260..6ff19b5 100644 ---- a/fs/udf/namei.c -+++ b/fs/udf/namei.c -@@ -233,7 +233,8 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, - if (!lfi) - continue; - -- flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi); -+ flen = udf_get_filename(dir->i_sb, nameptr, lfi, fname, -+ UDF_NAME_LEN); - if (flen && udf_match(flen, fname, child->len, child->name)) - goto out_ok; - } -diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c -index 6fb7945..ac10ca9 100644 ---- a/fs/udf/symlink.c -+++ b/fs/udf/symlink.c -@@ -30,49 +30,73 @@ - #include <linux/buffer_head.h> - #include "udf_i.h" - --static void udf_pc_to_char(struct super_block *sb, unsigned char *from, -- int fromlen, unsigned char *to) -+static int udf_pc_to_char(struct super_block *sb, unsigned char *from, -+ int fromlen, unsigned char *to, int tolen) - { - struct pathComponent *pc; - int elen = 0; -+ int comp_len; - unsigned char *p = to; - -+ /* Reserve one byte for terminating \0 */ -+ tolen--; - while (elen < fromlen) { - pc = (struct pathComponent *)(from + elen); -+ elen += sizeof(struct pathComponent); - switch (pc->componentType) { - case 1: - /* - * Symlink points to some place which should be agreed - * upon between originator and receiver of the media. Ignore. - */ -- if (pc->lengthComponentIdent > 0) -+ if (pc->lengthComponentIdent > 0) { -+ elen += pc->lengthComponentIdent; - break; -+ } - /* Fall through */ - case 2: -+ if (tolen == 0) -+ return -ENAMETOOLONG; - p = to; - *p++ = '/'; -+ tolen--; - break; - case 3: -+ if (tolen < 3) -+ return -ENAMETOOLONG; - memcpy(p, "../", 3); - p += 3; -+ tolen -= 3; - break; - case 4: -+ if (tolen < 2) -+ return -ENAMETOOLONG; - memcpy(p, "./", 2); - p += 2; -+ tolen -= 2; - /* that would be . - just ignore */ - break; - case 5: -- p += udf_get_filename(sb, pc->componentIdent, p, -- pc->lengthComponentIdent); -+ elen += pc->lengthComponentIdent; -+ if (elen > fromlen) -+ return -EIO; -+ comp_len = udf_get_filename(sb, pc->componentIdent, -+ pc->lengthComponentIdent, -+ p, tolen); -+ p += comp_len; -+ tolen -= comp_len; -+ if (tolen == 0) -+ return -ENAMETOOLONG; - *p++ = '/'; -+ tolen--; - break; - } -- elen += sizeof(struct pathComponent) + pc->lengthComponentIdent; - } - if (p > to + 1) - p[-1] = '\0'; - else - p[0] = '\0'; -+ return 0; - } - - static int udf_symlink_filler(struct file *file, struct page *page) -@@ -80,11 +104,17 @@ static int udf_symlink_filler(struct file *file, struct page *page) - struct inode *inode = page->mapping->host; - struct buffer_head *bh = NULL; - unsigned char *symlink; -- int err = -EIO; -+ int err; - unsigned char *p = kmap(page); - struct udf_inode_info *iinfo; - uint32_t pos; - -+ /* We don't support symlinks longer than one block */ -+ if (inode->i_size > inode->i_sb->s_blocksize) { -+ err = -ENAMETOOLONG; -+ goto out_unmap; -+ } -+ - iinfo = UDF_I(inode); - pos = udf_block_map(inode, 0); - -@@ -94,14 +124,18 @@ static int udf_symlink_filler(struct file *file, struct page *page) - } else { - bh = sb_bread(inode->i_sb, pos); - -- if (!bh) -- goto out; -+ if (!bh) { -+ err = -EIO; -+ goto out_unlock_inode; -+ } - - symlink = bh->b_data; - } - -- udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p); -+ err = udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p, PAGE_SIZE); - brelse(bh); -+ if (err) -+ goto out_unlock_inode; - - up_read(&iinfo->i_data_sem); - SetPageUptodate(page); -@@ -109,9 +143,10 @@ static int udf_symlink_filler(struct file *file, struct page *page) - unlock_page(page); - return 0; - --out: -+out_unlock_inode: - up_read(&iinfo->i_data_sem); - SetPageError(page); -+out_unmap: - kunmap(page); - unlock_page(page); - return err; -diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h -index 1cc3c99..47bb3f5 100644 ---- a/fs/udf/udfdecl.h -+++ b/fs/udf/udfdecl.h -@@ -211,7 +211,8 @@ udf_get_lb_pblock(struct super_block *sb, struct kernel_lb_addr *loc, - } - - /* unicode.c */ --extern int udf_get_filename(struct super_block *, uint8_t *, uint8_t *, int); -+extern int udf_get_filename(struct super_block *, uint8_t *, int, uint8_t *, -+ int); - extern int udf_put_filename(struct super_block *, const uint8_t *, uint8_t *, - int); - extern int udf_build_ustr(struct ustr *, dstring *, int); -diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c -index afd470e..b84fee3 100644 ---- a/fs/udf/unicode.c -+++ b/fs/udf/unicode.c -@@ -28,7 +28,8 @@ - - #include "udf_sb.h" - --static int udf_translate_to_linux(uint8_t *, uint8_t *, int, uint8_t *, int); -+static int udf_translate_to_linux(uint8_t *, int, uint8_t *, int, uint8_t *, -+ int); - - static int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen) - { -@@ -333,8 +334,8 @@ try_again: - return u_len + 1; - } - --int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname, -- int flen) -+int udf_get_filename(struct super_block *sb, uint8_t *sname, int slen, -+ uint8_t *dname, int dlen) - { - struct ustr *filename, *unifilename; - int len = 0; -@@ -347,7 +348,7 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname, - if (!unifilename) - goto out1; - -- if (udf_build_ustr_exact(unifilename, sname, flen)) -+ if (udf_build_ustr_exact(unifilename, sname, slen)) - goto out2; - - if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) { -@@ -366,7 +367,8 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname, - } else - goto out2; - -- len = udf_translate_to_linux(dname, filename->u_name, filename->u_len, -+ len = udf_translate_to_linux(dname, dlen, -+ filename->u_name, filename->u_len, - unifilename->u_name, unifilename->u_len); - out2: - kfree(unifilename); -@@ -403,10 +405,12 @@ int udf_put_filename(struct super_block *sb, const uint8_t *sname, - #define EXT_MARK '.' - #define CRC_MARK '#' - #define EXT_SIZE 5 -+/* Number of chars we need to store generated CRC to make filename unique */ -+#define CRC_LEN 5 - --static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, -- int udfLen, uint8_t *fidName, -- int fidNameLen) -+static int udf_translate_to_linux(uint8_t *newName, int newLen, -+ uint8_t *udfName, int udfLen, -+ uint8_t *fidName, int fidNameLen) - { - int index, newIndex = 0, needsCRC = 0; - int extIndex = 0, newExtIndex = 0, hasExt = 0; -@@ -439,7 +443,7 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, - newExtIndex = newIndex; - } - } -- if (newIndex < 256) -+ if (newIndex < newLen) - newName[newIndex++] = curr; - else - needsCRC = 1; -@@ -467,13 +471,13 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, - } - ext[localExtIndex++] = curr; - } -- maxFilenameLen = 250 - localExtIndex; -+ maxFilenameLen = newLen - CRC_LEN - localExtIndex; - if (newIndex > maxFilenameLen) - newIndex = maxFilenameLen; - else - newIndex = newExtIndex; -- } else if (newIndex > 250) -- newIndex = 250; -+ } else if (newIndex > newLen - CRC_LEN) -+ newIndex = newLen - CRC_LEN; - newName[newIndex++] = CRC_MARK; - valueCRC = crc_itu_t(0, fidName, fidNameLen); - newName[newIndex++] = hex_asc_upper_hi(valueCRC >> 8); diff --git a/fs/ufs/swab.h b/fs/ufs/swab.h index 8d974c4..b82f6ec 100644 --- a/fs/ufs/swab.h @@ -80183,10 +79732,10 @@ index c1da539..1dcec55 100644 struct atmphy_ops { int (*start)(struct atm_dev *dev); diff --git a/include/linux/audit.h b/include/linux/audit.h -index e58fe7d..be9f6d8 100644 +index 10f155b..6c73ffe 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h -@@ -215,7 +215,7 @@ static inline void audit_ptrace(struct task_struct *t) +@@ -219,7 +219,7 @@ static inline void audit_ptrace(struct task_struct *t) extern unsigned int audit_serial(void); extern int auditsc_get_stamp(struct audit_context *ctx, struct timespec *t, unsigned int *serial); @@ -80687,7 +80236,7 @@ index 0a9a6da..ea597ca 100644 int cpumask_set_cpu_local_first(int i, int numa_node, cpumask_t *dstp); diff --git a/include/linux/cred.h b/include/linux/cred.h -index b2d0820..2ecafd3 100644 +index 2fb2ca2..d6a3340 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h @@ -35,7 +35,7 @@ struct group_info { @@ -80699,7 +80248,7 @@ index b2d0820..2ecafd3 100644 /** * get_group_info - Get a reference to a group info structure -@@ -136,7 +136,7 @@ struct cred { +@@ -137,7 +137,7 @@ struct cred { struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */ struct group_info *group_info; /* supplementary groups for euid/fsgid */ struct rcu_head rcu; /* RCU deletion hook */ @@ -80708,7 +80257,7 @@ index b2d0820..2ecafd3 100644 extern void __put_cred(struct cred *); extern void exit_creds(struct task_struct *); -@@ -194,6 +194,9 @@ static inline void validate_creds_for_do_exit(struct task_struct *tsk) +@@ -195,6 +195,9 @@ static inline void validate_creds_for_do_exit(struct task_struct *tsk) static inline void validate_process_creds(void) { } @@ -80718,7 +80267,7 @@ index b2d0820..2ecafd3 100644 #endif /** -@@ -331,6 +334,7 @@ static inline void put_cred(const struct cred *_cred) +@@ -332,6 +335,7 @@ static inline void put_cred(const struct cred *_cred) #define task_uid(task) (task_cred_xxx((task), uid)) #define task_euid(task) (task_cred_xxx((task), euid)) @@ -85787,10 +85336,10 @@ index d5952bb..9a626d4 100644 /* * callback functions for platform diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h -index e953726..8edb26a 100644 +index 9f3579f..3b2afa5 100644 --- a/include/linux/user_namespace.h +++ b/include/linux/user_namespace.h -@@ -33,7 +33,7 @@ struct user_namespace { +@@ -38,7 +38,7 @@ struct user_namespace { struct key *persistent_keyring_register; struct rw_semaphore persistent_keyring_register_sem; #endif @@ -88015,7 +87564,7 @@ index 88adc32..3867c68 100644 if ((requested_mode & ~granted_mode & 0007) && !ns_capable(ns->user_ns, CAP_IPC_OWNER)) diff --git a/kernel/audit.c b/kernel/audit.c -index cebb11d..4e0295f 100644 +index c6df990..fde80b4 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -122,7 +122,7 @@ u32 audit_sig_sid = 0; @@ -91130,7 +90679,7 @@ index cf80672..f6771b2 100644 } EXPORT_SYMBOL(__stack_chk_fail); diff --git a/kernel/pid.c b/kernel/pid.c -index 9b9a266..c20ef80 100644 +index 82430c8..53d7793 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -33,6 +33,7 @@ @@ -91150,7 +90699,7 @@ index 9b9a266..c20ef80 100644 int pid_max_min = RESERVED_PIDS + 1; int pid_max_max = PID_MAX_LIMIT; -@@ -445,10 +446,18 @@ EXPORT_SYMBOL(pid_task); +@@ -447,10 +448,18 @@ EXPORT_SYMBOL(pid_task); */ struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns) { @@ -91170,7 +90719,7 @@ index 9b9a266..c20ef80 100644 } struct task_struct *find_task_by_vpid(pid_t vnr) -@@ -456,6 +465,14 @@ struct task_struct *find_task_by_vpid(pid_t vnr) +@@ -458,6 +467,14 @@ struct task_struct *find_task_by_vpid(pid_t vnr) return find_task_by_pid_ns(vnr, task_active_pid_ns(current)); } @@ -94285,10 +93834,10 @@ index 29228c4..301bc8c 100644 mutex_lock(&syscall_trace_lock); sys_perf_refcount_exit--; diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c -index aa312b0..395f343 100644 +index a2e37c5..4fa859b 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c -@@ -82,6 +82,21 @@ int create_user_ns(struct cred *new) +@@ -83,6 +83,21 @@ int create_user_ns(struct cred *new) !kgid_has_mapping(parent_ns, group)) return -EPERM; @@ -94310,7 +93859,7 @@ index aa312b0..395f343 100644 ns = kmem_cache_zalloc(user_ns_cachep, GFP_KERNEL); if (!ns) return -ENOMEM; -@@ -872,7 +887,7 @@ static int userns_install(struct nsproxy *nsproxy, void *ns) +@@ -974,7 +989,7 @@ static int userns_install(struct nsproxy *nsproxy, void *ns) if (atomic_read(¤t->mm->mm_users) > 1) return -EINVAL; @@ -104292,10 +103841,10 @@ index 8c68da3..0695016 100644 /* number of interfaces with corresponding FIF_ flags */ int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll, diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c -index 653f5eb..02994ee 100644 +index eeae0ab..0f24585 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c -@@ -532,7 +532,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) +@@ -533,7 +533,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) break; } @@ -104304,7 +103853,7 @@ index 653f5eb..02994ee 100644 res = drv_start(local); if (res) goto err_del_bss; -@@ -579,7 +579,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) +@@ -580,7 +580,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) res = drv_add_interface(local, sdata); if (res) goto err_stop; @@ -104313,7 +103862,7 @@ index 653f5eb..02994ee 100644 res = ieee80211_add_virtual_monitor(local); if (res) goto err_stop; -@@ -688,7 +688,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) +@@ -689,7 +689,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) atomic_inc(&local->iff_promiscs); if (coming_up) @@ -104322,7 +103871,7 @@ index 653f5eb..02994ee 100644 if (hw_reconf_flags) ieee80211_hw_config(local, hw_reconf_flags); -@@ -726,7 +726,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) +@@ -727,7 +727,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) err_del_interface: drv_remove_interface(local, sdata); err_stop: @@ -104331,7 +103880,7 @@ index 653f5eb..02994ee 100644 drv_stop(local); err_del_bss: sdata->bss = NULL; -@@ -892,7 +892,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, +@@ -893,7 +893,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, } if (going_down) @@ -104340,7 +103889,7 @@ index 653f5eb..02994ee 100644 switch (sdata->vif.type) { case NL80211_IFTYPE_AP_VLAN: -@@ -954,7 +954,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, +@@ -955,7 +955,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, } spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); @@ -104349,7 +103898,7 @@ index 653f5eb..02994ee 100644 ieee80211_clear_tx_pending(local); /* -@@ -997,7 +997,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, +@@ -998,7 +998,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, if (cancel_scan) flush_delayed_work(&local->scan_work); @@ -104358,7 +103907,7 @@ index 653f5eb..02994ee 100644 ieee80211_stop_device(local); /* no reconfiguring after stop! */ -@@ -1008,7 +1008,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, +@@ -1009,7 +1009,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, ieee80211_configure_filter(local); ieee80211_hw_config(local, hw_reconf_flags); @@ -117630,10 +117179,10 @@ index 0000000..4378111 +} diff --git a/tools/gcc/size_overflow_plugin/size_overflow_hash.data b/tools/gcc/size_overflow_plugin/size_overflow_hash.data new file mode 100644 -index 0000000..367aa34 +index 0000000..f38f762 --- /dev/null +++ b/tools/gcc/size_overflow_plugin/size_overflow_hash.data -@@ -0,0 +1,6028 @@ +@@ -0,0 +1,6029 @@ +intel_fake_agp_alloc_by_type_1 intel_fake_agp_alloc_by_type 1 1 NULL +storvsc_connect_to_vsp_22 storvsc_connect_to_vsp 2 22 NULL +compat_sock_setsockopt_23 compat_sock_setsockopt 5 23 NULL @@ -120842,6 +120391,7 @@ index 0000000..367aa34 +sisusb_copy_memory_35016 sisusb_copy_memory 4 35016 NULL +coda_psdev_read_35029 coda_psdev_read 3 35029 NULL +hwdep_read_locked_35037 hwdep_read_locked 3 35037 NULL ++proc_setgroups_write_35039 proc_setgroups_write 3 35039 NULL +pwr_connection_out_of_sync_read_35061 pwr_connection_out_of_sync_read 3 35061 NULL +__kfifo_uint_must_check_helper_35097 __kfifo_uint_must_check_helper 0-1 35097 NULL +capi_write_35104 capi_write 3 35104 NULL nohasharray diff --git a/3.14.27/4425_grsec_remove_EI_PAX.patch b/3.18.2/4425_grsec_remove_EI_PAX.patch similarity index 100% rename from 3.14.27/4425_grsec_remove_EI_PAX.patch rename to 3.18.2/4425_grsec_remove_EI_PAX.patch diff --git a/3.18.1/4427_force_XATTR_PAX_tmpfs.patch b/3.18.2/4427_force_XATTR_PAX_tmpfs.patch similarity index 100% rename from 3.18.1/4427_force_XATTR_PAX_tmpfs.patch rename to 3.18.2/4427_force_XATTR_PAX_tmpfs.patch diff --git a/3.14.27/4430_grsec-remove-localversion-grsec.patch b/3.18.2/4430_grsec-remove-localversion-grsec.patch similarity index 100% rename from 3.14.27/4430_grsec-remove-localversion-grsec.patch rename to 3.18.2/4430_grsec-remove-localversion-grsec.patch diff --git a/3.18.1/4435_grsec-mute-warnings.patch b/3.18.2/4435_grsec-mute-warnings.patch similarity index 100% rename from 3.18.1/4435_grsec-mute-warnings.patch rename to 3.18.2/4435_grsec-mute-warnings.patch diff --git a/3.14.27/4440_grsec-remove-protected-paths.patch b/3.18.2/4440_grsec-remove-protected-paths.patch similarity index 100% rename from 3.14.27/4440_grsec-remove-protected-paths.patch rename to 3.18.2/4440_grsec-remove-protected-paths.patch diff --git a/3.18.1/4450_grsec-kconfig-default-gids.patch b/3.18.2/4450_grsec-kconfig-default-gids.patch similarity index 100% rename from 3.18.1/4450_grsec-kconfig-default-gids.patch rename to 3.18.2/4450_grsec-kconfig-default-gids.patch diff --git a/3.18.1/4465_selinux-avc_audit-log-curr_ip.patch b/3.18.2/4465_selinux-avc_audit-log-curr_ip.patch similarity index 100% rename from 3.18.1/4465_selinux-avc_audit-log-curr_ip.patch rename to 3.18.2/4465_selinux-avc_audit-log-curr_ip.patch diff --git a/3.18.1/4470_disable-compat_vdso.patch b/3.18.2/4470_disable-compat_vdso.patch similarity index 100% rename from 3.18.1/4470_disable-compat_vdso.patch rename to 3.18.2/4470_disable-compat_vdso.patch diff --git a/3.14.27/4475_emutramp_default_on.patch b/3.18.2/4475_emutramp_default_on.patch similarity index 100% rename from 3.14.27/4475_emutramp_default_on.patch rename to 3.18.2/4475_emutramp_default_on.patch diff --git a/3.2.66/0000_README b/3.2.66/0000_README index d4ad1aa..22258ee 100644 --- a/3.2.66/0000_README +++ b/3.2.66/0000_README @@ -182,7 +182,7 @@ Patch: 1065_linux-3.2.66.patch From: http://www.kernel.org Desc: Linux 3.2.66 -Patch: 4420_grsecurity-3.0-3.2.66-201501051839.patch +Patch: 4420_grsecurity-3.0-3.2.66-201501111416.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.2.66/4420_grsecurity-3.0-3.2.66-201501051839.patch b/3.2.66/4420_grsecurity-3.0-3.2.66-201501111416.patch similarity index 99% rename from 3.2.66/4420_grsecurity-3.0-3.2.66-201501051839.patch rename to 3.2.66/4420_grsecurity-3.0-3.2.66-201501111416.patch index a07d1dd..3b28713 100644 --- a/3.2.66/4420_grsecurity-3.0-3.2.66-201501051839.patch +++ b/3.2.66/4420_grsecurity-3.0-3.2.66-201501111416.patch @@ -41937,7 +41937,7 @@ index 4d4cd14..d6fdd87 100644 INIT_LIST_HEAD(&serio_raw->client_list); init_waitqueue_head(&serio_raw->wait); diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c -index 486982f..56816d7 100644 +index 486982f..1e8058b 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -536,11 +536,21 @@ static void copy_cmd_to_buffer(struct amd_iommu *iommu, @@ -41952,7 +41952,7 @@ index 486982f..56816d7 100644 - cmd->data[1] = upper_32_bits(__pa(address)); + +#ifdef CONFIG_GRKERNSEC_KSTACKOVERFLOW -+ if (object_starts_on_stack(address)) { ++ if (object_starts_on_stack((void *)address)) { + void *adjbuf = (void *)address - current->stack + current->lowmem_stack; + physaddr = __pa((u64)adjbuf); + } else