summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2012-11-24 07:49:18 -0500
committerAnthony G. Basile <blueness@gentoo.org>2012-11-24 07:49:18 -0500
commitd88a7209c49fbf714f2805ed8851059410365ebb (patch)
tree78fa916a9275a41d5e1182e60817fe3b1dc8ef9c
parentGrsec/PaX: 2.9.1-{2.6.32.60,3.2.34,3.6.7}-201211181105 (diff)
downloadhardened-patchset-20121122.tar.gz
hardened-patchset-20121122.tar.bz2
hardened-patchset-20121122.zip
Grsec/PaX: 2.9.1-{2.6.32.60,3.2.34,3.6.7}-20121122100020121122
-rw-r--r--2.6.32/0000_README2
-rw-r--r--2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201211220959.patch (renamed from 2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201211181103.patch)99
-rw-r--r--3.2.34/0000_README2
-rw-r--r--3.2.34/4420_grsecurity-2.9.1-3.2.34-201211220959.patch (renamed from 3.2.34/4420_grsecurity-2.9.1-3.2.34-201211181104.patch)324
-rw-r--r--3.6.7/0000_README2
-rw-r--r--3.6.7/4420_grsecurity-2.9.1-3.6.7-201211221000.patch (renamed from 3.6.7/4420_grsecurity-2.9.1-3.6.7-201211181105.patch)340
6 files changed, 618 insertions, 151 deletions
diff --git a/2.6.32/0000_README b/2.6.32/0000_README
index 00e77a9..424bb70 100644
--- a/2.6.32/0000_README
+++ b/2.6.32/0000_README
@@ -34,7 +34,7 @@ Patch: 1059_linux-2.6.32.60.patch
From: http://www.kernel.org
Desc: Linux 2.6.32.59
-Patch: 4420_grsecurity-2.9.1-2.6.32.60-201211181103.patch
+Patch: 4420_grsecurity-2.9.1-2.6.32.60-201211220959.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201211181103.patch b/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201211220959.patch
index 4688218..8492134 100644
--- a/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201211181103.patch
+++ b/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201211220959.patch
@@ -77942,7 +77942,7 @@ index a24c58e..53f91ee 100644
if (dot && fs && !(fs->fs_flags & FS_HAS_SUBTYPE)) {
diff --git a/fs/fs_struct.c b/fs/fs_struct.c
-index eee0590..0a5b2ee 100644
+index eee0590..34791ce 100644
--- a/fs/fs_struct.c
+++ b/fs/fs_struct.c
@@ -4,6 +4,7 @@
@@ -77975,7 +77975,14 @@ index eee0590..0a5b2ee 100644
count++;
}
if (fs->pwd.dentry == old_root->dentry
-@@ -89,7 +98,8 @@ void exit_fs(struct task_struct *tsk)
+@@ -84,12 +93,15 @@ void exit_fs(struct task_struct *tsk)
+ {
+ struct fs_struct *fs = tsk->fs;
+
++ gr_put_exec_file(tsk);
++
+ if (fs) {
+ int kill;
task_lock(tsk);
write_lock(&fs->lock);
tsk->fs = NULL;
@@ -77985,7 +77992,7 @@ index eee0590..0a5b2ee 100644
write_unlock(&fs->lock);
task_unlock(tsk);
if (kill)
-@@ -102,7 +112,7 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
+@@ -102,7 +114,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) {
@@ -77994,7 +78001,7 @@ index eee0590..0a5b2ee 100644
fs->in_exec = 0;
rwlock_init(&fs->lock);
fs->umask = old->umask;
-@@ -127,8 +137,9 @@ int unshare_fs_struct(void)
+@@ -127,8 +139,9 @@ int unshare_fs_struct(void)
task_lock(current);
write_lock(&fs->lock);
@@ -78005,7 +78012,7 @@ index eee0590..0a5b2ee 100644
write_unlock(&fs->lock);
task_unlock(current);
-@@ -141,13 +152,13 @@ EXPORT_SYMBOL_GPL(unshare_fs_struct);
+@@ -141,13 +154,13 @@ EXPORT_SYMBOL_GPL(unshare_fs_struct);
int current_umask(void)
{
@@ -78021,7 +78028,15 @@ index eee0590..0a5b2ee 100644
.lock = __RW_LOCK_UNLOCKED(init_fs.lock),
.umask = 0022,
};
-@@ -162,12 +173,13 @@ void daemonize_fs_struct(void)
+@@ -156,18 +169,21 @@ void daemonize_fs_struct(void)
+ {
+ struct fs_struct *fs = current->fs;
+
++ gr_put_exec_file(current);
++
+ if (fs) {
+ int kill;
+
task_lock(current);
write_lock(&init_fs.lock);
@@ -84700,10 +84715,10 @@ index 0000000..1b9afa9
+endif
diff --git a/grsecurity/gracl.c b/grsecurity/gracl.c
new file mode 100644
-index 0000000..42c1316
+index 0000000..a4c751d
--- /dev/null
+++ b/grsecurity/gracl.c
-@@ -0,0 +1,4198 @@
+@@ -0,0 +1,4214 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
@@ -88892,6 +88907,22 @@ index 0000000..42c1316
+ return (obj->mode & GR_FIND) ? 1 : 0;
+}
+
++void gr_put_exec_file(struct task_struct *task)
++{
++ struct file *filp;
++
++ write_lock(&grsec_exec_file_lock);
++ filp = task->exec_file;
++ task->exec_file = NULL;
++ write_unlock(&grsec_exec_file_lock);
++
++ if (filp)
++ fput(filp);
++
++ return;
++}
++
++
+#ifdef CONFIG_NETFILTER_XT_MATCH_GRADM_MODULE
+EXPORT_SYMBOL(gr_acl_is_enabled);
+#endif
@@ -90996,10 +91027,10 @@ index 0000000..197bdd5
+}
diff --git a/grsecurity/grsec_disabled.c b/grsecurity/grsec_disabled.c
new file mode 100644
-index 0000000..40545bf
+index 0000000..7a358f8
--- /dev/null
+++ b/grsecurity/grsec_disabled.c
-@@ -0,0 +1,437 @@
+@@ -0,0 +1,442 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
@@ -91431,6 +91462,11 @@ index 0000000..40545bf
+ return dentry->d_inode->i_sb->s_dev;
+}
+
++void gr_put_exec_file(struct task_struct *task)
++{
++ return;
++}
++
+EXPORT_SYMBOL(gr_learn_resource);
+EXPORT_SYMBOL(gr_set_kernel_label);
+#ifdef CONFIG_SECURITY
@@ -96665,10 +96701,10 @@ index 0000000..ac88734
+#define GR_SYMLINKOWNER_MSG "denied following symlink %.950s since symlink owner %u does not match target owner %u, by "
diff --git a/include/linux/grsecurity.h b/include/linux/grsecurity.h
new file mode 100644
-index 0000000..d44d8a6
+index 0000000..0e2a522
--- /dev/null
+++ b/include/linux/grsecurity.h
-@@ -0,0 +1,225 @@
+@@ -0,0 +1,226 @@
+#ifndef GR_SECURITY_H
+#define GR_SECURITY_H
+#include <linux/fs.h>
@@ -96868,6 +96904,7 @@ index 0000000..d44d8a6
+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);
++void gr_put_exec_file(struct task_struct *task);
+
+int gr_ptrace_readexec(struct file *file, int unsafe_flags);
+
@@ -101636,21 +101673,10 @@ index 9c06d10..5b211dc 100644
if (ret < 0)
return ret;
diff --git a/kernel/exit.c b/kernel/exit.c
-index a2a1659..66af9b1 100644
+index a2a1659..55ff5d7 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
-@@ -55,6 +55,10 @@
- #include <asm/pgtable.h>
- #include <asm/mmu_context.h>
-
-+#ifdef CONFIG_GRKERNSEC
-+extern rwlock_t grsec_exec_file_lock;
-+#endif
-+
- static void exit_mm(struct task_struct * tsk);
-
- static void __unhash_process(struct task_struct *p)
-@@ -174,6 +178,10 @@ void release_task(struct task_struct * p)
+@@ -174,6 +174,10 @@ void release_task(struct task_struct * p)
struct task_struct *leader;
int zap_leader;
repeat:
@@ -101661,7 +101687,7 @@ index a2a1659..66af9b1 100644
tracehook_prepare_release_task(p);
/* don't need to get the RCU readlock here - the process is dead and
* can't be modifying its own credentials */
-@@ -397,7 +405,7 @@ int allow_signal(int sig)
+@@ -397,7 +401,7 @@ int allow_signal(int sig)
* know it'll be handled, so that they don't get converted to
* SIGKILL or just silently dropped.
*/
@@ -101670,25 +101696,16 @@ index a2a1659..66af9b1 100644
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
return 0;
-@@ -433,6 +441,17 @@ void daemonize(const char *name, ...)
+@@ -433,6 +437,8 @@ void daemonize(const char *name, ...)
vsnprintf(current->comm, sizeof(current->comm), name, args);
va_end(args);
-+#ifdef CONFIG_GRKERNSEC
-+ write_lock(&grsec_exec_file_lock);
-+ if (current->exec_file) {
-+ fput(current->exec_file);
-+ current->exec_file = NULL;
-+ }
-+ write_unlock(&grsec_exec_file_lock);
-+#endif
-+
+ gr_set_kernel_label(current);
+
/*
* If we were started as result of loading a module, close all of the
* user space pages. We don't need them, and if we didn't close them
-@@ -897,17 +916,17 @@ NORET_TYPE void do_exit(long code)
+@@ -897,17 +903,17 @@ NORET_TYPE void do_exit(long code)
struct task_struct *tsk = current;
int group_dead;
@@ -101713,7 +101730,7 @@ index a2a1659..66af9b1 100644
* that get_fs() was left as KERNEL_DS, so reset it to USER_DS before
* continuing. Amongst other possible reasons, this is to prevent
* mm_release()->clear_child_tid() from writing to a user-controlled
-@@ -915,6 +934,13 @@ NORET_TYPE void do_exit(long code)
+@@ -915,6 +921,13 @@ NORET_TYPE void do_exit(long code)
*/
set_fs(USER_DS);
@@ -101727,7 +101744,7 @@ index a2a1659..66af9b1 100644
tracehook_report_exit(&code);
validate_creds_for_do_exit(tsk);
-@@ -973,6 +999,9 @@ NORET_TYPE void do_exit(long code)
+@@ -973,6 +986,9 @@ NORET_TYPE void do_exit(long code)
tsk->exit_code = code;
taskstats_exit(tsk, group_dead);
@@ -101737,7 +101754,7 @@ index a2a1659..66af9b1 100644
exit_mm(tsk);
if (group_dead)
-@@ -1059,7 +1088,7 @@ SYSCALL_DEFINE1(exit, int, error_code)
+@@ -1059,7 +1075,7 @@ SYSCALL_DEFINE1(exit, int, error_code)
* Take down every thread in the group. This is called by fatal signals
* as well as by sys_exit_group (below).
*/
@@ -101746,7 +101763,7 @@ index a2a1659..66af9b1 100644
do_group_exit(int exit_code)
{
struct signal_struct *sig = current->signal;
-@@ -1188,7 +1217,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
+@@ -1188,7 +1204,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
if (unlikely(wo->wo_flags & WNOWAIT)) {
int exit_code = p->exit_code;
diff --git a/3.2.34/0000_README b/3.2.34/0000_README
index 0896e71..5f22bbb 100644
--- a/3.2.34/0000_README
+++ b/3.2.34/0000_README
@@ -54,7 +54,7 @@ Patch: 1033_linux-3.2.34.patch
From: http://www.kernel.org
Desc: Linux 3.2.34
-Patch: 4420_grsecurity-2.9.1-3.2.34-201211181104.patch
+Patch: 4420_grsecurity-2.9.1-3.2.34-201211220959.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/3.2.34/4420_grsecurity-2.9.1-3.2.34-201211181104.patch b/3.2.34/4420_grsecurity-2.9.1-3.2.34-201211220959.patch
index 08bfa63..f917c5d 100644
--- a/3.2.34/4420_grsecurity-2.9.1-3.2.34-201211181104.patch
+++ b/3.2.34/4420_grsecurity-2.9.1-3.2.34-201211220959.patch
@@ -26314,10 +26314,139 @@ index 6687022..ceabcfa 100644
+ pax_force_retaddr
ret
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
-index 5a5b6e4..201d42e 100644
+index 5a5b6e4..2265c0f 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
-@@ -117,6 +117,10 @@ static inline void bpf_flush_icache(void *start, void *end)
+@@ -11,6 +11,7 @@
+ #include <asm/cacheflush.h>
+ #include <linux/netdevice.h>
+ #include <linux/filter.h>
++#include <linux/random.h>
+
+ /*
+ * Conventions :
+@@ -45,13 +46,87 @@ static inline u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len)
+ return ptr + len;
+ }
+
++#ifdef CONFIG_GRKERNSEC_JIT_HARDEN
++#define MAX_INSTR_CODE_SIZE 96
++#else
++#define MAX_INSTR_CODE_SIZE 64
++#endif
++
+ #define EMIT(bytes, len) do { prog = emit_code(prog, bytes, len); } while (0)
+
+ #define EMIT1(b1) EMIT(b1, 1)
+ #define EMIT2(b1, b2) EMIT((b1) + ((b2) << 8), 2)
+ #define EMIT3(b1, b2, b3) EMIT((b1) + ((b2) << 8) + ((b3) << 16), 3)
+ #define EMIT4(b1, b2, b3, b4) EMIT((b1) + ((b2) << 8) + ((b3) << 16) + ((b4) << 24), 4)
++
++#ifdef CONFIG_GRKERNSEC_JIT_HARDEN
++/* original constant will appear in ecx */
++#define DILUTE_CONST_SEQUENCE(_off, _key) \
++do { \
++ /* mov ecx, randkey */ \
++ EMIT1(0xb9); \
++ EMIT(_key, 4); \
++ /* xor ecx, randkey ^ off */ \
++ EMIT2(0x81, 0xf1); \
++ EMIT((_key) ^ (_off), 4); \
++} while (0)
++
++#define EMIT1_off32(b1, _off) \
++do { \
++ switch (b1) { \
++ case 0x05: /* add eax, imm32 */ \
++ case 0x2d: /* sub eax, imm32 */ \
++ case 0x25: /* and eax, imm32 */ \
++ case 0x0d: /* or eax, imm32 */ \
++ case 0xb8: /* mov 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 0xbb: /* mov ebx, imm32 */ \
++ DILUTE_CONST_SEQUENCE(_off, randkey); \
++ /* mov ebx, ecx */ \
++ EMIT2(0x89, 0xcb); \
++ break; \
++ case 0xbe: /* mov esi, imm32 */ \
++ DILUTE_CONST_SEQUENCE(_off, randkey); \
++ /* mov esi, ecx */ \
++ EMIT2(0x89, 0xce); \
++ break; \
++ case 0xe9: /* jmp rel imm32 */ \
++ EMIT1(b1); \
++ EMIT(_off, 4); \
++ /* prevent fall-through, we're not called if off = 0 */ \
++ EMIT(0xcccccccc, 4); \
++ EMIT(0xcccccccc, 4); \
++ break; \
++ default: \
++ EMIT1(b1); \
++ EMIT(_off, 4); \
++ } \
++} while (0)
++
++#define EMIT2_off32(b1, b2, _off) \
++do { \
++ if ((b1) == 0x8d && (b2) == 0xb3) { /* lea esi, [rbx+imm32] */ \
++ EMIT2(0x8d, 0xb3); /* lea esi, [rbx+randkey] */ \
++ EMIT(randkey, 4); \
++ EMIT2(0x8d, 0xb6); /* lea esi, [esi+off-randkey] */ \
++ EMIT((_off) - randkey, 4); \
++ } else if ((b1) == 0x69 && (b2) == 0xc0) { /* imul eax, imm32 */\
++ DILUTE_CONST_SEQUENCE(_off, randkey); \
++ /* imul eax, ecx */ \
++ EMIT3(0x0f, 0xaf, 0xc1); \
++ } else { \
++ EMIT2(b1, b2); \
++ EMIT(_off, 4); \
++ } \
++} while (0)
++#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)
++#endif
+
+ #define CLEAR_A() EMIT2(0x31, 0xc0) /* xor %eax,%eax */
+ #define CLEAR_X() EMIT2(0x31, 0xdb) /* xor %ebx,%ebx */
+@@ -86,6 +161,24 @@ do { \
+ #define X86_JBE 0x76
+ #define X86_JA 0x77
+
++#ifdef CONFIG_GRKERNSEC_JIT_HARDEN
++#define APPEND_FLOW_VERIFY() \
++do { \
++ /* mov ecx, randkey */ \
++ EMIT1(0xb9); \
++ EMIT(randkey, 4); \
++ /* cmp ecx, randkey */ \
++ EMIT2(0x81, 0xf9); \
++ EMIT(randkey, 4); \
++ /* jz after 8 int 3s */ \
++ EMIT2(0x74, 0x08); \
++ EMIT(0xcccccccc, 4); \
++ EMIT(0xcccccccc, 4); \
++} while (0)
++#else
++#define APPEND_FLOW_VERIFY() do { } while (0)
++#endif
++
+ #define EMIT_COND_JMP(op, offset) \
+ do { \
+ if (is_near(offset)) \
+@@ -93,6 +186,7 @@ do { \
+ else { \
+ EMIT2(0x0f, op + 0x10); \
+ EMIT(offset, 4); /* jxx .+off32 */ \
++ APPEND_FLOW_VERIFY(); \
+ } \
+ } while (0)
+
+@@ -117,10 +211,14 @@ static inline void bpf_flush_icache(void *start, void *end)
set_fs(old_fs);
}
@@ -26328,7 +26457,22 @@ index 5a5b6e4..201d42e 100644
void bpf_jit_compile(struct sk_filter *fp)
{
-@@ -141,6 +145,10 @@ void bpf_jit_compile(struct sk_filter *fp)
+- u8 temp[64];
++ u8 temp[MAX_INSTR_CODE_SIZE];
+ u8 *prog;
+ unsigned int proglen, oldproglen = 0;
+ int ilen, i;
+@@ -133,6 +231,9 @@ void bpf_jit_compile(struct sk_filter *fp)
+ unsigned int *addrs;
+ const struct sock_filter *filter = fp->insns;
+ int flen = fp->len;
++#ifdef CONFIG_GRKERNSEC_JIT_HARDEN
++ unsigned int randkey;
++#endif
+
+ if (!bpf_jit_enable)
+ return;
+@@ -141,11 +242,19 @@ void bpf_jit_compile(struct sk_filter *fp)
if (addrs == NULL)
return;
@@ -26336,10 +26480,49 @@ index 5a5b6e4..201d42e 100644
+ if (!fp->work)
+ goto out;
+
++#ifdef CONFIG_GRKERNSEC_JIT_HARDEN
++ randkey = get_random_int();
++#endif
++
/* Before first pass, make a rough estimation of addrs[]
- * each bpf instruction is translated to less than 64 bytes
+- * each bpf instruction is translated to less than 64 bytes
++ * each bpf instruction is translated to less than MAX_INSTR_CODE_SIZE bytes
*/
-@@ -477,7 +485,7 @@ void bpf_jit_compile(struct sk_filter *fp)
+ for (proglen = 0, i = 0; i < flen; i++) {
+- proglen += 64;
++ proglen += MAX_INSTR_CODE_SIZE;
+ addrs[i] = proglen;
+ }
+ cleanup_addr = proglen; /* epilogue address */
+@@ -253,10 +362,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 */
+- else {
+- EMIT2(0x69, 0xc0); /* imul imm32,%eax */
+- EMIT(K, 4);
+- }
++ else
++ EMIT2_off32(0x69, 0xc0, K); /* imul imm32,%eax */
+ break;
+ case BPF_S_ALU_DIV_X: /* A /= X; */
+ seen |= SEEN_XREG;
+@@ -276,8 +383,14 @@ void bpf_jit_compile(struct sk_filter *fp)
+ EMIT4(0x31, 0xd2, 0xf7, 0xf3); /* xor %edx,%edx; div %ebx */
+ break;
+ case BPF_S_ALU_DIV_K: /* A = reciprocal_divide(A, K); */
++#ifdef CONFIG_GRKERNSEC_JIT_HARDEN
++ DILUTE_CONST_SEQUENCE(K, randkey);
++ // imul rax, rcx
++ EMIT4(0x48, 0x0f, 0xaf, 0xc1);
++#else
+ EMIT3(0x48, 0x69, 0xc0); /* imul imm32,%rax,%rax */
+ EMIT(K, 4);
++#endif
+ EMIT4(0x48, 0xc1, 0xe8, 0x20); /* shr $0x20,%rax */
+ break;
+ case BPF_S_ALU_AND_X:
+@@ -477,7 +590,7 @@ void bpf_jit_compile(struct sk_filter *fp)
common_load: seen |= SEEN_DATAREF;
if ((int)K < 0) {
/* Abort the JIT because __load_pointer() is needed. */
@@ -26348,7 +26531,7 @@ index 5a5b6e4..201d42e 100644
}
t_offset = func - (image + addrs[i]);
EMIT1_off32(0xbe, K); /* mov imm32,%esi */
-@@ -492,7 +500,7 @@ common_load: seen |= SEEN_DATAREF;
+@@ -492,7 +605,7 @@ common_load: seen |= SEEN_DATAREF;
case BPF_S_LDX_B_MSH:
if ((int)K < 0) {
/* Abort the JIT because __load_pointer() is needed. */
@@ -26357,7 +26540,7 @@ index 5a5b6e4..201d42e 100644
}
seen |= SEEN_DATAREF | SEEN_XREG;
t_offset = sk_load_byte_msh - (image + addrs[i]);
-@@ -582,17 +590,18 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
+@@ -582,17 +695,18 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
break;
default:
/* hmm, too complex filter, give up with jit compiler */
@@ -26380,7 +26563,7 @@ index 5a5b6e4..201d42e 100644
}
proglen += ilen;
addrs[i] = proglen;
-@@ -613,11 +622,9 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
+@@ -613,11 +727,9 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
break;
}
if (proglen == oldproglen) {
@@ -26394,7 +26577,7 @@ index 5a5b6e4..201d42e 100644
}
oldproglen = proglen;
}
-@@ -633,7 +640,10 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
+@@ -633,7 +745,10 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
bpf_flush_icache(image, image + proglen);
fp->bpf_func = (void *)image;
@@ -26406,7 +26589,7 @@ index 5a5b6e4..201d42e 100644
out:
kfree(addrs);
return;
-@@ -641,18 +651,20 @@ out:
+@@ -641,18 +756,20 @@ out:
static void jit_free_defer(struct work_struct *arg)
{
@@ -46415,7 +46598,7 @@ index 0845f84..7b4ebef 100644
if (dot && fs && !(fs->fs_flags & FS_HAS_SUBTYPE)) {
diff --git a/fs/fs_struct.c b/fs/fs_struct.c
-index 78b519c..0386555 100644
+index 78b519c..7c6fd17 100644
--- a/fs/fs_struct.c
+++ b/fs/fs_struct.c
@@ -4,6 +4,7 @@
@@ -46448,7 +46631,15 @@ index 78b519c..0386555 100644
count++;
}
if (fs->pwd.dentry == old_root->dentry
-@@ -109,7 +118,8 @@ void exit_fs(struct task_struct *tsk)
+@@ -103,13 +112,16 @@ void exit_fs(struct task_struct *tsk)
+ {
+ struct fs_struct *fs = tsk->fs;
+
++ gr_put_exec_file(tsk);
++
+ if (fs) {
+ int kill;
+ task_lock(tsk);
spin_lock(&fs->lock);
write_seqcount_begin(&fs->seq);
tsk->fs = NULL;
@@ -46458,7 +46649,7 @@ index 78b519c..0386555 100644
write_seqcount_end(&fs->seq);
spin_unlock(&fs->lock);
task_unlock(tsk);
-@@ -123,7 +133,7 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
+@@ -123,7 +135,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) {
@@ -46467,7 +46658,7 @@ index 78b519c..0386555 100644
fs->in_exec = 0;
spin_lock_init(&fs->lock);
seqcount_init(&fs->seq);
-@@ -132,6 +142,9 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
+@@ -132,6 +144,9 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
spin_lock(&old->lock);
fs->root = old->root;
path_get_longterm(&fs->root);
@@ -46477,7 +46668,7 @@ index 78b519c..0386555 100644
fs->pwd = old->pwd;
path_get_longterm(&fs->pwd);
spin_unlock(&old->lock);
-@@ -150,8 +163,9 @@ int unshare_fs_struct(void)
+@@ -150,8 +165,9 @@ int unshare_fs_struct(void)
task_lock(current);
spin_lock(&fs->lock);
@@ -46488,7 +46679,7 @@ index 78b519c..0386555 100644
spin_unlock(&fs->lock);
task_unlock(current);
-@@ -164,13 +178,13 @@ EXPORT_SYMBOL_GPL(unshare_fs_struct);
+@@ -164,13 +180,13 @@ EXPORT_SYMBOL_GPL(unshare_fs_struct);
int current_umask(void)
{
@@ -46504,7 +46695,15 @@ index 78b519c..0386555 100644
.lock = __SPIN_LOCK_UNLOCKED(init_fs.lock),
.seq = SEQCNT_ZERO,
.umask = 0022,
-@@ -186,12 +200,13 @@ void daemonize_fs_struct(void)
+@@ -180,18 +196,21 @@ void daemonize_fs_struct(void)
+ {
+ struct fs_struct *fs = current->fs;
+
++ gr_put_exec_file(current);
++
+ if (fs) {
+ int kill;
+
task_lock(current);
spin_lock(&init_fs.lock);
@@ -51324,10 +51523,10 @@ index 87323f1..dab9d00 100644
ip = issum ? mp->m_rsumip : mp->m_rbmip;
diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig
new file mode 100644
-index 0000000..ae8456d
+index 0000000..b0d5e22
--- /dev/null
+++ b/grsecurity/Kconfig
-@@ -0,0 +1,947 @@
+@@ -0,0 +1,964 @@
+#
+# grecurity configuration
+#
@@ -51390,6 +51589,23 @@ index 0000000..ae8456d
+ IF YOU USE XFree86. If you use XFree86 and you still want to
+ protect your kernel against modification, use the RBAC system.
+
++config GRKERNSEC_JIT_HARDEN
++ bool "Harden BPF JIT against spray attacks"
++ default y if GRKERNSEC_CONFIG_AUTO
++ depends on BPF_JIT
++ help
++ If you say Y here, the native code generated by the kernel's Berkeley
++ Packet Filter (BPF) JIT engine will be hardened against JIT-spraying
++ attacks that attempt to fit attacker-beneficial instructions in
++ 32bit immediate fields of JIT-generated native instructions. The
++ attacker will generally aim to cause an unintended instruction sequence
++ of JIT-generated native code to execute by jumping into the middle of
++ a generated instruction. This feature effectively randomizes the 32bit
++ immediate constants present in the generated code to thwart such attacks.
++
++ If you're using KERNEXEC, it's recommended that you enable this option
++ to supplement the hardening of the kernel.
++
+config GRKERNSEC_PROC_MEMMAP
+ bool "Harden ASLR against information leaks and entropy reduction"
+ default y if (GRKERNSEC_CONFIG_AUTO || PAX_NOEXEC || PAX_ASLR)
@@ -52321,10 +52537,10 @@ index 0000000..1b9afa9
+endif
diff --git a/grsecurity/gracl.c b/grsecurity/gracl.c
new file mode 100644
-index 0000000..7feb2c5
+index 0000000..93f15bf
--- /dev/null
+++ b/grsecurity/gracl.c
-@@ -0,0 +1,4213 @@
+@@ -0,0 +1,4229 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
@@ -56528,6 +56744,22 @@ index 0000000..7feb2c5
+ return (obj->mode & GR_FIND) ? 1 : 0;
+}
+
++void gr_put_exec_file(struct task_struct *task)
++{
++ struct file *filp;
++
++ write_lock(&grsec_exec_file_lock);
++ filp = task->exec_file;
++ task->exec_file = NULL;
++ write_unlock(&grsec_exec_file_lock);
++
++ if (filp)
++ fput(filp);
++
++ return;
++}
++
++
+#ifdef CONFIG_NETFILTER_XT_MATCH_GRADM_MODULE
+EXPORT_SYMBOL(gr_acl_is_enabled);
+#endif
@@ -58611,10 +58843,10 @@ index 0000000..a2dc675
+}
diff --git a/grsecurity/grsec_disabled.c b/grsecurity/grsec_disabled.c
new file mode 100644
-index 0000000..213ad8b
+index 0000000..b79fe50
--- /dev/null
+++ b/grsecurity/grsec_disabled.c
-@@ -0,0 +1,437 @@
+@@ -0,0 +1,442 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
@@ -59046,6 +59278,11 @@ index 0000000..213ad8b
+ return dentry->d_inode->i_sb->s_dev;
+}
+
++void gr_put_exec_file(struct task_struct *task)
++{
++ return;
++}
++
+EXPORT_SYMBOL(gr_learn_resource);
+EXPORT_SYMBOL(gr_set_kernel_label);
+#ifdef CONFIG_SECURITY
@@ -63472,10 +63709,10 @@ index 0000000..54f4e85
+#define GR_SYMLINKOWNER_MSG "denied following symlink %.950s since symlink owner %u does not match target owner %u, by "
diff --git a/include/linux/grsecurity.h b/include/linux/grsecurity.h
new file mode 100644
-index 0000000..c14f3fb
+index 0000000..90ccf22
--- /dev/null
+++ b/include/linux/grsecurity.h
-@@ -0,0 +1,235 @@
+@@ -0,0 +1,236 @@
+#ifndef GR_SECURITY_H
+#define GR_SECURITY_H
+#include <linux/fs.h>
@@ -63685,6 +63922,7 @@ index 0000000..c14f3fb
+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);
++void gr_put_exec_file(struct task_struct *task);
+
+int gr_ptrace_readexec(struct file *file, int unsafe_flags);
+
@@ -68111,21 +68349,10 @@ index 7d1f05e..66d5a8e 100644
/*
diff --git a/kernel/exit.c b/kernel/exit.c
-index 234e152..3600fae 100644
+index 234e152..2e3e7e1 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
-@@ -57,6 +57,10 @@
- #include <asm/pgtable.h>
- #include <asm/mmu_context.h>
-
-+#ifdef CONFIG_GRKERNSEC
-+extern rwlock_t grsec_exec_file_lock;
-+#endif
-+
- static void exit_mm(struct task_struct * tsk);
-
- static void __unhash_process(struct task_struct *p, bool group_dead)
-@@ -168,6 +172,10 @@ void release_task(struct task_struct * p)
+@@ -168,6 +168,10 @@ void release_task(struct task_struct * p)
struct task_struct *leader;
int zap_leader;
repeat:
@@ -68136,7 +68363,7 @@ index 234e152..3600fae 100644
/* don't need to get the RCU readlock here - the process is dead and
* can't be modifying its own credentials. But shut RCU-lockdep up */
rcu_read_lock();
-@@ -380,7 +388,7 @@ int allow_signal(int sig)
+@@ -380,7 +384,7 @@ int allow_signal(int sig)
* know it'll be handled, so that they don't get converted to
* SIGKILL or just silently dropped.
*/
@@ -68145,25 +68372,16 @@ index 234e152..3600fae 100644
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
return 0;
-@@ -416,6 +424,17 @@ void daemonize(const char *name, ...)
+@@ -416,6 +420,8 @@ void daemonize(const char *name, ...)
vsnprintf(current->comm, sizeof(current->comm), name, args);
va_end(args);
-+#ifdef CONFIG_GRKERNSEC
-+ write_lock(&grsec_exec_file_lock);
-+ if (current->exec_file) {
-+ fput(current->exec_file);
-+ current->exec_file = NULL;
-+ }
-+ write_unlock(&grsec_exec_file_lock);
-+#endif
-+
+ gr_set_kernel_label(current);
+
/*
* If we were started as result of loading a module, close all of the
* user space pages. We don't need them, and if we didn't close them
-@@ -874,6 +893,8 @@ NORET_TYPE void do_exit(long code)
+@@ -874,6 +880,8 @@ NORET_TYPE void do_exit(long code)
struct task_struct *tsk = current;
int group_dead;
@@ -68172,7 +68390,7 @@ index 234e152..3600fae 100644
profile_task_exit(tsk);
WARN_ON(blk_needs_flush_plug(tsk));
-@@ -890,7 +911,6 @@ NORET_TYPE void do_exit(long code)
+@@ -890,7 +898,6 @@ NORET_TYPE void do_exit(long code)
* mm_release()->clear_child_tid() from writing to a user-controlled
* kernel address.
*/
@@ -68180,7 +68398,7 @@ index 234e152..3600fae 100644
ptrace_event(PTRACE_EVENT_EXIT, code);
-@@ -952,6 +972,9 @@ NORET_TYPE void do_exit(long code)
+@@ -952,6 +959,9 @@ NORET_TYPE void do_exit(long code)
tsk->exit_code = code;
taskstats_exit(tsk, group_dead);
@@ -68190,7 +68408,7 @@ index 234e152..3600fae 100644
exit_mm(tsk);
if (group_dead)
-@@ -1065,7 +1088,7 @@ SYSCALL_DEFINE1(exit, int, error_code)
+@@ -1065,7 +1075,7 @@ SYSCALL_DEFINE1(exit, int, error_code)
* Take down every thread in the group. This is called by fatal signals
* as well as by sys_exit_group (below).
*/
diff --git a/3.6.7/0000_README b/3.6.7/0000_README
index 8b389a1..05b1561 100644
--- a/3.6.7/0000_README
+++ b/3.6.7/0000_README
@@ -6,7 +6,7 @@ Patch: 1006_linux-3.6.7.patch
From: http://www.kernel.org
Desc: Linux 3.6.7
-Patch: 4420_grsecurity-2.9.1-3.6.7-201211181105.patch
+Patch: 4420_grsecurity-2.9.1-3.6.7-201211221000.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/3.6.7/4420_grsecurity-2.9.1-3.6.7-201211181105.patch b/3.6.7/4420_grsecurity-2.9.1-3.6.7-201211221000.patch
index 6f0229a..cdc60ce 100644
--- a/3.6.7/4420_grsecurity-2.9.1-3.6.7-201211181105.patch
+++ b/3.6.7/4420_grsecurity-2.9.1-3.6.7-201211221000.patch
@@ -26100,10 +26100,139 @@ index 877b9a1..a8ecf42 100644
+ pax_force_retaddr
ret
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
-index 33643a8..8e44870 100644
+index 33643a8..f6211a0 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
-@@ -120,6 +120,11 @@ static inline void bpf_flush_icache(void *start, void *end)
+@@ -11,6 +11,7 @@
+ #include <asm/cacheflush.h>
+ #include <linux/netdevice.h>
+ #include <linux/filter.h>
++#include <linux/random.h>
+
+ /*
+ * Conventions :
+@@ -48,13 +49,87 @@ static inline u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len)
+ return ptr + len;
+ }
+
++#ifdef CONFIG_GRKERNSEC_JIT_HARDEN
++#define MAX_INSTR_CODE_SIZE 96
++#else
++#define MAX_INSTR_CODE_SIZE 64
++#endif
++
+ #define EMIT(bytes, len) do { prog = emit_code(prog, bytes, len); } while (0)
+
+ #define EMIT1(b1) EMIT(b1, 1)
+ #define EMIT2(b1, b2) EMIT((b1) + ((b2) << 8), 2)
+ #define EMIT3(b1, b2, b3) EMIT((b1) + ((b2) << 8) + ((b3) << 16), 3)
+ #define EMIT4(b1, b2, b3, b4) EMIT((b1) + ((b2) << 8) + ((b3) << 16) + ((b4) << 24), 4)
++
++#ifdef CONFIG_GRKERNSEC_JIT_HARDEN
++/* original constant will appear in ecx */
++#define DILUTE_CONST_SEQUENCE(_off, _key) \
++do { \
++ /* mov ecx, randkey */ \
++ EMIT1(0xb9); \
++ EMIT(_key, 4); \
++ /* xor ecx, randkey ^ off */ \
++ EMIT2(0x81, 0xf1); \
++ EMIT((_key) ^ (_off), 4); \
++} while (0)
++
++#define EMIT1_off32(b1, _off) \
++do { \
++ switch (b1) { \
++ case 0x05: /* add eax, imm32 */ \
++ case 0x2d: /* sub eax, imm32 */ \
++ case 0x25: /* and eax, imm32 */ \
++ case 0x0d: /* or eax, imm32 */ \
++ case 0xb8: /* mov 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 0xbb: /* mov ebx, imm32 */ \
++ DILUTE_CONST_SEQUENCE(_off, randkey); \
++ /* mov ebx, ecx */ \
++ EMIT2(0x89, 0xcb); \
++ break; \
++ case 0xbe: /* mov esi, imm32 */ \
++ DILUTE_CONST_SEQUENCE(_off, randkey); \
++ /* mov esi, ecx */ \
++ EMIT2(0x89, 0xce); \
++ break; \
++ case 0xe9: /* jmp rel imm32 */ \
++ EMIT1(b1); \
++ EMIT(_off, 4); \
++ /* prevent fall-through, we're not called if off = 0 */ \
++ EMIT(0xcccccccc, 4); \
++ EMIT(0xcccccccc, 4); \
++ break; \
++ default: \
++ EMIT1(b1); \
++ EMIT(_off, 4); \
++ } \
++} while (0)
++
++#define EMIT2_off32(b1, b2, _off) \
++do { \
++ if ((b1) == 0x8d && (b2) == 0xb3) { /* lea esi, [rbx+imm32] */ \
++ EMIT2(0x8d, 0xb3); /* lea esi, [rbx+randkey] */ \
++ EMIT(randkey, 4); \
++ EMIT2(0x8d, 0xb6); /* lea esi, [esi+off-randkey] */ \
++ EMIT((_off) - randkey, 4); \
++ } else if ((b1) == 0x69 && (b2) == 0xc0) { /* imul eax, imm32 */\
++ DILUTE_CONST_SEQUENCE(_off, randkey); \
++ /* imul eax, ecx */ \
++ EMIT3(0x0f, 0xaf, 0xc1); \
++ } else { \
++ EMIT2(b1, b2); \
++ EMIT(_off, 4); \
++ } \
++} while (0)
++#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)
++#endif
+
+ #define CLEAR_A() EMIT2(0x31, 0xc0) /* xor %eax,%eax */
+ #define CLEAR_X() EMIT2(0x31, 0xdb) /* xor %ebx,%ebx */
+@@ -89,6 +164,24 @@ do { \
+ #define X86_JBE 0x76
+ #define X86_JA 0x77
+
++#ifdef CONFIG_GRKERNSEC_JIT_HARDEN
++#define APPEND_FLOW_VERIFY() \
++do { \
++ /* mov ecx, randkey */ \
++ EMIT1(0xb9); \
++ EMIT(randkey, 4); \
++ /* cmp ecx, randkey */ \
++ EMIT2(0x81, 0xf9); \
++ EMIT(randkey, 4); \
++ /* jz after 8 int 3s */ \
++ EMIT2(0x74, 0x08); \
++ EMIT(0xcccccccc, 4); \
++ EMIT(0xcccccccc, 4); \
++} while (0)
++#else
++#define APPEND_FLOW_VERIFY() do { } while (0)
++#endif
++
+ #define EMIT_COND_JMP(op, offset) \
+ do { \
+ if (is_near(offset)) \
+@@ -96,6 +189,7 @@ do { \
+ else { \
+ EMIT2(0x0f, op + 0x10); \
+ EMIT(offset, 4); /* jxx .+off32 */ \
++ APPEND_FLOW_VERIFY(); \
+ } \
+ } while (0)
+
+@@ -120,12 +214,17 @@ static inline void bpf_flush_icache(void *start, void *end)
set_fs(old_fs);
}
@@ -26115,7 +26244,24 @@ index 33643a8..8e44870 100644
#define CHOOSE_LOAD_FUNC(K, func) \
((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset)
-@@ -146,6 +151,10 @@ void bpf_jit_compile(struct sk_filter *fp)
+ void bpf_jit_compile(struct sk_filter *fp)
+ {
+- u8 temp[64];
++ u8 temp[MAX_INSTR_CODE_SIZE];
+ u8 *prog;
+ unsigned int proglen, oldproglen = 0;
+ int ilen, i;
+@@ -138,6 +237,9 @@ void bpf_jit_compile(struct sk_filter *fp)
+ unsigned int *addrs;
+ const struct sock_filter *filter = fp->insns;
+ int flen = fp->len;
++#ifdef CONFIG_GRKERNSEC_JIT_HARDEN
++ unsigned int randkey;
++#endif
+
+ if (!bpf_jit_enable)
+ return;
+@@ -146,11 +248,19 @@ void bpf_jit_compile(struct sk_filter *fp)
if (addrs == NULL)
return;
@@ -26123,10 +26269,59 @@ index 33643a8..8e44870 100644
+ if (!fp->work)
+ goto out;
+
++#ifdef CONFIG_GRKERNSEC_JIT_HARDEN
++ randkey = get_random_int();
++#endif
++
/* Before first pass, make a rough estimation of addrs[]
- * each bpf instruction is translated to less than 64 bytes
+- * each bpf instruction is translated to less than 64 bytes
++ * each bpf instruction is translated to less than MAX_INSTR_CODE_SIZE bytes
*/
-@@ -593,17 +602,18 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
+ for (proglen = 0, i = 0; i < flen; i++) {
+- proglen += 64;
++ proglen += MAX_INSTR_CODE_SIZE;
+ addrs[i] = proglen;
+ }
+ cleanup_addr = proglen; /* epilogue address */
+@@ -258,10 +368,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 */
+- else {
+- EMIT2(0x69, 0xc0); /* imul imm32,%eax */
+- EMIT(K, 4);
+- }
++ else
++ EMIT2_off32(0x69, 0xc0, K); /* imul imm32,%eax */
+ break;
+ case BPF_S_ALU_DIV_X: /* A /= X; */
+ seen |= SEEN_XREG;
+@@ -281,8 +389,14 @@ void bpf_jit_compile(struct sk_filter *fp)
+ EMIT4(0x31, 0xd2, 0xf7, 0xf3); /* xor %edx,%edx; div %ebx */
+ break;
+ case BPF_S_ALU_DIV_K: /* A = reciprocal_divide(A, K); */
++#ifdef CONFIG_GRKERNSEC_JIT_HARDEN
++ DILUTE_CONST_SEQUENCE(K, randkey);
++ // imul rax, rcx
++ EMIT4(0x48, 0x0f, 0xaf, 0xc1);
++#else
+ EMIT3(0x48, 0x69, 0xc0); /* imul imm32,%rax,%rax */
+ EMIT(K, 4);
++#endif
+ EMIT4(0x48, 0xc1, 0xe8, 0x20); /* shr $0x20,%rax */
+ break;
+ case BPF_S_ALU_AND_X:
+@@ -509,8 +623,7 @@ common_load_ind: seen |= SEEN_DATAREF | SEEN_XREG;
+ if (is_imm8(K)) {
+ EMIT3(0x8d, 0x73, K); /* lea imm8(%rbx), %esi */
+ } else {
+- EMIT2(0x8d, 0xb3); /* lea imm32(%rbx),%esi */
+- EMIT(K, 4);
++ EMIT2_off32(0x8d, 0xb3, K); /* lea imm32(%rbx),%esi */
+ }
+ } else {
+ EMIT2(0x89,0xde); /* mov %ebx,%esi */
+@@ -593,17 +706,18 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
break;
default:
/* hmm, too complex filter, give up with jit compiler */
@@ -26149,7 +26344,7 @@ index 33643a8..8e44870 100644
}
proglen += ilen;
addrs[i] = proglen;
-@@ -624,11 +634,9 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
+@@ -624,11 +738,9 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
break;
}
if (proglen == oldproglen) {
@@ -26163,7 +26358,7 @@ index 33643a8..8e44870 100644
}
oldproglen = proglen;
}
-@@ -644,7 +652,10 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
+@@ -644,7 +756,10 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
bpf_flush_icache(image, image + proglen);
fp->bpf_func = (void *)image;
@@ -26175,7 +26370,7 @@ index 33643a8..8e44870 100644
out:
kfree(addrs);
return;
-@@ -652,18 +663,20 @@ out:
+@@ -652,18 +767,20 @@ out:
static void jit_free_defer(struct work_struct *arg)
{
@@ -46151,7 +46346,7 @@ index 96f2428..f5eeb8e 100644
if (dot && fs && !(fs->fs_flags & FS_HAS_SUBTYPE)) {
diff --git a/fs/fs_struct.c b/fs/fs_struct.c
-index 5df4775..9d9336f 100644
+index 5df4775..f656176 100644
--- a/fs/fs_struct.c
+++ b/fs/fs_struct.c
@@ -4,6 +4,7 @@
@@ -46201,7 +46396,14 @@ index 5df4775..9d9336f 100644
hits += replace_path(&fs->pwd, old_root, new_root);
write_seqcount_end(&fs->seq);
while (hits--) {
-@@ -99,7 +116,8 @@ void exit_fs(struct task_struct *tsk)
+@@ -94,12 +111,15 @@ void exit_fs(struct task_struct *tsk)
+ {
+ struct fs_struct *fs = tsk->fs;
+
++ gr_put_exec_file(tsk);
++
+ if (fs) {
+ int kill;
task_lock(tsk);
spin_lock(&fs->lock);
tsk->fs = NULL;
@@ -46211,7 +46413,7 @@ index 5df4775..9d9336f 100644
spin_unlock(&fs->lock);
task_unlock(tsk);
if (kill)
-@@ -112,7 +130,7 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
+@@ -112,7 +132,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) {
@@ -46220,7 +46422,7 @@ index 5df4775..9d9336f 100644
fs->in_exec = 0;
spin_lock_init(&fs->lock);
seqcount_init(&fs->seq);
-@@ -121,6 +139,9 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
+@@ -121,6 +141,9 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
spin_lock(&old->lock);
fs->root = old->root;
path_get(&fs->root);
@@ -46230,7 +46432,7 @@ index 5df4775..9d9336f 100644
fs->pwd = old->pwd;
path_get(&fs->pwd);
spin_unlock(&old->lock);
-@@ -139,8 +160,9 @@ int unshare_fs_struct(void)
+@@ -139,8 +162,9 @@ int unshare_fs_struct(void)
task_lock(current);
spin_lock(&fs->lock);
@@ -46241,7 +46443,7 @@ index 5df4775..9d9336f 100644
spin_unlock(&fs->lock);
task_unlock(current);
-@@ -153,13 +175,13 @@ EXPORT_SYMBOL_GPL(unshare_fs_struct);
+@@ -153,13 +177,13 @@ EXPORT_SYMBOL_GPL(unshare_fs_struct);
int current_umask(void)
{
@@ -46257,7 +46459,15 @@ index 5df4775..9d9336f 100644
.lock = __SPIN_LOCK_UNLOCKED(init_fs.lock),
.seq = SEQCNT_ZERO,
.umask = 0022,
-@@ -175,12 +197,13 @@ void daemonize_fs_struct(void)
+@@ -169,18 +193,21 @@ void daemonize_fs_struct(void)
+ {
+ struct fs_struct *fs = current->fs;
+
++ gr_put_exec_file(current);
++
+ if (fs) {
+ int kill;
+
task_lock(current);
spin_lock(&init_fs.lock);
@@ -50872,10 +51082,10 @@ index 4e00cf0..3374374 100644
kfree(s);
diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig
new file mode 100644
-index 0000000..d38b430
+index 0000000..10c36fb
--- /dev/null
+++ b/grsecurity/Kconfig
-@@ -0,0 +1,947 @@
+@@ -0,0 +1,964 @@
+#
+# grecurity configuration
+#
@@ -50938,6 +51148,23 @@ index 0000000..d38b430
+ IF YOU USE XFree86. If you use XFree86 and you still want to
+ protect your kernel against modification, use the RBAC system.
+
++config GRKERNSEC_JIT_HARDEN
++ bool "Harden BPF JIT against spray attacks"
++ default y if GRKERNSEC_CONFIG_AUTO
++ depends on BPF_JIT
++ help
++ If you say Y here, the native code generated by the kernel's Berkeley
++ Packet Filter (BPF) JIT engine will be hardened against JIT-spraying
++ attacks that attempt to fit attacker-beneficial instructions in
++ 32bit immediate fields of JIT-generated native instructions. The
++ attacker will generally aim to cause an unintended instruction sequence
++ of JIT-generated native code to execute by jumping into the middle of
++ a generated instruction. This feature effectively randomizes the 32bit
++ immediate constants present in the generated code to thwart such attacks.
++
++ If you're using KERNEXEC, it's recommended that you enable this option
++ to supplement the hardening of the kernel.
++
+config GRKERNSEC_PROC_MEMMAP
+ bool "Harden ASLR against information leaks and entropy reduction"
+ default y if (GRKERNSEC_CONFIG_AUTO || PAX_NOEXEC || PAX_ASLR)
@@ -51869,10 +52096,10 @@ index 0000000..1b9afa9
+endif
diff --git a/grsecurity/gracl.c b/grsecurity/gracl.c
new file mode 100644
-index 0000000..b736032
+index 0000000..4428c82
--- /dev/null
+++ b/grsecurity/gracl.c
-@@ -0,0 +1,4040 @@
+@@ -0,0 +1,4056 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
@@ -55903,6 +56130,22 @@ index 0000000..b736032
+ return (obj->mode & GR_FIND) ? 1 : 0;
+}
+
++void gr_put_exec_file(struct task_struct *task)
++{
++ struct file *filp;
++
++ write_lock(&grsec_exec_file_lock);
++ filp = task->exec_file;
++ task->exec_file = NULL;
++ write_unlock(&grsec_exec_file_lock);
++
++ if (filp)
++ fput(filp);
++
++ return;
++}
++
++
+#ifdef CONFIG_NETFILTER_XT_MATCH_GRADM_MODULE
+EXPORT_SYMBOL(gr_acl_is_enabled);
+#endif
@@ -58012,10 +58255,10 @@ index 0000000..9807ee2
+}
diff --git a/grsecurity/grsec_disabled.c b/grsecurity/grsec_disabled.c
new file mode 100644
-index 0000000..213ad8b
+index 0000000..b79fe50
--- /dev/null
+++ b/grsecurity/grsec_disabled.c
-@@ -0,0 +1,437 @@
+@@ -0,0 +1,442 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
@@ -58447,6 +58690,11 @@ index 0000000..213ad8b
+ return dentry->d_inode->i_sb->s_dev;
+}
+
++void gr_put_exec_file(struct task_struct *task)
++{
++ return;
++}
++
+EXPORT_SYMBOL(gr_learn_resource);
+EXPORT_SYMBOL(gr_set_kernel_label);
+#ifdef CONFIG_SECURITY
@@ -62887,10 +63135,10 @@ index 0000000..54f4e85
+#define GR_SYMLINKOWNER_MSG "denied following symlink %.950s since symlink owner %u does not match target owner %u, by "
diff --git a/include/linux/grsecurity.h b/include/linux/grsecurity.h
new file mode 100644
-index 0000000..f9b9a21
+index 0000000..187b3ed
--- /dev/null
+++ b/include/linux/grsecurity.h
-@@ -0,0 +1,238 @@
+@@ -0,0 +1,239 @@
+#ifndef GR_SECURITY_H
+#define GR_SECURITY_H
+#include <linux/fs.h>
@@ -63103,6 +63351,7 @@ index 0000000..f9b9a21
+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);
++void gr_put_exec_file(struct task_struct *task);
+
+int gr_ptrace_readexec(struct file *file, int unsafe_flags);
+
@@ -67384,21 +67633,10 @@ index 7fee567..8affa2c 100644
/*
diff --git a/kernel/exit.c b/kernel/exit.c
-index f65345f9..9c28dab 100644
+index f65345f9..1423231 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
-@@ -59,6 +59,10 @@
- #include <asm/pgtable.h>
- #include <asm/mmu_context.h>
-
-+#ifdef CONFIG_GRKERNSEC
-+extern rwlock_t grsec_exec_file_lock;
-+#endif
-+
- static void exit_mm(struct task_struct * tsk);
-
- static void __unhash_process(struct task_struct *p, bool group_dead)
-@@ -182,6 +186,10 @@ void release_task(struct task_struct * p)
+@@ -182,6 +182,10 @@ void release_task(struct task_struct * p)
struct task_struct *leader;
int zap_leader;
repeat:
@@ -67409,7 +67647,7 @@ index f65345f9..9c28dab 100644
/* don't need to get the RCU readlock here - the process is dead and
* can't be modifying its own credentials. But shut RCU-lockdep up */
rcu_read_lock();
-@@ -394,7 +402,7 @@ int allow_signal(int sig)
+@@ -394,7 +398,7 @@ int allow_signal(int sig)
* know it'll be handled, so that they don't get converted to
* SIGKILL or just silently dropped.
*/
@@ -67418,25 +67656,16 @@ index f65345f9..9c28dab 100644
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
return 0;
-@@ -430,6 +438,17 @@ void daemonize(const char *name, ...)
+@@ -430,6 +434,8 @@ void daemonize(const char *name, ...)
vsnprintf(current->comm, sizeof(current->comm), name, args);
va_end(args);
-+#ifdef CONFIG_GRKERNSEC
-+ write_lock(&grsec_exec_file_lock);
-+ if (current->exec_file) {
-+ fput(current->exec_file);
-+ current->exec_file = NULL;
-+ }
-+ write_unlock(&grsec_exec_file_lock);
-+#endif
-+
+ gr_set_kernel_label(current);
+
/*
* If we were started as result of loading a module, close all of the
* user space pages. We don't need them, and if we didn't close them
-@@ -907,6 +926,8 @@ void do_exit(long code)
+@@ -907,6 +913,8 @@ void do_exit(long code)
struct task_struct *tsk = current;
int group_dead;
@@ -67445,7 +67674,7 @@ index f65345f9..9c28dab 100644
profile_task_exit(tsk);
WARN_ON(blk_needs_flush_plug(tsk));
-@@ -923,7 +944,6 @@ void do_exit(long code)
+@@ -923,7 +931,6 @@ void do_exit(long code)
* mm_release()->clear_child_tid() from writing to a user-controlled
* kernel address.
*/
@@ -67453,7 +67682,7 @@ index f65345f9..9c28dab 100644
ptrace_event(PTRACE_EVENT_EXIT, code);
-@@ -982,6 +1002,9 @@ void do_exit(long code)
+@@ -982,6 +989,9 @@ void do_exit(long code)
tsk->exit_code = code;
taskstats_exit(tsk, group_dead);
@@ -67463,7 +67692,7 @@ index f65345f9..9c28dab 100644
exit_mm(tsk);
if (group_dead)
-@@ -1099,7 +1122,7 @@ SYSCALL_DEFINE1(exit, int, error_code)
+@@ -1099,7 +1109,7 @@ SYSCALL_DEFINE1(exit, int, error_code)
* Take down every thread in the group. This is called by fatal signals
* as well as by sys_exit_group (below).
*/
@@ -83091,7 +83320,7 @@ index 0000000..92ed719
+ return 0;
+}
diff --git a/tools/gcc/generate_size_overflow_hash.sh b/tools/gcc/generate_size_overflow_hash.sh
-new file mode 100644
+new file mode 100755
index 0000000..02c6bec
--- /dev/null
+++ b/tools/gcc/generate_size_overflow_hash.sh
@@ -84099,10 +84328,10 @@ index 0000000..b8008f7
+}
diff --git a/tools/gcc/size_overflow_hash.data b/tools/gcc/size_overflow_hash.data
new file mode 100644
-index 0000000..9332f17
+index 0000000..67468e3
--- /dev/null
+++ b/tools/gcc/size_overflow_hash.data
-@@ -0,0 +1,3597 @@
+@@ -0,0 +1,3600 @@
+_000001_hash alloc_dr 2 65495 _000001_hash NULL
+_000002_hash __copy_from_user 3 10918 _000002_hash NULL
+_000003_hash copy_from_user 3 17559 _000003_hash NULL
@@ -87700,6 +87929,9 @@ index 0000000..9332f17
+_003894_hash io_mapping_map_wc 2 19284 _003894_hash NULL
+_003895_hash nfs_dns_resolve_name 3 25036 _003895_hash NULL
+_003896_hash nfs_parse_server_name 2 1899 _003896_hash NULL
++_003897_hash acl_alloc 1 35979 _003897_hash NULL
++_003898_hash acl_alloc_stack_init 1 60630 _003898_hash NULL
++_003899_hash create_table 2 16213 _003899_hash NULL
diff --git a/tools/gcc/size_overflow_plugin.c b/tools/gcc/size_overflow_plugin.c
new file mode 100644
index 0000000..1aa0dce