diff options
Diffstat (limited to 'main/linux-grsec')
-rw-r--r-- | main/linux-grsec/APKBUILD | 16 | ||||
-rw-r--r-- | main/linux-grsec/grsecurity-3.1-3.14.33-201502222137.patch (renamed from main/linux-grsec/grsecurity-3.0-3.14.32-201502062101.patch) | 782 |
2 files changed, 522 insertions, 276 deletions
diff --git a/main/linux-grsec/APKBUILD b/main/linux-grsec/APKBUILD index 80f993d7db..6ff4b1905b 100644 --- a/main/linux-grsec/APKBUILD +++ b/main/linux-grsec/APKBUILD @@ -2,7 +2,7 @@ _flavor=grsec pkgname=linux-${_flavor} -pkgver=3.14.32 +pkgver=3.14.33 case $pkgver in *.*.*) _kernver=${pkgver%.*};; *.*) _kernver=${pkgver};; @@ -17,7 +17,7 @@ _config=${config:-kernelconfig.${CARCH}} install= source="http://ftp.kernel.org/pub/linux/kernel/v3.x/linux-$_kernver.tar.xz http://ftp.kernel.org/pub/linux/kernel/v3.x/patch-$pkgver.xz - grsecurity-3.0-3.14.32-201502062101.patch + grsecurity-3.1-3.14.33-201502222137.patch fix-memory-map-for-PIE-applications.patch imx6q-no-unclocked-sleep.patch @@ -165,24 +165,24 @@ dev() { } md5sums="b621207b3f6ecbb67db18b13258f8ea8 linux-3.14.tar.xz -64519f60de7b12ef5bf2df4d323cee9c patch-3.14.32.xz -c2ba768d23f52cb8ee025ad92bd0375a grsecurity-3.0-3.14.32-201502062101.patch +f75aa6a7dda86fdde2980e5820847574 patch-3.14.33.xz +cb819f5d0f36794e3fb0702fe7017f7c grsecurity-3.1-3.14.33-201502222137.patch c6a4ae7e8ca6159e1631545515805216 fix-memory-map-for-PIE-applications.patch 1a307fc1d63231bf01d22493a4f14378 imx6q-no-unclocked-sleep.patch 870b91f0eb07294ba453ac61b052c0b6 kernelconfig.x86 38b50cd1a7670f886c5e9fe9f1f91496 kernelconfig.x86_64 6709c83fbbd38d40f31d39f0022d4ce9 kernelconfig.armhf" sha256sums="61558aa490855f42b6340d1a1596be47454909629327c49a5e4e10268065dffa linux-3.14.tar.xz -601ea355f71435b19421d7eabd7b92b2bb25bf5598f419ac548f46e416e162e9 patch-3.14.32.xz -528dfd709203fb6ec09c2cf1ce79f3c29f5f2d4f5580cae1c20f663e4d1fd1e2 grsecurity-3.0-3.14.32-201502062101.patch +442afcc7e4ba4e58d21c12b5136be671c0bf7ae24347b5c5374644022ac37d14 patch-3.14.33.xz +02afc578e50a368130d61b697e9325f6bd9f822e55899e3f06bafb52c92bfcd7 grsecurity-3.1-3.14.33-201502222137.patch 500f3577310be52e87b9fecdc2e9c4ca43210fd97d69089f9005d484563f74c7 fix-memory-map-for-PIE-applications.patch 21179fbb22a5b74af0a609350ae1a170e232908572b201d02e791d2ce0a685d3 imx6q-no-unclocked-sleep.patch bf953a65ba047b5316509da5bc7a6dbcee12767e343d26e8360369d27bfdbe78 kernelconfig.x86 d555a01f2b464e20cfa71c67ea6d571f80c707c5a3fea33879de09b085e2d7b6 kernelconfig.x86_64 01a6c90cf0643f8727d120aede2267ca7303c4ebe548c5d19222d4387ceb98cc kernelconfig.armhf" sha512sums="5730d83a7a81134c1e77c0bf89e42dee4f8251ad56c1ac2be20c59e26fdfaa7bea55f277e7af156b637f22e1584914a46089af85039177cb43485089c74ac26e linux-3.14.tar.xz -b5105f88d982fef656cae9e232457e24a49efc59717ff3511a0d08544beae88644a2a03644361f2f56e5d5e9dcdb8de51da12d8c3ccb8c4e2712abc391d608b9 patch-3.14.32.xz -9a34575ae4a827bbd201eb679dc3554ac391ebf3c6cc1aadd2e40598d55396bee80df36a1739cb676689e35153ca0822e3f7cab5123ef8b19a8a1671f00fe134 grsecurity-3.0-3.14.32-201502062101.patch +ff5894fe7f8790475c75e1c47f88240c2c0d1a463296f0f407f50380e14d7920bf408413ce17f393cbc25d41e6b2652afb15fbf47f8f4470bfb28edc10ffc908 patch-3.14.33.xz +8ed93addc4f63582fbfe1f5ccf06cb585f0e9dff3b2e3c5d988e585dd2e318bfe999b2dba8da0ec80f9272074281547ee0b1760c4d7f08cbff784019882ee2bd grsecurity-3.1-3.14.33-201502222137.patch 4665c56ae1bbac311f9205d64918e84ee8b01d47d6e2396ff6b8adfb10aada7f7254531ce62e31edbb65c2a54a830f09ad05d314dfcd75d6272f4068945ad7c7 fix-memory-map-for-PIE-applications.patch 87d1ad59732f265a5b0db54490dc1762c14ea4b868e7eb1aedc3ce57b48046de7bbc08cf5cfcf6f1380fa84063b0edb16ba3d5e3c5670be9bbb229275c88b221 imx6q-no-unclocked-sleep.patch dde402be39f68955f9395f807631f1457e90cda76a80e0e198695c8f946cdba02a00fe12a59a77bf5e8b40f5ecb52efbe364449f3e58d8996f27e07b719ac6a4 kernelconfig.x86 diff --git a/main/linux-grsec/grsecurity-3.0-3.14.32-201502062101.patch b/main/linux-grsec/grsecurity-3.1-3.14.33-201502222137.patch index 65a470aea6..ae236ccde6 100644 --- a/main/linux-grsec/grsecurity-3.0-3.14.32-201502062101.patch +++ b/main/linux-grsec/grsecurity-3.1-3.14.33-201502222137.patch @@ -292,7 +292,7 @@ index 5d91ba1..935a4e7 100644 pcd. [PARIDE] diff --git a/Makefile b/Makefile -index 00fffa3..1dc26b3 100644 +index b0963ca..76c9099 100644 --- a/Makefile +++ b/Makefile @@ -244,8 +244,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ @@ -3896,7 +3896,7 @@ index 7abde2c..9df495f 100644 static bool of_init = false; diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c -index 6eb97b3..e77848e 100644 +index 4370933..e77848e 100644 --- a/arch/arm/mm/context.c +++ b/arch/arm/mm/context.c @@ -43,7 +43,7 @@ @@ -3908,40 +3908,7 @@ index 6eb97b3..e77848e 100644 static DECLARE_BITMAP(asid_map, NUM_USER_ASIDS); static DEFINE_PER_CPU(atomic64_t, active_asids); -@@ -144,21 +144,17 @@ static void flush_context(unsigned int cpu) - /* Update the list of reserved ASIDs and the ASID bitmap. */ - bitmap_clear(asid_map, 0, NUM_USER_ASIDS); - for_each_possible_cpu(i) { -- if (i == cpu) { -- asid = 0; -- } else { -- asid = atomic64_xchg(&per_cpu(active_asids, i), 0); -- /* -- * If this CPU has already been through a -- * rollover, but hasn't run another task in -- * the meantime, we must preserve its reserved -- * ASID, as this is the only trace we have of -- * the process it is still running. -- */ -- if (asid == 0) -- asid = per_cpu(reserved_asids, i); -- __set_bit(asid & ~ASID_MASK, asid_map); -- } -+ asid = atomic64_xchg(&per_cpu(active_asids, i), 0); -+ /* -+ * If this CPU has already been through a -+ * rollover, but hasn't run another task in -+ * the meantime, we must preserve its reserved -+ * ASID, as this is the only trace we have of -+ * the process it is still running. -+ */ -+ if (asid == 0) -+ asid = per_cpu(reserved_asids, i); -+ __set_bit(asid & ~ASID_MASK, asid_map); - per_cpu(reserved_asids, i) = asid; - } - -@@ -182,7 +178,7 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu) +@@ -178,7 +178,7 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu) { static u32 cur_idx = 1; u64 asid = atomic64_read(&mm->context.id); @@ -3950,7 +3917,7 @@ index 6eb97b3..e77848e 100644 if (asid != 0 && is_reserved_asid(asid)) { /* -@@ -203,7 +199,7 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu) +@@ -199,7 +199,7 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu) */ asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, cur_idx); if (asid == NUM_USER_ASIDS) { @@ -3959,7 +3926,7 @@ index 6eb97b3..e77848e 100644 &asid_generation); flush_context(cpu); asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, 1); -@@ -234,14 +230,14 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk) +@@ -230,14 +230,14 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk) cpu_set_reserved_ttbr0(); asid = atomic64_read(&mm->context.id); @@ -28225,7 +28192,7 @@ index e8edcf5..27f9344 100644 goto cannot_handle; if ((segoffs >> 16) == BIOSSEG) diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S -index da6b35a..977e9cf 100644 +index da6b35a..7ef6b87 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -26,6 +26,13 @@ @@ -28406,7 +28373,6 @@ index da6b35a..977e9cf 100644 + .init.text (. - __KERNEL_TEXT_OFFSET): AT(init_begin - LOAD_OFFSET) { + VMLINUX_SYMBOL(_sinittext) = .; + INIT_TEXT -+ VMLINUX_SYMBOL(_einittext) = .; + . = ALIGN(PAGE_SIZE); + } :text.init @@ -28417,6 +28383,7 @@ index da6b35a..977e9cf 100644 + */ + .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { + EXIT_TEXT ++ VMLINUX_SYMBOL(_einittext) = .; + . = ALIGN(16); + } :text.exit + . = init_begin + SIZEOF(.init.text) + SIZEOF(.exit.text); @@ -28834,18 +28801,10 @@ index 9643eda6..c9cb765 100644 local_irq_disable(); diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c -index de42688..6e3ace5 100644 +index 80c22a3..ec2028e 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c -@@ -441,6 +441,7 @@ struct vcpu_vmx { - #endif - int gs_ldt_reload_needed; - int fs_reload_needed; -+ unsigned long vmcs_host_cr4; /* May not match real cr4 */ - } host_state; - struct { - int vm86_active; -@@ -1320,12 +1321,12 @@ static void vmcs_write64(unsigned long field, u64 value) +@@ -1321,12 +1321,12 @@ static void vmcs_write64(unsigned long field, u64 value) #endif } @@ -28860,7 +28819,7 @@ index de42688..6e3ace5 100644 { vmcs_writel(field, vmcs_readl(field) | mask); } -@@ -1585,7 +1586,11 @@ static void reload_tss(void) +@@ -1586,7 +1586,11 @@ static void reload_tss(void) struct desc_struct *descs; descs = (void *)gdt->address; @@ -28872,7 +28831,7 @@ index de42688..6e3ace5 100644 load_TR_desc(); } -@@ -1809,6 +1814,10 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +@@ -1810,6 +1814,10 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) vmcs_writel(HOST_TR_BASE, kvm_read_tr_base()); /* 22.2.4 */ vmcs_writel(HOST_GDTR_BASE, gdt->address); /* 22.2.4 */ @@ -28883,7 +28842,7 @@ index de42688..6e3ace5 100644 rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp); vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */ vmx->loaded_vmcs->cpu = cpu; -@@ -2098,7 +2107,7 @@ static void setup_msrs(struct vcpu_vmx *vmx) +@@ -2099,7 +2107,7 @@ static void setup_msrs(struct vcpu_vmx *vmx) * reads and returns guest's timestamp counter "register" * guest_tsc = host_tsc + tsc_offset -- 21.3 */ @@ -28892,7 +28851,7 @@ index de42688..6e3ace5 100644 { u64 host_tsc, tsc_offset; -@@ -3027,8 +3036,11 @@ static __init int hardware_setup(void) +@@ -3028,8 +3036,11 @@ static __init int hardware_setup(void) if (!cpu_has_vmx_flexpriority()) flexpriority_enabled = 0; @@ -28906,7 +28865,7 @@ index de42688..6e3ace5 100644 if (enable_ept && !cpu_has_vmx_ept_2m_page()) kvm_disable_largepages(); -@@ -3039,13 +3051,15 @@ static __init int hardware_setup(void) +@@ -3040,13 +3051,15 @@ static __init int hardware_setup(void) if (!cpu_has_vmx_apicv()) enable_apicv = 0; @@ -28926,26 +28885,18 @@ index de42688..6e3ace5 100644 if (nested) nested_vmx_setup_ctls_msrs(); -@@ -4165,10 +4179,17 @@ static void vmx_set_constant_host_state(struct vcpu_vmx *vmx) - u32 low32, high32; - unsigned long tmpl; - struct desc_ptr dt; -+ unsigned long cr4; +@@ -4169,7 +4182,10 @@ static void vmx_set_constant_host_state(struct vcpu_vmx *vmx) + unsigned long cr4; vmcs_writel(HOST_CR0, read_cr0() & ~X86_CR0_TS); /* 22.2.3 */ -- vmcs_writel(HOST_CR4, read_cr4()); /* 22.2.3, 22.2.5 */ ++ +#ifndef CONFIG_PAX_PER_CPU_PGD vmcs_writel(HOST_CR3, read_cr3()); /* 22.2.3 FIXME: shadow tables */ +#endif -+ -+ /* Save the most likely value for this task's CR4 in the VMCS. */ -+ cr4 = read_cr4(); -+ vmcs_writel(HOST_CR4, cr4); /* 22.2.3, 22.2.5 */ -+ vmx->host_state.vmcs_host_cr4 = cr4; - vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS); /* 22.2.4 */ - #ifdef CONFIG_X86_64 -@@ -4190,7 +4211,7 @@ static void vmx_set_constant_host_state(struct vcpu_vmx *vmx) + /* Save the most likely value for this task's CR4 in the VMCS. */ + cr4 = read_cr4(); +@@ -4196,7 +4212,7 @@ static void vmx_set_constant_host_state(struct vcpu_vmx *vmx) vmcs_writel(HOST_IDTR_BASE, dt.address); /* 22.2.4 */ vmx->host_idt_base = dt.address; @@ -28954,29 +28905,7 @@ index de42688..6e3ace5 100644 rdmsr(MSR_IA32_SYSENTER_CS, low32, high32); vmcs_write32(HOST_IA32_SYSENTER_CS, low32); -@@ -7196,7 +7217,7 @@ static void atomic_switch_perf_msrs(struct vcpu_vmx *vmx) - static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) - { - struct vcpu_vmx *vmx = to_vmx(vcpu); -- unsigned long debugctlmsr; -+ unsigned long debugctlmsr, cr4; - - /* Record the guest's net vcpu time for enforced NMI injections. */ - if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked)) -@@ -7217,6 +7238,12 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) - if (test_bit(VCPU_REGS_RIP, (unsigned long *)&vcpu->arch.regs_dirty)) - vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]); - -+ cr4 = read_cr4(); -+ if (unlikely(cr4 != vmx->host_state.vmcs_host_cr4)) { -+ vmcs_writel(HOST_CR4, cr4); -+ vmx->host_state.vmcs_host_cr4 = cr4; -+ } -+ - /* When single-stepping over STI and MOV SS, we must clear the - * corresponding interruptibility bits in the guest state. Otherwise - * vmentry fails as it then expects bit 14 (BS) in pending debug -@@ -7275,6 +7302,12 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) +@@ -7287,6 +7303,12 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) "jmp 2f \n\t" "1: " __ex(ASM_VMX_VMRESUME) "\n\t" "2: " @@ -28989,7 +28918,7 @@ index de42688..6e3ace5 100644 /* Save guest registers, load host registers, keep flags */ "mov %0, %c[wordsize](%%" _ASM_SP ") \n\t" "pop %0 \n\t" -@@ -7327,6 +7360,11 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) +@@ -7339,6 +7361,11 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) #endif [cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2)), [wordsize]"i"(sizeof(ulong)) @@ -29001,7 +28930,7 @@ index de42688..6e3ace5 100644 : "cc", "memory" #ifdef CONFIG_X86_64 , "rax", "rbx", "rdi", "rsi" -@@ -7340,7 +7378,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) +@@ -7352,7 +7379,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) if (debugctlmsr) update_debugctlmsr(debugctlmsr); @@ -29010,7 +28939,7 @@ index de42688..6e3ace5 100644 /* * The sysexit path does not restore ds/es, so we must set them to * a reasonable value ourselves. -@@ -7349,8 +7387,18 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) +@@ -7361,8 +7388,18 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) * may be executed in interrupt context, which saves and restore segments * around it, nullifying its effect. */ @@ -33438,7 +33367,7 @@ index 7b179b49..6bd17777 100644 return (void *)vaddr; diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c -index 94bd247..7e48391 100644 +index 94bd247..49644a3 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -56,8 +56,8 @@ static int __ioremap_check_ram(unsigned long start_pfn, unsigned long nr_pages, @@ -33461,17 +33390,29 @@ index 94bd247..7e48391 100644 { struct vm_struct *p, *o; -@@ -322,6 +322,9 @@ void *xlate_dev_mem_ptr(unsigned long phys) - +@@ -317,23 +317,22 @@ EXPORT_SYMBOL(iounmap); + */ + void *xlate_dev_mem_ptr(unsigned long phys) + { +- void *addr; +- unsigned long start = phys & PAGE_MASK; +- /* If page is RAM, we can use __va. Otherwise ioremap and unmap. */ - if (page_is_ram(start >> PAGE_SHIFT)) +- if (page_is_ram(start >> PAGE_SHIFT)) ++ if (page_is_ram(phys >> PAGE_SHIFT)) +#ifdef CONFIG_HIGHMEM -+ if ((start >> PAGE_SHIFT) < max_low_pfn) ++ if ((phys >> PAGE_SHIFT) < max_low_pfn) +#endif return __va(phys); - addr = (void __force *)ioremap_cache(start, PAGE_SIZE); -@@ -334,6 +337,9 @@ void *xlate_dev_mem_ptr(unsigned long phys) +- addr = (void __force *)ioremap_cache(start, PAGE_SIZE); +- if (addr) +- addr = (void *)((unsigned long)addr | (phys & ~PAGE_MASK)); +- +- return addr; ++ return (void __force *)ioremap_cache(phys, PAGE_SIZE); + } + void unxlate_dev_mem_ptr(unsigned long phys, void *addr) { if (page_is_ram(phys >> PAGE_SHIFT)) @@ -33481,7 +33422,7 @@ index 94bd247..7e48391 100644 return; iounmap((void __iomem *)((unsigned long)addr & PAGE_MASK)); -@@ -351,7 +357,7 @@ static int __init early_ioremap_debug_setup(char *str) +@@ -351,7 +350,7 @@ static int __init early_ioremap_debug_setup(char *str) early_param("early_ioremap_debug", early_ioremap_debug_setup); static __initdata int after_paging_init; @@ -33490,7 +33431,7 @@ index 94bd247..7e48391 100644 static inline pmd_t * __init early_ioremap_pmd(unsigned long addr) { -@@ -388,8 +394,7 @@ void __init early_ioremap_init(void) +@@ -388,8 +387,7 @@ void __init early_ioremap_init(void) slot_virt[i] = __fix_to_virt(FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*i); pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)); @@ -34391,10 +34332,10 @@ index 0149575..f746de8 100644 + pax_force_retaddr ret diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c -index af2d431..bc63cba 100644 +index af2d431..c405730 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c -@@ -50,13 +50,90 @@ static inline u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len) +@@ -50,13 +50,102 @@ static inline u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len) return ptr + len; } @@ -34422,7 +34363,8 @@ index af2d431..bc63cba 100644 + EMIT2(0x81, 0xf1); \ + EMIT((_key) ^ (_off), 4); \ +} while (0) -+ ++#define SHORT_JMP_LENGTH 2 ++#define NEAR_JMP_LENGTH (5 + 8) +#define EMIT1_off32(b1, _off) \ +do { \ + switch (b1) { \ @@ -34430,13 +34372,21 @@ index af2d431..bc63cba 100644 + case 0x2d: /* sub eax, imm32 */ \ + case 0x25: /* and eax, imm32 */ \ + case 0x0d: /* or eax, imm32 */ \ -+ case 0xb8: /* mov eax, imm32 */ \ + case 0x35: /* xor eax, imm32 */ \ + case 0x3d: /* cmp eax, imm32 */ \ -+ case 0xa9: /* test eax, imm32 */ \ + DILUTE_CONST_SEQUENCE(_off, randkey); \ + EMIT2((b1) - 4, 0xc8); /* convert imm instruction to eax, ecx */\ + break; \ ++ case 0xb8: /* mov eax, imm32 */ \ ++ DILUTE_CONST_SEQUENCE(_off, randkey); \ ++ /* mov eax, ecx */ \ ++ EMIT2(0x89, 0xc8); \ ++ break; \ ++ case 0xa9: /* test eax, imm32 */ \ ++ DILUTE_CONST_SEQUENCE(_off, randkey); \ ++ /* test eax, ecx */ \ ++ EMIT2(0x85, 0xc8); \ ++ break; \ + case 0xbb: /* mov ebx, imm32 */ \ + DILUTE_CONST_SEQUENCE(_off, randkey); \ + /* mov ebx, ecx */ \ @@ -34452,8 +34402,9 @@ index af2d431..bc63cba 100644 + EMIT(_off, 4); \ + break; \ + case 0xe9: /* jmp rel imm32 */ \ ++ BUG_ON((int)(_off) < 0); \ + EMIT1(b1); \ -+ EMIT(_off, 4); \ ++ EMIT(_off + 8, 4); \ + /* prevent fall-through, we're not called if off = 0 */ \ + EMIT(0xcccccccc, 4); \ + EMIT(0xcccccccc, 4); \ @@ -34481,11 +34432,21 @@ index af2d431..bc63cba 100644 +#else #define EMIT1_off32(b1, off) do { EMIT1(b1); EMIT(off, 4);} while (0) +#define EMIT2_off32(b1, b2, off) do { EMIT2(b1, b2); EMIT(off, 4);} while (0) ++#define SHORT_JMP_LENGTH 2 ++#define NEAR_JMP_LENGTH 5 +#endif #define CLEAR_A() EMIT2(0x31, 0xc0) /* xor %eax,%eax */ #define CLEAR_X() EMIT2(0x31, 0xdb) /* xor %ebx,%ebx */ -@@ -91,6 +168,24 @@ do { \ +@@ -73,6 +162,7 @@ static inline bool is_near(int offset) + + #define EMIT_JMP(offset) \ + do { \ ++ BUG_ON((int)(offset) < 0); \ + if (offset) { \ + if (is_near(offset)) \ + EMIT2(0xeb, offset); /* jmp .+off8 */ \ +@@ -91,13 +181,33 @@ do { \ #define X86_JBE 0x76 #define X86_JA 0x77 @@ -34509,16 +34470,18 @@ index af2d431..bc63cba 100644 + #define EMIT_COND_JMP(op, offset) \ do { \ ++ BUG_ON((int)(offset) < 0); \ if (is_near(offset)) \ -@@ -98,6 +193,7 @@ do { \ + EMIT2(op, offset); /* jxx .+off8 */ \ else { \ EMIT2(0x0f, op + 0x10); \ - EMIT(offset, 4); /* jxx .+off32 */ \ +- EMIT(offset, 4); /* jxx .+off32 */ \ ++ EMIT((offset) + 21, 4); /* jxx .+off32 */ \ + APPEND_FLOW_VERIFY(); \ } \ } while (0) -@@ -145,55 +241,54 @@ static int pkt_type_offset(void) +@@ -145,55 +255,54 @@ static int pkt_type_offset(void) return -1; } @@ -34590,7 +34553,7 @@ index af2d431..bc63cba 100644 if (!bpf_jit_enable) return; -@@ -203,10 +298,10 @@ void bpf_jit_compile(struct sk_filter *fp) +@@ -203,10 +312,10 @@ void bpf_jit_compile(struct sk_filter *fp) return; /* Before first pass, make a rough estimation of addrs[] @@ -34603,7 +34566,7 @@ index af2d431..bc63cba 100644 addrs[i] = proglen; } cleanup_addr = proglen; /* epilogue address */ -@@ -285,6 +380,10 @@ void bpf_jit_compile(struct sk_filter *fp) +@@ -285,6 +394,10 @@ void bpf_jit_compile(struct sk_filter *fp) for (i = 0; i < flen; i++) { unsigned int K = filter[i].k; @@ -34614,7 +34577,7 @@ index af2d431..bc63cba 100644 switch (filter[i].code) { case BPF_S_ALU_ADD_X: /* A += X; */ seen |= SEEN_XREG; -@@ -317,10 +416,8 @@ void bpf_jit_compile(struct sk_filter *fp) +@@ -317,10 +430,8 @@ void bpf_jit_compile(struct sk_filter *fp) case BPF_S_ALU_MUL_K: /* A *= K */ if (is_imm8(K)) EMIT3(0x6b, 0xc0, K); /* imul imm8,%eax,%eax */ @@ -34627,7 +34590,16 @@ index af2d431..bc63cba 100644 break; case BPF_S_ALU_DIV_X: /* A /= X; */ seen |= SEEN_XREG; -@@ -364,7 +461,11 @@ void bpf_jit_compile(struct sk_filter *fp) +@@ -333,7 +444,7 @@ void bpf_jit_compile(struct sk_filter *fp) + EMIT_COND_JMP(X86_JE, addrs[pc_ret0 - 1] - + (addrs[i] - 4)); + } else { +- EMIT_COND_JMP(X86_JNE, 2 + 5); ++ EMIT_COND_JMP(X86_JNE, 2 + NEAR_JMP_LENGTH); + CLEAR_A(); + EMIT1_off32(0xe9, cleanup_addr - (addrs[i] - 4)); /* jmp .+off32 */ + } +@@ -364,7 +475,11 @@ void bpf_jit_compile(struct sk_filter *fp) break; } EMIT2(0x31, 0xd2); /* xor %edx,%edx */ @@ -34639,7 +34611,7 @@ index af2d431..bc63cba 100644 EMIT2(0xf7, 0xf1); /* div %ecx */ EMIT2(0x89, 0xd0); /* mov %edx,%eax */ break; -@@ -372,7 +473,11 @@ void bpf_jit_compile(struct sk_filter *fp) +@@ -372,7 +487,11 @@ void bpf_jit_compile(struct sk_filter *fp) if (K == 1) break; EMIT2(0x31, 0xd2); /* xor %edx,%edx */ @@ -34651,7 +34623,7 @@ index af2d431..bc63cba 100644 EMIT2(0xf7, 0xf1); /* div %ecx */ break; case BPF_S_ALU_AND_X: -@@ -643,8 +748,7 @@ common_load_ind: seen |= SEEN_DATAREF | SEEN_XREG; +@@ -643,8 +762,7 @@ common_load_ind: seen |= SEEN_DATAREF | SEEN_XREG; if (is_imm8(K)) { EMIT3(0x8d, 0x73, K); /* lea imm8(%rbx), %esi */ } else { @@ -34661,7 +34633,16 @@ index af2d431..bc63cba 100644 } } else { EMIT2(0x89,0xde); /* mov %ebx,%esi */ -@@ -734,10 +838,12 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i]; +@@ -717,7 +835,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i]; + } + if (filter[i].jt != 0) { + if (filter[i].jf && f_offset) +- t_offset += is_near(f_offset) ? 2 : 5; ++ t_offset += is_near(f_offset) ? SHORT_JMP_LENGTH : NEAR_JMP_LENGTH; + EMIT_COND_JMP(t_op, t_offset); + if (filter[i].jf) + EMIT_JMP(f_offset); +@@ -734,10 +852,12 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i]; if (unlikely(proglen + ilen > oldproglen)) { pr_err("bpb_jit_compile fatal error\n"); kfree(addrs); @@ -34675,7 +34656,7 @@ index af2d431..bc63cba 100644 } proglen += ilen; addrs[i] = proglen; -@@ -770,7 +876,6 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i]; +@@ -770,7 +890,6 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i]; if (image) { bpf_flush_icache(header, image + proglen); @@ -34683,7 +34664,7 @@ index af2d431..bc63cba 100644 fp->bpf_func = (void *)image; } out: -@@ -782,10 +887,8 @@ static void bpf_jit_free_deferred(struct work_struct *work) +@@ -782,10 +901,8 @@ static void bpf_jit_free_deferred(struct work_struct *work) { struct sk_filter *fp = container_of(work, struct sk_filter, work); unsigned long addr = (unsigned long)fp->bpf_func & PAGE_MASK; @@ -60031,37 +60012,10 @@ index 5d12d69..161d0ce 100644 GLOBAL_EXTERN atomic_t smBufAllocCount; GLOBAL_EXTERN atomic_t midCount; diff --git a/fs/cifs/file.c b/fs/cifs/file.c -index d375322..2f1ac75 100644 +index 0218a9b..2f1ac75 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c -@@ -366,6 +366,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) - struct cifsLockInfo *li, *tmp; - struct cifs_fid fid; - struct cifs_pending_open open; -+ bool oplock_break_cancelled; - - spin_lock(&cifs_file_list_lock); - if (--cifs_file->count > 0) { -@@ -397,7 +398,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) - } - spin_unlock(&cifs_file_list_lock); - -- cancel_work_sync(&cifs_file->oplock_break); -+ oplock_break_cancelled = cancel_work_sync(&cifs_file->oplock_break); - - if (!tcon->need_reconnect && !cifs_file->invalidHandle) { - struct TCP_Server_Info *server = tcon->ses->server; -@@ -409,6 +410,9 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) - _free_xid(xid); - } - -+ if (oplock_break_cancelled) -+ cifs_done_oplock_break(cifsi); -+ - cifs_del_pending_open(&open); - - /* -@@ -1900,10 +1904,14 @@ static int cifs_writepages(struct address_space *mapping, +@@ -1904,10 +1904,14 @@ static int cifs_writepages(struct address_space *mapping, index = mapping->writeback_index; /* Start from prev offset */ end = -1; } else { @@ -60715,7 +60669,7 @@ index a93f7e6..d58bcbe 100644 return 0; while (nr) { diff --git a/fs/dcache.c b/fs/dcache.c -index 4366127..581b312 100644 +index 4366127..b8c2cf9 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -250,7 +250,7 @@ static void __d_free(struct rcu_head *head) @@ -60850,7 +60804,17 @@ index 4366127..581b312 100644 dentry->d_flags = 0; spin_lock_init(&dentry->d_lock); seqcount_init(&dentry->d_seq); -@@ -2275,7 +2276,7 @@ struct dentry *__d_lookup(const struct dentry *parent, const struct qstr *name) +@@ -1521,6 +1522,9 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) + dentry->d_sb = sb; + dentry->d_op = NULL; + dentry->d_fsdata = NULL; ++#ifdef CONFIG_GRKERNSEC_CHROOT_RENAME ++ atomic_set(&dentry->chroot_refcnt, 0); ++#endif + INIT_HLIST_BL_NODE(&dentry->d_hash); + INIT_LIST_HEAD(&dentry->d_lru); + INIT_LIST_HEAD(&dentry->d_subdirs); +@@ -2275,7 +2279,7 @@ struct dentry *__d_lookup(const struct dentry *parent, const struct qstr *name) goto next; } @@ -60859,7 +60823,7 @@ index 4366127..581b312 100644 found = dentry; spin_unlock(&dentry->d_lock); break; -@@ -2374,7 +2375,7 @@ again: +@@ -2374,7 +2378,7 @@ again: spin_lock(&dentry->d_lock); inode = dentry->d_inode; isdir = S_ISDIR(inode->i_mode); @@ -60868,7 +60832,7 @@ index 4366127..581b312 100644 if (!spin_trylock(&inode->i_lock)) { spin_unlock(&dentry->d_lock); cpu_relax(); -@@ -3318,7 +3319,7 @@ static enum d_walk_ret d_genocide_kill(void *data, struct dentry *dentry) +@@ -3318,7 +3322,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; @@ -60877,7 +60841,7 @@ index 4366127..581b312 100644 } } return D_WALK_CONTINUE; -@@ -3434,7 +3435,8 @@ void __init vfs_caches_init(unsigned long mempages) +@@ -3434,7 +3438,8 @@ void __init vfs_caches_init(unsigned long mempages) mempages -= reserve; names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0, @@ -62309,7 +62273,7 @@ index 92567d9..fcd8cbf 100644 if (dot && fs && !(fs->fs_flags & FS_HAS_SUBTYPE)) { diff --git a/fs/fs_struct.c b/fs/fs_struct.c -index 7dca743..543d620 100644 +index 7dca743..2f2786d 100644 --- a/fs/fs_struct.c +++ b/fs/fs_struct.c @@ -4,6 +4,7 @@ @@ -62320,15 +62284,27 @@ index 7dca743..543d620 100644 #include "internal.h" /* -@@ -19,6 +20,7 @@ void set_fs_root(struct fs_struct *fs, const struct path *path) +@@ -15,14 +16,18 @@ void set_fs_root(struct fs_struct *fs, const struct path *path) + struct path old_root; + + path_get(path); ++ gr_inc_chroot_refcnts(path->dentry, path->mnt); + spin_lock(&fs->lock); write_seqcount_begin(&fs->seq); old_root = fs->root; fs->root = *path; + gr_set_chroot_entries(current, path); write_seqcount_end(&fs->seq); spin_unlock(&fs->lock); - if (old_root.dentry) -@@ -67,6 +69,10 @@ void chroot_fs_refs(const struct path *old_root, const struct path *new_root) +- if (old_root.dentry) ++ if (old_root.dentry) { ++ gr_dec_chroot_refcnts(old_root.dentry, old_root.mnt); + path_put(&old_root); ++ } + } + + /* +@@ -67,6 +72,10 @@ void chroot_fs_refs(const struct path *old_root, const struct path *new_root) int hits = 0; spin_lock(&fs->lock); write_seqcount_begin(&fs->seq); @@ -62339,7 +62315,15 @@ index 7dca743..543d620 100644 hits += replace_path(&fs->root, old_root, new_root); hits += replace_path(&fs->pwd, old_root, new_root); write_seqcount_end(&fs->seq); -@@ -99,7 +105,8 @@ void exit_fs(struct task_struct *tsk) +@@ -85,6 +94,7 @@ void chroot_fs_refs(const struct path *old_root, const struct path *new_root) + + void free_fs_struct(struct fs_struct *fs) + { ++ gr_dec_chroot_refcnts(fs->root.dentry, fs->root.mnt); + path_put(&fs->root); + path_put(&fs->pwd); + kmem_cache_free(fs_cachep, fs); +@@ -99,7 +109,8 @@ void exit_fs(struct task_struct *tsk) task_lock(tsk); spin_lock(&fs->lock); tsk->fs = NULL; @@ -62349,7 +62333,7 @@ index 7dca743..543d620 100644 spin_unlock(&fs->lock); task_unlock(tsk); if (kill) -@@ -112,7 +119,7 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old) +@@ -112,7 +123,7 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old) struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL); /* We don't need to lock fs - think why ;-) */ if (fs) { @@ -62358,7 +62342,7 @@ index 7dca743..543d620 100644 fs->in_exec = 0; spin_lock_init(&fs->lock); seqcount_init(&fs->seq); -@@ -121,6 +128,9 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old) +@@ -121,6 +132,9 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old) spin_lock(&old->lock); fs->root = old->root; path_get(&fs->root); @@ -62368,7 +62352,7 @@ index 7dca743..543d620 100644 fs->pwd = old->pwd; path_get(&fs->pwd); spin_unlock(&old->lock); -@@ -139,8 +149,9 @@ int unshare_fs_struct(void) +@@ -139,8 +153,9 @@ int unshare_fs_struct(void) task_lock(current); spin_lock(&fs->lock); @@ -62379,7 +62363,7 @@ index 7dca743..543d620 100644 spin_unlock(&fs->lock); task_unlock(current); -@@ -153,13 +164,13 @@ EXPORT_SYMBOL_GPL(unshare_fs_struct); +@@ -153,13 +168,13 @@ EXPORT_SYMBOL_GPL(unshare_fs_struct); int current_umask(void) { @@ -64185,7 +64169,7 @@ index b29e42f..5ea7fdf 100644 #define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */ diff --git a/fs/namei.c b/fs/namei.c -index 0dd72c8..34dd17d 100644 +index 0dd72c8..07c6710 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -331,17 +331,34 @@ int generic_permission(struct inode *inode, int mask) @@ -64629,7 +64613,7 @@ index 0dd72c8..34dd17d 100644 struct filename *name; struct dentry *dentry; struct nameidata nd; -+ ino_t saved_ino = 0; ++ u64 saved_ino = 0; + dev_t saved_dev = 0; unsigned int lookup_flags = 0; retry: @@ -64639,7 +64623,7 @@ index 0dd72c8..34dd17d 100644 goto exit3; } + -+ saved_ino = dentry->d_inode->i_ino; ++ saved_ino = gr_get_ino_from_dentry(dentry); + saved_dev = gr_get_dev_from_dentry(dentry); + + if (!gr_acl_handle_rmdir(dentry, nd.path.mnt)) { @@ -64660,7 +64644,7 @@ index 0dd72c8..34dd17d 100644 struct nameidata nd; struct inode *inode = NULL; struct inode *delegated_inode = NULL; -+ ino_t saved_ino = 0; ++ u64 saved_ino = 0; + dev_t saved_dev = 0; unsigned int lookup_flags = 0; retry: @@ -64671,7 +64655,7 @@ index 0dd72c8..34dd17d 100644 ihold(inode); + + if (inode->i_nlink <= 1) { -+ saved_ino = inode->i_ino; ++ saved_ino = gr_get_ino_from_dentry(dentry); + saved_dev = gr_get_dev_from_dentry(dentry); + } + if (!gr_acl_handle_unlink(dentry, nd.path.mnt)) { @@ -64752,10 +64736,18 @@ index 0dd72c8..34dd17d 100644 done_path_create(&new_path, new_dentry); if (delegated_inode) { error = break_deleg_wait(&delegated_inode); -@@ -4239,6 +4433,12 @@ retry_deleg: +@@ -4239,6 +4433,20 @@ retry_deleg: if (new_dentry == trap) goto exit5; ++ if (gr_bad_chroot_rename(old_dentry, oldnd.path.mnt, new_dentry, newnd.path.mnt)) { ++ /* use EXDEV error to cause 'mv' to switch to an alternative ++ * method for usability ++ */ ++ error = -EXDEV; ++ goto exit5; ++ } ++ + error = gr_acl_handle_rename(new_dentry, new_dir, newnd.path.mnt, + old_dentry, old_dir->d_inode, oldnd.path.mnt, + to); @@ -64765,7 +64757,7 @@ index 0dd72c8..34dd17d 100644 error = security_path_rename(&oldnd.path, old_dentry, &newnd.path, new_dentry); if (error) -@@ -4246,6 +4446,9 @@ retry_deleg: +@@ -4246,6 +4454,9 @@ retry_deleg: error = vfs_rename(old_dir->d_inode, old_dentry, new_dir->d_inode, new_dentry, &delegated_inode); @@ -64775,7 +64767,7 @@ index 0dd72c8..34dd17d 100644 exit5: dput(new_dentry); exit4: -@@ -4282,6 +4485,8 @@ SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newna +@@ -4282,6 +4493,8 @@ SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newna int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const char *link) { @@ -64784,7 +64776,7 @@ index 0dd72c8..34dd17d 100644 int len; len = PTR_ERR(link); -@@ -4291,7 +4496,14 @@ int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const c +@@ -4291,7 +4504,14 @@ int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const c len = strlen(link); if (len > (unsigned) buflen) len = buflen; @@ -69182,10 +69174,10 @@ index f9bb590..af3c389 100644 diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig new file mode 100644 -index 0000000..cdaa3ef +index 0000000..49e1a77 --- /dev/null +++ b/grsecurity/Kconfig -@@ -0,0 +1,1168 @@ +@@ -0,0 +1,1184 @@ +# +# grecurity configuration +# @@ -69828,6 +69820,22 @@ index 0000000..cdaa3ef + sysctl option is enabled, a sysctl option with name + "chroot_deny_sysctl" is created. + ++config GRKERNSEC_CHROOT_RENAME ++ bool "Deny bad renames" ++ default y if GRKERNSEC_CONFIG_AUTO ++ depends on GRKERNSEC_CHROOT ++ help ++ If you say Y here, an attacker in a chroot will not be able to ++ abuse the ability to create double chroots to break out of the ++ chroot by exploiting a race condition between a rename of a directory ++ within a chroot against an open of a symlink with relative path ++ components. This feature will likewise prevent an accomplice outside ++ a chroot from enabling a user inside the chroot to break out and make ++ use of their credentials on the global filesystem. Enabling this ++ feature is essential to prevent root users from breaking out of a ++ chroot. If the sysctl option is enabled, a sysctl option with name ++ "chroot_deny_bad_rename" is created. ++ +config GRKERNSEC_CHROOT_CAPS + bool "Capability restrictions" + default y if GRKERNSEC_CONFIG_AUTO @@ -70416,10 +70424,10 @@ index 0000000..30ababb +endif diff --git a/grsecurity/gracl.c b/grsecurity/gracl.c new file mode 100644 -index 0000000..c83525f +index 0000000..24d5a4c --- /dev/null +++ b/grsecurity/gracl.c -@@ -0,0 +1,2697 @@ +@@ -0,0 +1,2725 @@ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/sched.h> @@ -70527,11 +70535,26 @@ index 0000000..c83525f + return dentry->d_sb->s_dev; +} + ++static inline u64 __get_ino(const struct dentry *dentry) ++{ ++#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE) ++ if (dentry->d_sb->s_magic == BTRFS_SUPER_MAGIC) ++ return btrfs_ino(dentry->d_inode); ++ else ++#endif ++ return dentry->d_inode->i_ino; ++} ++ +dev_t gr_get_dev_from_dentry(struct dentry *dentry) +{ + return __get_dev(dentry); +} + ++u64 gr_get_ino_from_dentry(struct dentry *dentry) ++{ ++ return __get_ino(dentry); ++} ++ +static char gr_task_roletype_to_char(struct task_struct *task) +{ + switch (task->role->roletype & @@ -70870,7 +70893,7 @@ index 0000000..c83525f +} + +struct acl_subject_label * -+lookup_acl_subj_label(const ino_t ino, const dev_t dev, ++lookup_acl_subj_label(const u64 ino, const dev_t dev, + const struct acl_role_label *role) +{ + unsigned int index = gr_fhash(ino, dev, role->subj_hash_size); @@ -70890,7 +70913,7 @@ index 0000000..c83525f +} + +struct acl_subject_label * -+lookup_acl_subj_label_deleted(const ino_t ino, const dev_t dev, ++lookup_acl_subj_label_deleted(const u64 ino, const dev_t dev, + const struct acl_role_label *role) +{ + unsigned int index = gr_fhash(ino, dev, role->subj_hash_size); @@ -70910,7 +70933,7 @@ index 0000000..c83525f +} + +static struct acl_object_label * -+lookup_acl_obj_label(const ino_t ino, const dev_t dev, ++lookup_acl_obj_label(const u64 ino, const dev_t dev, + const struct acl_subject_label *subj) +{ + unsigned int index = gr_fhash(ino, dev, subj->obj_hash_size); @@ -70930,7 +70953,7 @@ index 0000000..c83525f +} + +static struct acl_object_label * -+lookup_acl_obj_label_create(const ino_t ino, const dev_t dev, ++lookup_acl_obj_label_create(const u64 ino, const dev_t dev, + const struct acl_subject_label *subj) +{ + unsigned int index = gr_fhash(ino, dev, subj->obj_hash_size); @@ -71011,7 +71034,7 @@ index 0000000..c83525f +} + +static struct inodev_entry * -+lookup_inodev_entry(const ino_t ino, const dev_t dev) ++lookup_inodev_entry(const u64 ino, const dev_t dev) +{ + unsigned int index = gr_fhash(ino, dev, running_polstate.inodev_set.i_size); + struct inodev_entry *match; @@ -71236,7 +71259,7 @@ index 0000000..c83525f + +static struct acl_object_label * +__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt, -+ const ino_t curr_ino, const dev_t curr_dev, ++ const u64 curr_ino, const dev_t curr_dev, + const struct acl_subject_label *subj, char **path, const int checkglob) +{ + struct acl_subject_label *tmpsubj; @@ -71267,7 +71290,7 @@ index 0000000..c83525f + const struct acl_subject_label *subj, char **path, const int checkglob) +{ + int newglob = checkglob; -+ ino_t inode; ++ u64 inode; + dev_t device; + + /* if we aren't checking a subdirectory of the original path yet, don't do glob checking @@ -71279,7 +71302,7 @@ index 0000000..c83525f + newglob = GR_NO_GLOB; + + spin_lock(&curr_dentry->d_lock); -+ inode = curr_dentry->d_inode->i_ino; ++ inode = __get_ino(curr_dentry); + device = __get_dev(curr_dentry); + spin_unlock(&curr_dentry->d_lock); + @@ -71412,7 +71435,7 @@ index 0000000..c83525f + spin_lock(&dentry->d_lock); + read_lock(&gr_inode_lock); + retval = -+ lookup_acl_subj_label(dentry->d_inode->i_ino, ++ lookup_acl_subj_label(__get_ino(dentry), + __get_dev(dentry), role); + read_unlock(&gr_inode_lock); + spin_unlock(&dentry->d_lock); @@ -71427,7 +71450,7 @@ index 0000000..c83525f + + spin_lock(&dentry->d_lock); + read_lock(&gr_inode_lock); -+ retval = lookup_acl_subj_label(dentry->d_inode->i_ino, ++ retval = lookup_acl_subj_label(__get_ino(dentry), + __get_dev(dentry), role); + read_unlock(&gr_inode_lock); + parent = dentry->d_parent; @@ -71441,7 +71464,7 @@ index 0000000..c83525f + + spin_lock(&dentry->d_lock); + read_lock(&gr_inode_lock); -+ retval = lookup_acl_subj_label(dentry->d_inode->i_ino, ++ retval = lookup_acl_subj_label(__get_ino(dentry), + __get_dev(dentry), role); + read_unlock(&gr_inode_lock); + spin_unlock(&dentry->d_lock); @@ -71449,7 +71472,7 @@ index 0000000..c83525f + if (unlikely(retval == NULL)) { + /* gr_real_root is pinned, we don't need to hold a reference */ + read_lock(&gr_inode_lock); -+ retval = lookup_acl_subj_label(gr_real_root.dentry->d_inode->i_ino, ++ retval = lookup_acl_subj_label(__get_ino(gr_real_root.dentry), + __get_dev(gr_real_root.dentry), role); + read_unlock(&gr_inode_lock); + } @@ -71576,14 +71599,27 @@ index 0000000..c83525f + return; + + for (i = 0; i < RLIM_NLIMITS; i++) { ++ unsigned long rlim_cur, rlim_max; ++ + if (!(proc->resmask & (1U << i))) + continue; + -+ task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur; -+ task->signal->rlim[i].rlim_max = proc->res[i].rlim_max; ++ rlim_cur = proc->res[i].rlim_cur; ++ rlim_max = proc->res[i].rlim_max; ++ ++ if (i == RLIMIT_NOFILE) { ++ unsigned long saved_sysctl_nr_open = sysctl_nr_open; ++ if (rlim_cur > saved_sysctl_nr_open) ++ rlim_cur = saved_sysctl_nr_open; ++ if (rlim_max > saved_sysctl_nr_open) ++ rlim_max = saved_sysctl_nr_open; ++ } ++ ++ task->signal->rlim[i].rlim_cur = rlim_cur; ++ task->signal->rlim[i].rlim_max = rlim_max; + + if (i == RLIMIT_CPU) -+ update_rlimit_cpu(task, proc->res[i].rlim_cur); ++ update_rlimit_cpu(task, rlim_cur); + } + + return; @@ -72286,7 +72322,7 @@ index 0000000..c83525f + +/* always called with valid inodev ptr */ +static void -+do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev) ++do_handle_delete(struct inodev_entry *inodev, const u64 ino, const dev_t dev) +{ + struct acl_object_label *matchpo; + struct acl_subject_label *matchps; @@ -72314,7 +72350,7 @@ index 0000000..c83525f +} + +void -+gr_handle_delete(const ino_t ino, const dev_t dev) ++gr_handle_delete(const u64 ino, const dev_t dev) +{ + struct inodev_entry *inodev; + @@ -72331,8 +72367,8 @@ index 0000000..c83525f +} + +static void -+update_acl_obj_label(const ino_t oldinode, const dev_t olddevice, -+ const ino_t newinode, const dev_t newdevice, ++update_acl_obj_label(const u64 oldinode, const dev_t olddevice, ++ const u64 newinode, const dev_t newdevice, + struct acl_subject_label *subj) +{ + unsigned int index = gr_fhash(oldinode, olddevice, subj->obj_hash_size); @@ -72370,8 +72406,8 @@ index 0000000..c83525f +} + +static void -+update_acl_subj_label(const ino_t oldinode, const dev_t olddevice, -+ const ino_t newinode, const dev_t newdevice, ++update_acl_subj_label(const u64 oldinode, const dev_t olddevice, ++ const u64 newinode, const dev_t newdevice, + struct acl_role_label *role) +{ + unsigned int index = gr_fhash(oldinode, olddevice, role->subj_hash_size); @@ -72409,8 +72445,8 @@ index 0000000..c83525f +} + +static void -+update_inodev_entry(const ino_t oldinode, const dev_t olddevice, -+ const ino_t newinode, const dev_t newdevice) ++update_inodev_entry(const u64 oldinode, const dev_t olddevice, ++ const u64 newinode, const dev_t newdevice) +{ + unsigned int index = gr_fhash(oldinode, olddevice, running_polstate.inodev_set.i_size); + struct inodev_entry *match; @@ -72446,7 +72482,7 @@ index 0000000..c83525f +} + +static void -+__do_handle_create(const struct name_entry *matchn, ino_t ino, dev_t dev) ++__do_handle_create(const struct name_entry *matchn, u64 ino, dev_t dev) +{ + struct acl_subject_label *subj; + struct acl_role_label *role; @@ -72479,7 +72515,7 @@ index 0000000..c83525f +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry, + const struct vfsmount *mnt) +{ -+ ino_t ino = dentry->d_inode->i_ino; ++ u64 ino = __get_ino(dentry); + dev_t dev = __get_dev(dentry); + + __do_handle_create(matchn, ino, dev); @@ -72538,7 +72574,7 @@ index 0000000..c83525f + struct name_entry *matchn; + struct inodev_entry *inodev; + struct inode *inode = new_dentry->d_inode; -+ ino_t old_ino = old_dentry->d_inode->i_ino; ++ u64 old_ino = __get_ino(old_dentry); + dev_t old_dev = __get_dev(old_dentry); + + /* vfs_rename swaps the name and parent link for old_dentry and @@ -72561,7 +72597,7 @@ index 0000000..c83525f + + write_lock(&gr_inode_lock); + if (unlikely(replace && inode)) { -+ ino_t new_ino = inode->i_ino; ++ u64 new_ino = __get_ino(new_dentry); + dev_t new_dev = __get_dev(new_dentry); + + inodev = lookup_inodev_entry(new_ino, new_dev); @@ -73018,7 +73054,7 @@ index 0000000..c83525f + return 0; +} + -+int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino) ++int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const u64 ino) +{ + struct task_struct *task = current; + struct dentry *dentry = file->f_path.dentry; @@ -73363,10 +73399,10 @@ index 0000000..1a94c11 + diff --git a/grsecurity/gracl_compat.c b/grsecurity/gracl_compat.c new file mode 100644 -index 0000000..ca25605 +index 0000000..a43dd06 --- /dev/null +++ b/grsecurity/gracl_compat.c -@@ -0,0 +1,270 @@ +@@ -0,0 +1,269 @@ +#include <linux/kernel.h> +#include <linux/gracl.h> +#include <linux/compat.h> @@ -73381,8 +73417,7 @@ index 0000000..ca25605 + if (copy_from_user(&uwrapcompat, buf, sizeof(uwrapcompat))) + return -EFAULT; + -+ if (((uwrapcompat.version != GRSECURITY_VERSION) && -+ (uwrapcompat.version != 0x2901)) || ++ if ((uwrapcompat.version != GRSECURITY_VERSION) || + (uwrapcompat.size != sizeof(struct gr_arg_compat))) + return -EINVAL; + @@ -74689,10 +74724,10 @@ index 0000000..25f54ef +}; diff --git a/grsecurity/gracl_policy.c b/grsecurity/gracl_policy.c new file mode 100644 -index 0000000..7949dcd +index 0000000..fd26052 --- /dev/null +++ b/grsecurity/gracl_policy.c -@@ -0,0 +1,1782 @@ +@@ -0,0 +1,1781 @@ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/sched.h> @@ -74772,8 +74807,8 @@ index 0000000..7949dcd +extern void insert_acl_subj_label(struct acl_subject_label *obj, struct acl_role_label *role); +extern struct name_entry * __lookup_name_entry(const struct gr_policy_state *state, const char *name); +extern char *gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt); -+extern struct acl_subject_label *lookup_acl_subj_label(const ino_t ino, const dev_t dev, const struct acl_role_label *role); -+extern struct acl_subject_label *lookup_acl_subj_label_deleted(const ino_t ino, const dev_t dev, const struct acl_role_label *role); ++extern struct acl_subject_label *lookup_acl_subj_label(const u64 ino, const dev_t dev, const struct acl_role_label *role); ++extern struct acl_subject_label *lookup_acl_subj_label_deleted(const u64 ino, const dev_t dev, const struct acl_role_label *role); +extern void assign_special_role(const char *rolename); +extern struct acl_subject_label *chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt, const struct acl_role_label *role); +extern int gr_rbac_disable(void *unused); @@ -74856,8 +74891,7 @@ index 0000000..7949dcd + if (copy_from_user(uwrap, buf, sizeof (struct gr_arg_wrapper))) + return -EFAULT; + -+ if (((uwrap->version != GRSECURITY_VERSION) && -+ (uwrap->version != 0x2901)) || ++ if ((uwrap->version != GRSECURITY_VERSION) || + (uwrap->size != sizeof(struct gr_arg))) + return -EINVAL; + @@ -75042,7 +75076,7 @@ index 0000000..7949dcd +} + +static int -+insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted) ++insert_name_entry(char *name, const u64 inode, const dev_t device, __u8 deleted) +{ + struct name_entry **curr, *nentry; + struct inodev_entry *ientry; @@ -76551,10 +76585,10 @@ index 0000000..39645c9 +} diff --git a/grsecurity/gracl_segv.c b/grsecurity/gracl_segv.c new file mode 100644 -index 0000000..2040e61 +index 0000000..218b66b --- /dev/null +++ b/grsecurity/gracl_segv.c -@@ -0,0 +1,313 @@ +@@ -0,0 +1,324 @@ +#include <linux/kernel.h> +#include <linux/mm.h> +#include <asm/uaccess.h> @@ -76585,7 +76619,7 @@ index 0000000..2040e61 +static DEFINE_SPINLOCK(gr_uid_lock); +extern rwlock_t gr_inode_lock; +extern struct acl_subject_label * -+ lookup_acl_subj_label(const ino_t inode, const dev_t dev, ++ lookup_acl_subj_label(const u64 inode, const dev_t dev, + struct acl_role_label *role); + +static inline dev_t __get_dev(const struct dentry *dentry) @@ -76598,6 +76632,16 @@ index 0000000..2040e61 + return dentry->d_sb->s_dev; +} + ++static inline u64 __get_ino(const struct dentry *dentry) ++{ ++#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE) ++ if (dentry->d_sb->s_magic == BTRFS_SUPER_MAGIC) ++ return btrfs_ino(dentry->d_inode); ++ else ++#endif ++ return dentry->d_inode->i_ino; ++} ++ +int +gr_init_uidset(void) +{ @@ -76818,13 +76862,14 @@ index 0000000..2040e61 +gr_check_crash_exec(const struct file *filp) +{ + struct acl_subject_label *curr; ++ struct dentry *dentry; + + if (unlikely(!gr_acl_is_enabled())) + return 0; + + read_lock(&gr_inode_lock); -+ curr = lookup_acl_subj_label(filp->f_path.dentry->d_inode->i_ino, -+ __get_dev(filp->f_path.dentry), ++ dentry = filp->f_path.dentry; ++ curr = lookup_acl_subj_label(__get_ino(dentry), __get_dev(dentry), + current->role); + read_unlock(&gr_inode_lock); + @@ -76941,10 +76986,10 @@ index 0000000..bc0be01 +} diff --git a/grsecurity/grsec_chroot.c b/grsecurity/grsec_chroot.c new file mode 100644 -index 0000000..baa635c +index 0000000..2a43673 --- /dev/null +++ b/grsecurity/grsec_chroot.c -@@ -0,0 +1,387 @@ +@@ -0,0 +1,469 @@ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/sched.h> @@ -76960,6 +77005,88 @@ index 0000000..baa635c +int gr_init_ran; +#endif + ++void gr_inc_chroot_refcnts(struct dentry *dentry, struct vfsmount *mnt) ++{ ++#ifdef CONFIG_GRKERNSEC_CHROOT_RENAME ++ struct dentry *tmpd = dentry; ++ ++ read_seqlock_excl(&mount_lock); ++ write_seqlock(&rename_lock); ++ ++ while (tmpd != mnt->mnt_root) { ++ atomic_inc(&tmpd->chroot_refcnt); ++ tmpd = tmpd->d_parent; ++ } ++ atomic_inc(&tmpd->chroot_refcnt); ++ ++ write_sequnlock(&rename_lock); ++ read_sequnlock_excl(&mount_lock); ++#endif ++} ++ ++void gr_dec_chroot_refcnts(struct dentry *dentry, struct vfsmount *mnt) ++{ ++#ifdef CONFIG_GRKERNSEC_CHROOT_RENAME ++ struct dentry *tmpd = dentry; ++ ++ read_seqlock_excl(&mount_lock); ++ write_seqlock(&rename_lock); ++ ++ while (tmpd != mnt->mnt_root) { ++ atomic_dec(&tmpd->chroot_refcnt); ++ tmpd = tmpd->d_parent; ++ } ++ atomic_dec(&tmpd->chroot_refcnt); ++ ++ write_sequnlock(&rename_lock); ++ read_sequnlock_excl(&mount_lock); ++#endif ++} ++ ++#ifdef CONFIG_GRKERNSEC_CHROOT_RENAME ++static struct dentry *get_closest_chroot(struct dentry *dentry) ++{ ++ write_seqlock(&rename_lock); ++ do { ++ if (atomic_read(&dentry->chroot_refcnt)) { ++ write_sequnlock(&rename_lock); ++ return dentry; ++ } ++ dentry = dentry->d_parent; ++ } while (!IS_ROOT(dentry)); ++ write_sequnlock(&rename_lock); ++ return NULL; ++} ++#endif ++ ++int gr_bad_chroot_rename(struct dentry *olddentry, struct vfsmount *oldmnt, ++ struct dentry *newdentry, struct vfsmount *newmnt) ++{ ++#ifdef CONFIG_GRKERNSEC_CHROOT_RENAME ++ struct dentry *chroot; ++ ++ if (unlikely(!grsec_enable_chroot_rename)) ++ return 0; ++ ++ if (likely(!proc_is_chrooted(current) && gr_is_global_root(current_uid()))) ++ return 0; ++ ++ chroot = get_closest_chroot(olddentry); ++ ++ if (chroot == NULL) ++ return 0; ++ ++ if (is_subdir(newdentry, chroot)) ++ return 0; ++ ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_RENAME_MSG, olddentry, oldmnt); ++ ++ return 1; ++#else ++ return 0; ++#endif ++} ++ +void gr_set_chroot_entries(struct task_struct *task, const struct path *path) +{ +#ifdef CONFIG_GRKERNSEC @@ -77334,10 +77461,10 @@ index 0000000..baa635c +} diff --git a/grsecurity/grsec_disabled.c b/grsecurity/grsec_disabled.c new file mode 100644 -index 0000000..1e028d7 +index 0000000..7e8cbe4 --- /dev/null +++ b/grsecurity/grsec_disabled.c -@@ -0,0 +1,439 @@ +@@ -0,0 +1,444 @@ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/sched.h> @@ -77459,7 +77586,7 @@ index 0000000..1e028d7 +} + +void -+gr_handle_delete(const ino_t ino, const dev_t dev) ++gr_handle_delete(const u64 ino, const dev_t dev) +{ + return; +} @@ -77659,7 +77786,7 @@ index 0000000..1e028d7 + +int +gr_acl_handle_filldir(const struct file *file, const char *name, -+ const int namelen, const ino_t ino) ++ const int namelen, const u64 ino) +{ + return 1; +} @@ -77768,6 +77895,11 @@ index 0000000..1e028d7 + return dentry->d_sb->s_dev; +} + ++u64 gr_get_ino_from_dentry(struct dentry *dentry) ++{ ++ return dentry->d_inode->i_ino; ++} ++ +void gr_put_exec_file(struct task_struct *task) +{ + return; @@ -78032,10 +78164,10 @@ index 0000000..8ca18bf +} diff --git a/grsecurity/grsec_init.c b/grsecurity/grsec_init.c new file mode 100644 -index 0000000..b7cb191 +index 0000000..4ed9e7d --- /dev/null +++ b/grsecurity/grsec_init.c -@@ -0,0 +1,286 @@ +@@ -0,0 +1,290 @@ +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> @@ -78078,6 +78210,7 @@ index 0000000..b7cb191 +int grsec_enable_chroot_nice; +int grsec_enable_chroot_execlog; +int grsec_enable_chroot_caps; ++int grsec_enable_chroot_rename; +int grsec_enable_chroot_sysctl; +int grsec_enable_chroot_unix; +int grsec_enable_tpe; @@ -78289,6 +78422,9 @@ index 0000000..b7cb191 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS + grsec_enable_chroot_caps = 1; +#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_RENAME ++ grsec_enable_chroot_rename = 1; ++#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL + grsec_enable_chroot_sysctl = 1; +#endif @@ -79519,10 +79655,10 @@ index 0000000..e3650b6 +} diff --git a/grsecurity/grsec_sysctl.c b/grsecurity/grsec_sysctl.c new file mode 100644 -index 0000000..8159888 +index 0000000..cce889e --- /dev/null +++ b/grsecurity/grsec_sysctl.c -@@ -0,0 +1,479 @@ +@@ -0,0 +1,488 @@ +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/sysctl.h> @@ -79792,6 +79928,15 @@ index 0000000..8159888 + .proc_handler = &proc_dointvec, + }, +#endif ++#ifdef CONFIG_GRKERNSEC_CHROOT_RENAME ++ { ++ .procname = "chroot_deny_bad_rename", ++ .data = &grsec_enable_chroot_rename, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL + { + .procname = "chroot_deny_sysctl", @@ -81319,6 +81464,39 @@ index 2507fd2..55203f8 100644 /* * Mark a position in code as unreachable. This can be used to * suppress control flow warnings after asm blocks that transfer +diff --git a/include/linux/compiler-gcc5.h b/include/linux/compiler-gcc5.h +index cdd1cc2..59dc542 100644 +--- a/include/linux/compiler-gcc5.h ++++ b/include/linux/compiler-gcc5.h +@@ -28,6 +28,28 @@ + # define __compiletime_error(message) __attribute__((error(message))) + #endif /* __CHECKER__ */ + ++#define __alloc_size(...) __attribute((alloc_size(__VA_ARGS__))) ++#define __bos(ptr, arg) __builtin_object_size((ptr), (arg)) ++#define __bos0(ptr) __bos((ptr), 0) ++#define __bos1(ptr) __bos((ptr), 1) ++ ++#ifdef CONSTIFY_PLUGIN ++#error not yet ++#define __no_const __attribute__((no_const)) ++#define __do_const __attribute__((do_const)) ++#endif ++ ++#ifdef SIZE_OVERFLOW_PLUGIN ++#error not yet ++#define __size_overflow(...) __attribute__((size_overflow(__VA_ARGS__))) ++#define __intentional_overflow(...) __attribute__((intentional_overflow(__VA_ARGS__))) ++#endif ++ ++#ifdef LATENT_ENTROPY_PLUGIN ++#error not yet ++#define __latent_entropy __attribute__((latent_entropy)) ++#endif ++ + /* + * Mark a position in code as unreachable. This can be used to + * suppress control flow warnings after asm blocks that transfer diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 2472740..4857634 100644 --- a/include/linux/compiler.h @@ -81675,10 +81853,20 @@ index 653589e..4ef254a 100644 return c | 0x20; } diff --git a/include/linux/dcache.h b/include/linux/dcache.h -index 3b50cac..71a4cec 100644 +index 3b50cac..a3b0c8a 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h -@@ -133,7 +133,7 @@ struct dentry { +@@ -123,6 +123,9 @@ struct dentry { + unsigned long d_time; /* used by d_revalidate */ + void *d_fsdata; /* fs-specific data */ + ++#ifdef CONFIG_GRKERNSEC_CHROOT_RENAME ++ atomic_t chroot_refcnt; /* tracks use of directory in chroot */ ++#endif + struct list_head d_lru; /* LRU list */ + /* + * d_child and d_rcu can share memory +@@ -133,7 +136,7 @@ struct dentry { } d_u; struct list_head d_subdirs; /* our children */ struct hlist_node d_alias; /* inode alias list */ @@ -82133,10 +82321,10 @@ index 3824ac6..f3932a3 100644 { diff --git a/include/linux/gracl.h b/include/linux/gracl.h new file mode 100644 -index 0000000..edb2cb6 +index 0000000..91858e4 --- /dev/null +++ b/include/linux/gracl.h -@@ -0,0 +1,340 @@ +@@ -0,0 +1,342 @@ +#ifndef GR_ACL_H +#define GR_ACL_H + @@ -82148,8 +82336,8 @@ index 0000000..edb2cb6 + +/* Major status information */ + -+#define GR_VERSION "grsecurity 3.0" -+#define GRSECURITY_VERSION 0x3000 ++#define GR_VERSION "grsecurity 3.1" ++#define GRSECURITY_VERSION 0x3100 + +enum { + GR_SHUTDOWN = 0, @@ -82194,7 +82382,7 @@ index 0000000..edb2cb6 + +struct name_entry { + __u32 key; -+ ino_t inode; ++ u64 inode; + dev_t device; + char *name; + __u16 len; @@ -82242,7 +82430,7 @@ index 0000000..edb2cb6 + +struct acl_subject_label { + char *filename; -+ ino_t inode; ++ u64 inode; + dev_t device; + __u32 mode; + kernel_cap_t cap_mask; @@ -82330,7 +82518,7 @@ index 0000000..edb2cb6 + +struct acl_object_label { + char *filename; -+ ino_t inode; ++ u64 inode; + dev_t device; + __u32 mode; + @@ -82366,7 +82554,7 @@ index 0000000..edb2cb6 + unsigned char sp_role[GR_SPROLE_LEN]; + struct sprole_pw *sprole_pws; + dev_t segv_device; -+ ino_t segv_inode; ++ u64 segv_inode; + uid_t segv_uid; + __u16 num_sprole_pws; + __u16 mode; @@ -82438,9 +82626,11 @@ index 0000000..edb2cb6 +} + +static __inline__ unsigned int -+gr_fhash(const ino_t ino, const dev_t dev, const unsigned int sz) ++gr_fhash(const u64 ino, const dev_t dev, const unsigned int sz) +{ -+ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz); ++ unsigned int rem; ++ div_u64_rem((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9)), sz, &rem); ++ return rem; +} + +static __inline__ unsigned int @@ -82479,7 +82669,7 @@ index 0000000..edb2cb6 + diff --git a/include/linux/gracl_compat.h b/include/linux/gracl_compat.h new file mode 100644 -index 0000000..33ebd1f +index 0000000..af64092 --- /dev/null +++ b/include/linux/gracl_compat.h @@ -0,0 +1,156 @@ @@ -82506,7 +82696,7 @@ index 0000000..33ebd1f + +struct acl_subject_label_compat { + compat_uptr_t filename; -+ compat_ino_t inode; ++ compat_u64 inode; + __u32 device; + __u32 mode; + kernel_cap_t cap_mask; @@ -82594,7 +82784,7 @@ index 0000000..33ebd1f + +struct acl_object_label_compat { + compat_uptr_t filename; -+ compat_ino_t inode; ++ compat_u64 inode; + __u32 device; + __u32 mode; + @@ -82626,7 +82816,7 @@ index 0000000..33ebd1f + unsigned char sp_role[GR_SPROLE_LEN]; + compat_uptr_t sprole_pws; + __u32 segv_device; -+ compat_ino_t segv_inode; ++ compat_u64 segv_inode; + uid_t segv_uid; + __u16 num_sprole_pws; + __u16 mode; @@ -82802,10 +82992,10 @@ index 0000000..be66033 +#endif diff --git a/include/linux/grinternal.h b/include/linux/grinternal.h new file mode 100644 -index 0000000..d25522e +index 0000000..fb1de5d --- /dev/null +++ b/include/linux/grinternal.h -@@ -0,0 +1,229 @@ +@@ -0,0 +1,230 @@ +#ifndef __GRINTERNAL_H +#define __GRINTERNAL_H + @@ -82865,6 +83055,7 @@ index 0000000..d25522e +extern int grsec_enable_chroot_nice; +extern int grsec_enable_chroot_execlog; +extern int grsec_enable_chroot_caps; ++extern int grsec_enable_chroot_rename; +extern int grsec_enable_chroot_sysctl; +extern int grsec_enable_chroot_unix; +extern int grsec_enable_symlinkown; @@ -83037,10 +83228,10 @@ index 0000000..d25522e +#endif diff --git a/include/linux/grmsg.h b/include/linux/grmsg.h new file mode 100644 -index 0000000..b02ba9d +index 0000000..26ef560 --- /dev/null +++ b/include/linux/grmsg.h -@@ -0,0 +1,117 @@ +@@ -0,0 +1,118 @@ +#define DEFAULTSECMSG "%.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u, parent %.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u" +#define GR_ACL_PROCACCT_MSG "%.256s[%.16s:%d] IP:%pI4 TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u run time:[%ud %uh %um %us] cpu time:[%ud %uh %um %us] %s with exit code %ld, parent %.256s[%.16s:%d] IP:%pI4 TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u" +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by " @@ -83084,6 +83275,7 @@ index 0000000..b02ba9d +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by " +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by " +#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by " ++#define GR_CHROOT_RENAME_MSG "denied bad rename of %.950s out of a chroot by " +#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by " +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by " +#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by " @@ -83160,10 +83352,10 @@ index 0000000..b02ba9d +#define GR_MSRWRITE_MSG "denied write to CPU MSR by " diff --git a/include/linux/grsecurity.h b/include/linux/grsecurity.h new file mode 100644 -index 0000000..acda855 +index 0000000..0fb332e --- /dev/null +++ b/include/linux/grsecurity.h -@@ -0,0 +1,254 @@ +@@ -0,0 +1,260 @@ +#ifndef GR_SECURITY_H +#define GR_SECURITY_H +#include <linux/fs.h> @@ -83331,7 +83523,7 @@ index 0000000..acda855 + const struct vfsmount *parent_mnt); +__u32 gr_acl_handle_rmdir(const struct dentry *dentry, + const struct vfsmount *mnt); -+void gr_handle_delete(const ino_t ino, const dev_t dev); ++void gr_handle_delete(const u64 ino, const dev_t dev); +__u32 gr_acl_handle_unlink(const struct dentry *dentry, + const struct vfsmount *mnt); +__u32 gr_acl_handle_symlink(const struct dentry *new_dentry, @@ -83360,7 +83552,7 @@ index 0000000..acda855 + const struct dentry *old_dentry, + const struct vfsmount *old_mnt); +int gr_acl_handle_filldir(const struct file *file, const char *name, -+ const unsigned int namelen, const ino_t ino); ++ const unsigned int namelen, const u64 ino); + +__u32 gr_acl_handle_unix(const struct dentry *dentry, + const struct vfsmount *mnt); @@ -83371,6 +83563,7 @@ index 0000000..acda855 +int gr_handle_rofs_blockwrite(struct dentry *dentry, struct vfsmount *mnt, int acc_mode); +void gr_audit_ptrace(struct task_struct *task); +dev_t gr_get_dev_from_dentry(struct dentry *dentry); ++u64 gr_get_ino_from_dentry(struct dentry *dentry); +void gr_put_exec_file(struct task_struct *task); + +int gr_ptrace_readexec(struct file *file, int unsafe_flags); @@ -83387,14 +83580,19 @@ index 0000000..acda855 + +#ifdef CONFIG_GRKERNSEC_RESLOG +extern void gr_log_resource(const struct task_struct *task, const int res, -+ const unsigned long wanted, const int gt); ++ const unsigned long wanted, const int gt); +#else +static inline void gr_log_resource(const struct task_struct *task, const int res, -+ const unsigned long wanted, const int gt) ++ const unsigned long wanted, const int gt) +{ +} +#endif + ++void gr_inc_chroot_refcnts(struct dentry *dentry, struct vfsmount *mnt); ++void gr_dec_chroot_refcnts(struct dentry *dentry, struct vfsmount *mnt); ++int gr_bad_chroot_rename(struct dentry *olddentry, struct vfsmount *oldmnt, ++ struct dentry *newdentry, struct vfsmount *newmnt); ++ +#ifdef CONFIG_GRKERNSEC +void task_grsec_rbac(struct seq_file *m, struct task_struct *p); +void gr_handle_vm86(void); @@ -93826,10 +94024,10 @@ index 52f881d..1e9f941 100644 set_fs(seg); if (ret >= 0 && uoss_ptr) { diff --git a/kernel/smpboot.c b/kernel/smpboot.c -index eb89e18..a4e6792 100644 +index 60d35ac5..59d289f 100644 --- a/kernel/smpboot.c +++ b/kernel/smpboot.c -@@ -288,7 +288,7 @@ int smpboot_register_percpu_thread(struct smp_hotplug_thread *plug_thread) +@@ -289,7 +289,7 @@ int smpboot_register_percpu_thread(struct smp_hotplug_thread *plug_thread) } smpboot_unpark_thread(plug_thread, cpu); } @@ -93837,8 +94035,8 @@ index eb89e18..a4e6792 100644 + pax_list_add(&plug_thread->list, &hotplug_threads); out: mutex_unlock(&smpboot_threads_lock); - return ret; -@@ -305,7 +305,7 @@ void smpboot_unregister_percpu_thread(struct smp_hotplug_thread *plug_thread) + put_online_cpus(); +@@ -307,7 +307,7 @@ void smpboot_unregister_percpu_thread(struct smp_hotplug_thread *plug_thread) { get_online_cpus(); mutex_lock(&smpboot_threads_lock); @@ -97576,7 +97774,7 @@ index b1eb536..091d154 100644 capable(CAP_IPC_LOCK)) ret = do_mlockall(flags); diff --git a/mm/mmap.c b/mm/mmap.c -index 085bcd8..cb98f9f 100644 +index 085bcd8..916b1d4 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -37,6 +37,7 @@ @@ -97641,6 +97839,24 @@ index 085bcd8..cb98f9f 100644 /* * Make sure vm_committed_as in one cacheline and not cacheline shared with * other variables. It can be updated by several CPUs frequently. +@@ -129,7 +150,7 @@ EXPORT_SYMBOL_GPL(vm_memory_committed); + */ + int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) + { +- unsigned long free, allowed, reserve; ++ long free, allowed, reserve; + + vm_acct_memory(pages); + +@@ -193,7 +214,7 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) + */ + if (mm) { + reserve = sysctl_user_reserve_kbytes >> (PAGE_SHIFT - 10); +- allowed -= min(mm->total_vm / 32, reserve); ++ allowed -= min_t(long, mm->total_vm / 32, reserve); + } + + if (percpu_counter_read_positive(&vm_committed_as) < allowed) @@ -247,6 +268,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) struct vm_area_struct *next = vma->vm_next; @@ -99169,7 +99385,7 @@ index 05f1180..c3cde48 100644 out: if (ret & ~PAGE_MASK) diff --git a/mm/nommu.c b/mm/nommu.c -index 3ee4f74..9f4fdd8 100644 +index 3ee4f74..d79b8e2 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -66,7 +66,6 @@ int sysctl_max_map_count = DEFAULT_MAX_MAP_COUNT; @@ -99204,6 +99420,24 @@ index 3ee4f74..9f4fdd8 100644 *region = *vma->vm_region; new->vm_region = region; +@@ -1905,7 +1896,7 @@ EXPORT_SYMBOL(unmap_mapping_range); + */ + int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) + { +- unsigned long free, allowed, reserve; ++ long free, allowed, reserve; + + vm_acct_memory(pages); + +@@ -1969,7 +1960,7 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) + */ + if (mm) { + reserve = sysctl_user_reserve_kbytes >> (PAGE_SHIFT - 10); +- allowed -= min(mm->total_vm / 32, reserve); ++ allowed -= min_t(long, mm->total_vm / 32, reserve); + } + + if (percpu_counter_read_positive(&vm_committed_as) < allowed) @@ -2001,8 +1992,8 @@ int generic_file_remap_pages(struct vm_area_struct *vma, unsigned long addr, } EXPORT_SYMBOL(generic_file_remap_pages); @@ -108537,14 +108771,14 @@ index 078fe1d..fbdb363 100644 fprintf(stderr, "fixdep: sizeof(int) != 4 or wrong endianness? %#x\n", diff --git a/scripts/gcc-plugin.sh b/scripts/gcc-plugin.sh new file mode 100644 -index 0000000..42018ed +index 0000000..822fa9e --- /dev/null +++ b/scripts/gcc-plugin.sh @@ -0,0 +1,51 @@ +#!/bin/sh +srctree=$(dirname "$0") +gccplugins_dir=$($3 -print-file-name=plugin) -+plugincc=$($1 -E - -o /dev/null -I${srctree}/../tools/gcc -I${gccplugins_dir}/include 2>&1 <<EOF ++plugincc=$($1 -E - -o /dev/null -I"${srctree}"/../tools/gcc -I"${gccplugins_dir}"/include 2>&1 <<EOF +#include "gcc-common.h" +#if BUILDING_GCC_VERSION >= 4008 || defined(ENABLE_BUILD_WITH_CXX) +#warning $2 CXX @@ -108575,7 +108809,7 @@ index 0000000..42018ed +esac + +# we need a c++ compiler that supports the designated initializer GNU extension -+plugincc=$($2 -c -x c++ -std=gnu++98 - -fsyntax-only -I${srctree}/../tools/gcc -I${gccplugins_dir}/include 2>&1 <<EOF ++plugincc=$($2 -c -x c++ -std=gnu++98 - -fsyntax-only -I"${srctree}"/../tools/gcc -I"${gccplugins_dir}"/include 2>&1 <<EOF +#include "gcc-common.h" +class test { +public: @@ -110263,6 +110497,18 @@ index cee72ce..e46074a 100644 err: if (iov != iovstack) kfree(iov); +diff --git a/security/keys/request_key.c b/security/keys/request_key.c +index 3814119..2e8ebaa 100644 +--- a/security/keys/request_key.c ++++ b/security/keys/request_key.c +@@ -432,6 +432,7 @@ link_check_failed: + + link_prealloc_failed: + mutex_unlock(&user->cons_lock); ++ key_put(key); + kleave(" = %d [prelink]", ret); + return ret; + diff --git a/security/min_addr.c b/security/min_addr.c index f728728..6457a0c 100644 --- a/security/min_addr.c |