summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2013-05-30 07:43:36 -0400
committerAnthony G. Basile <blueness@gentoo.org>2013-05-30 07:43:36 -0400
commit98f0944d5d4dcb71e3c77924f54f81cd836c04b4 (patch)
treecfec06e4ef05f9991de8dda879044eaba429837f
parentGrsec/PaX: 2.9.1-{2.6.32.60,3.2.45,3.9.4}-201305251009 (diff)
downloadhardened-patchset-98f0944d5d4dcb71e3c77924f54f81cd836c04b4.tar.gz
hardened-patchset-98f0944d5d4dcb71e3c77924f54f81cd836c04b4.tar.bz2
hardened-patchset-98f0944d5d4dcb71e3c77924f54f81cd836c04b4.zip
Grsec/PaX: 2.9.1-{2.6.32.60,3.2.45,3.9.4}-20130529215120130529
-rw-r--r--2.6.32/0000_README2
-rw-r--r--2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201305292148.patch (renamed from 2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201305251007.patch)141
-rw-r--r--3.2.45/0000_README2
-rw-r--r--3.2.45/4420_grsecurity-2.9.1-3.2.45-201305292150.patch (renamed from 3.2.45/4420_grsecurity-2.9.1-3.2.45-201305251007.patch)426
-rw-r--r--3.9.4/0000_README2
-rw-r--r--3.9.4/4420_grsecurity-2.9.1-3.9.4-201305292151.patch (renamed from 3.9.4/4420_grsecurity-2.9.1-3.9.4-201305251009.patch)751
6 files changed, 1141 insertions, 183 deletions
diff --git a/2.6.32/0000_README b/2.6.32/0000_README
index 5ca0857..378709b 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-201305251007.patch
+Patch: 4420_grsecurity-2.9.1-2.6.32.60-201305292148.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-201305251007.patch b/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201305292148.patch
index f7ef7a8..a6ebcd3 100644
--- a/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201305251007.patch
+++ b/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201305292148.patch
@@ -43345,7 +43345,7 @@ index 62f282e..e45c45c 100644
cdev_init(&ptmx_cdev, &ptmx_fops);
if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
diff --git a/drivers/char/random.c b/drivers/char/random.c
-index 446b20a..710568a 100644
+index 446b20a..1193fa7 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -269,8 +269,13 @@
@@ -43399,36 +43399,94 @@ index 446b20a..710568a 100644
smp_wmb();
if (out)
-@@ -942,6 +955,10 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
+@@ -840,6 +853,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
+ int reserved)
+ {
+ unsigned long flags;
++ int wakeup_write = 0;
+
+ /* Hold lock while accounting */
+ spin_lock_irqsave(&r->lock, flags);
+@@ -852,19 +866,25 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
+ if (r->entropy_count / 8 < min + reserved) {
+ nbytes = 0;
+ } else {
++ int entropy_count, orig;
++retry:
++ entropy_count = orig = ACCESS_ONCE(r->entropy_count);
+ /* If limited, never pull more than available */
+- if (r->limit && nbytes + reserved >= r->entropy_count / 8)
+- nbytes = r->entropy_count/8 - reserved;
++ if (r->limit && nbytes + reserved >= entropy_count / 8)
++ nbytes = entropy_count/8 - reserved;
+
+- if (r->entropy_count / 8 >= nbytes + reserved)
+- r->entropy_count -= nbytes*8;
+- else
+- r->entropy_count = reserved;
+-
+- if (r->entropy_count < random_write_wakeup_thresh) {
+- wake_up_interruptible(&random_write_wait);
+- kill_fasync(&fasync, SIGIO, POLL_OUT);
++ if (entropy_count / 8 >= nbytes + reserved) {
++ entropy_count -= nbytes*8;
++ if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
++ goto retry;
++ } else {
++ entropy_count = reserved;
++ if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
++ goto retry;
+ }
++
++ if (entropy_count < random_write_wakeup_thresh)
++ wakeup_write = 1;
+ }
+
+ DEBUG_ENT("debiting %d entropy credits from %s%s\n",
+@@ -872,6 +892,11 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
+
+ spin_unlock_irqrestore(&r->lock, flags);
+
++ if (wakeup_write) {
++ wake_up_interruptible(&random_write_wait);
++ kill_fasync(&fasync, SIGIO, POLL_OUT);
++ }
++
+ return nbytes;
+ }
+
+@@ -941,6 +966,21 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
+ {
ssize_t ret = 0, i;
__u8 tmp[EXTRACT_SIZE];
-
-+ /* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */
-+ if (fips_enabled && !r->last_data_init)
-+ nbytes += EXTRACT_SIZE;
++ unsigned long flags;
+
++ /* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */
++ if (fips_enabled) {
++ spin_lock_irqsave(&r->lock, flags);
++ if (!r->last_data_init) {
++ r->last_data_init = true;
++ spin_unlock_irqrestore(&r->lock, flags);
++ xfer_secondary_pool(r, EXTRACT_SIZE);
++ extract_buf(r, tmp);
++ spin_lock_irqsave(&r->lock, flags);
++ memcpy(r->last_data, tmp, EXTRACT_SIZE);
++ }
++ spin_unlock_irqrestore(&r->lock, flags);
++ }
+
xfer_secondary_pool(r, nbytes);
nbytes = account(r, nbytes, min, reserved);
+@@ -949,8 +989,6 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
+ extract_buf(r, tmp);
-@@ -951,6 +968,17 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
if (fips_enabled) {
- unsigned long flags;
-
-+
-+ /* prime last_data value if need be, per fips 140-2 */
-+ if (!r->last_data_init) {
-+ spin_lock_irqsave(&r->lock, flags);
-+ memcpy(r->last_data, tmp, EXTRACT_SIZE);
-+ r->last_data_init = true;
-+ nbytes -= EXTRACT_SIZE;
-+ spin_unlock_irqrestore(&r->lock, flags);
-+ extract_buf(r, tmp);
-+ }
-+
+- unsigned long flags;
+-
spin_lock_irqsave(&r->lock, flags);
if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))
panic("Hardware RNG duplicated output!\n");
-@@ -1015,7 +1043,21 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
+@@ -1015,7 +1053,21 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
*/
void get_random_bytes(void *buf, int nbytes)
{
@@ -43451,7 +43509,7 @@ index 446b20a..710568a 100644
}
EXPORT_SYMBOL(get_random_bytes);
-@@ -1068,6 +1110,7 @@ static void init_std_data(struct entropy_store *r)
+@@ -1068,6 +1120,7 @@ static void init_std_data(struct entropy_store *r)
r->entropy_count = 0;
r->entropy_total = 0;
@@ -43459,7 +43517,7 @@ index 446b20a..710568a 100644
mix_pool_bytes(r, &now, sizeof(now), NULL);
for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof(rv)) {
if (!arch_get_random_long(&rv))
-@@ -1322,7 +1365,7 @@ EXPORT_SYMBOL(generate_random_uuid);
+@@ -1322,7 +1375,7 @@ EXPORT_SYMBOL(generate_random_uuid);
#include <linux/sysctl.h>
static int min_read_thresh = 8, min_write_thresh;
@@ -43468,7 +43526,7 @@ index 446b20a..710568a 100644
static int max_write_thresh = INPUT_POOL_WORDS * 32;
static char sysctl_bootid[16];
-@@ -1397,6 +1440,7 @@ static int uuid_strategy(ctl_table *table,
+@@ -1397,6 +1450,7 @@ static int uuid_strategy(ctl_table *table,
}
static int sysctl_poolsize = INPUT_POOL_WORDS * 32;
@@ -43476,7 +43534,7 @@ index 446b20a..710568a 100644
ctl_table random_table[] = {
{
.ctl_name = RANDOM_POOLSIZE,
-@@ -1472,7 +1516,7 @@ late_initcall(random_int_secret_init);
+@@ -1472,7 +1526,7 @@ late_initcall(random_int_secret_init);
* value is not cryptographically secure but for several uses the cost of
* depleting entropy is too high
*/
@@ -71823,7 +71881,7 @@ index 913b4a4..4de325a9 100644
crtc.h_tot_disp = aty_ld_le32(CRTC_H_TOTAL_DISP, par);
crtc.h_sync_strt_wid = aty_ld_le32(CRTC_H_SYNC_STRT_WID, par);
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c
-index 1a056ad..221bd6a 100644
+index 1a056ad..221bd6ae 100644
--- a/drivers/video/aty/radeon_backlight.c
+++ b/drivers/video/aty/radeon_backlight.c
@@ -127,7 +127,7 @@ static int radeon_bl_get_brightness(struct backlight_device *bd)
@@ -79170,7 +79228,7 @@ index f1e7077..edd86b2 100644
.store = ext4_attr_store,
};
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
-index 76b7961..c187e92 100644
+index 76b7961..ca5f1c9 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -558,7 +558,7 @@ static int fat_statfs(struct dentry *dentry, struct kstatfs *buf)
@@ -79182,6 +79240,35 @@ index 76b7961..c187e92 100644
return 0;
}
+@@ -1206,6 +1206,19 @@ static int fat_read_root(struct inode *inode)
+ return 0;
+ }
+
++static unsigned long calc_fat_clusters(struct super_block *sb)
++{
++ struct msdos_sb_info *sbi = MSDOS_SB(sb);
++
++ /* Divide first to avoid overflow */
++ if (sbi->fat_bits != 12) {
++ unsigned long ent_per_sec = sb->s_blocksize * 8 / sbi->fat_bits;
++ return ent_per_sec * sbi->fat_length;
++ }
++
++ return sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
++}
++
+ /*
+ * Read the super block of an MS-DOS FS.
+ */
+@@ -1400,7 +1413,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
+ sbi->fat_bits = (total_clusters > MAX_FAT12) ? 16 : 12;
+
+ /* check that FAT table does not overflow */
+- fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
++ fat_clusters = calc_fat_clusters(sb);
+ total_clusters = min(total_clusters, fat_clusters - FAT_START_ENT);
+ if (total_clusters > MAX_FAT(sb)) {
+ if (!silent)
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index 72646e2..4251f35 100644
--- a/fs/fat/namei_vfat.c
diff --git a/3.2.45/0000_README b/3.2.45/0000_README
index ba3ec05..577c9db 100644
--- a/3.2.45/0000_README
+++ b/3.2.45/0000_README
@@ -98,7 +98,7 @@ Patch: 1044_linux-3.2.45.patch
From: http://www.kernel.org
Desc: Linux 3.2.45
-Patch: 4420_grsecurity-2.9.1-3.2.45-201305251007.patch
+Patch: 4420_grsecurity-2.9.1-3.2.45-201305292150.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/3.2.45/4420_grsecurity-2.9.1-3.2.45-201305251007.patch b/3.2.45/4420_grsecurity-2.9.1-3.2.45-201305292150.patch
index bc81306..52e473e 100644
--- a/3.2.45/4420_grsecurity-2.9.1-3.2.45-201305251007.patch
+++ b/3.2.45/4420_grsecurity-2.9.1-3.2.45-201305292150.patch
@@ -1858,6 +1858,28 @@ index 7ac5dfd..0ce09c2 100644
if (ret != NOTIFY_STOP)
do_exit(SIGSEGV);
}
+diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
+index 20b3041..da44b1f 100644
+--- a/arch/arm/kernel/vmlinux.lds.S
++++ b/arch/arm/kernel/vmlinux.lds.S
+@@ -103,6 +103,8 @@ SECTIONS
+ ARM_CPU_KEEP(PROC_INFO)
+ }
+
++ _etext = .; /* End of text section */
++
+ RO_DATA(PAGE_SIZE)
+
+ #ifdef CONFIG_ARM_UNWIND
+@@ -122,8 +124,6 @@ SECTIONS
+ }
+ #endif
+
+- _etext = .; /* End of text and rodata section */
+-
+ #ifndef CONFIG_XIP_KERNEL
+ . = ALIGN(PAGE_SIZE);
+ __init_begin = .;
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
index 66a477a..bee61d3 100644
--- a/arch/arm/lib/copy_from_user.S
@@ -2210,7 +2232,7 @@ index c3a58a1..78fbf54 100644
/*
* Memory returned by kmalloc() may be used for DMA, so we must make
diff --git a/arch/avr32/include/asm/elf.h b/arch/avr32/include/asm/elf.h
-index 3b3159b..425ea94 100644
+index 3b3159b..425ea94d 100644
--- a/arch/avr32/include/asm/elf.h
+++ b/arch/avr32/include/asm/elf.h
@@ -84,8 +84,14 @@ typedef struct user_fpu_struct elf_fpregset_t;
@@ -28041,7 +28063,7 @@ 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..2265c0f 100644
+index 5a5b6e4..37ccbe3 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -11,6 +11,7 @@
@@ -28052,7 +28074,7 @@ index 5a5b6e4..2265c0f 100644
/*
* Conventions :
-@@ -45,13 +46,87 @@ static inline u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len)
+@@ -45,13 +46,84 @@ static inline u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len)
return ptr + len;
}
@@ -28104,6 +28126,10 @@ index 5a5b6e4..2265c0f 100644
+ /* mov esi, ecx */ \
+ EMIT2(0x89, 0xce); \
+ break; \
++ case 0xe8: /* call rel imm32, always to known funcs */ \
++ EMIT1(b1); \
++ EMIT(_off, 4); \
++ break; \
+ case 0xe9: /* jmp rel imm32 */ \
+ EMIT1(b1); \
+ EMIT(_off, 4); \
@@ -28112,25 +28138,18 @@ index 5a5b6e4..2265c0f 100644
+ EMIT(0xcccccccc, 4); \
+ break; \
+ default: \
-+ EMIT1(b1); \
-+ EMIT(_off, 4); \
++ BUILD_BUG_ON(1); \
+ } \
+} 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 */\
++ 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); \
++ BUILD_BUG_ON(1); \
+ } \
+} while (0)
+#else
@@ -28140,7 +28159,7 @@ index 5a5b6e4..2265c0f 100644
#define CLEAR_A() EMIT2(0x31, 0xc0) /* xor %eax,%eax */
#define CLEAR_X() EMIT2(0x31, 0xdb) /* xor %ebx,%ebx */
-@@ -86,6 +161,24 @@ do { \
+@@ -86,6 +158,24 @@ do { \
#define X86_JBE 0x76
#define X86_JA 0x77
@@ -28165,7 +28184,7 @@ index 5a5b6e4..2265c0f 100644
#define EMIT_COND_JMP(op, offset) \
do { \
if (is_near(offset)) \
-@@ -93,6 +186,7 @@ do { \
+@@ -93,6 +183,7 @@ do { \
else { \
EMIT2(0x0f, op + 0x10); \
EMIT(offset, 4); /* jxx .+off32 */ \
@@ -28173,7 +28192,7 @@ index 5a5b6e4..2265c0f 100644
} \
} while (0)
-@@ -117,10 +211,14 @@ static inline void bpf_flush_icache(void *start, void *end)
+@@ -117,10 +208,14 @@ static inline void bpf_flush_icache(void *start, void *end)
set_fs(old_fs);
}
@@ -28189,7 +28208,7 @@ index 5a5b6e4..2265c0f 100644
u8 *prog;
unsigned int proglen, oldproglen = 0;
int ilen, i;
-@@ -133,6 +231,9 @@ void bpf_jit_compile(struct sk_filter *fp)
+@@ -133,6 +228,9 @@ void bpf_jit_compile(struct sk_filter *fp)
unsigned int *addrs;
const struct sock_filter *filter = fp->insns;
int flen = fp->len;
@@ -28199,7 +28218,7 @@ index 5a5b6e4..2265c0f 100644
if (!bpf_jit_enable)
return;
-@@ -141,11 +242,19 @@ void bpf_jit_compile(struct sk_filter *fp)
+@@ -141,11 +239,19 @@ void bpf_jit_compile(struct sk_filter *fp)
if (addrs == NULL)
return;
@@ -28221,7 +28240,7 @@ index 5a5b6e4..2265c0f 100644
addrs[i] = proglen;
}
cleanup_addr = proglen; /* epilogue address */
-@@ -253,10 +362,8 @@ void bpf_jit_compile(struct sk_filter *fp)
+@@ -253,10 +359,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 */
@@ -28234,7 +28253,7 @@ index 5a5b6e4..2265c0f 100644
break;
case BPF_S_ALU_DIV_X: /* A /= X; */
seen |= SEEN_XREG;
-@@ -276,8 +383,14 @@ void bpf_jit_compile(struct sk_filter *fp)
+@@ -276,8 +380,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); */
@@ -28249,7 +28268,7 @@ index 5a5b6e4..2265c0f 100644
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)
+@@ -477,7 +587,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. */
@@ -28258,7 +28277,7 @@ index 5a5b6e4..2265c0f 100644
}
t_offset = func - (image + addrs[i]);
EMIT1_off32(0xbe, K); /* mov imm32,%esi */
-@@ -492,7 +605,7 @@ common_load: seen |= SEEN_DATAREF;
+@@ -492,7 +602,7 @@ common_load: seen |= SEEN_DATAREF;
case BPF_S_LDX_B_MSH:
if ((int)K < 0) {
/* Abort the JIT because __load_pointer() is needed. */
@@ -28267,7 +28286,7 @@ index 5a5b6e4..2265c0f 100644
}
seen |= SEEN_DATAREF | SEEN_XREG;
t_offset = sk_load_byte_msh - (image + addrs[i]);
-@@ -582,17 +695,18 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
+@@ -582,17 +692,18 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
break;
default:
/* hmm, too complex filter, give up with jit compiler */
@@ -28290,7 +28309,7 @@ index 5a5b6e4..2265c0f 100644
}
proglen += ilen;
addrs[i] = proglen;
-@@ -613,11 +727,9 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
+@@ -613,11 +724,9 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
break;
}
if (proglen == oldproglen) {
@@ -28304,7 +28323,7 @@ index 5a5b6e4..2265c0f 100644
}
oldproglen = proglen;
}
-@@ -633,7 +745,10 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
+@@ -633,7 +742,10 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
bpf_flush_icache(image, image + proglen);
fp->bpf_func = (void *)image;
@@ -28316,7 +28335,7 @@ index 5a5b6e4..2265c0f 100644
out:
kfree(addrs);
return;
-@@ -641,18 +756,20 @@ out:
+@@ -641,18 +753,20 @@ out:
static void jit_free_defer(struct work_struct *arg)
{
@@ -32413,7 +32432,7 @@ index da3cfee..a5a6606 100644
*ppos = i;
diff --git a/drivers/char/random.c b/drivers/char/random.c
-index 8ae9235..ea94cf2 100644
+index 8ae9235..788c4ba 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -269,8 +269,13 @@
@@ -32467,36 +32486,94 @@ index 8ae9235..ea94cf2 100644
smp_wmb();
if (out)
-@@ -979,6 +992,10 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
+@@ -877,6 +890,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
+ int reserved)
+ {
+ unsigned long flags;
++ int wakeup_write = 0;
+
+ /* Hold lock while accounting */
+ spin_lock_irqsave(&r->lock, flags);
+@@ -889,19 +903,25 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
+ if (r->entropy_count / 8 < min + reserved) {
+ nbytes = 0;
+ } else {
++ int entropy_count, orig;
++retry:
++ entropy_count = orig = ACCESS_ONCE(r->entropy_count);
+ /* If limited, never pull more than available */
+- if (r->limit && nbytes + reserved >= r->entropy_count / 8)
+- nbytes = r->entropy_count/8 - reserved;
++ if (r->limit && nbytes + reserved >= entropy_count / 8)
++ nbytes = entropy_count/8 - reserved;
+
+- if (r->entropy_count / 8 >= nbytes + reserved)
+- r->entropy_count -= nbytes*8;
+- else
+- r->entropy_count = reserved;
+-
+- if (r->entropy_count < random_write_wakeup_thresh) {
+- wake_up_interruptible(&random_write_wait);
+- kill_fasync(&fasync, SIGIO, POLL_OUT);
++ if (entropy_count / 8 >= nbytes + reserved) {
++ entropy_count -= nbytes*8;
++ if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
++ goto retry;
++ } else {
++ entropy_count = reserved;
++ if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
++ goto retry;
+ }
++
++ if (entropy_count < random_write_wakeup_thresh)
++ wakeup_write = 1;
+ }
+
+ DEBUG_ENT("debiting %d entropy credits from %s%s\n",
+@@ -909,6 +929,11 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
+
+ spin_unlock_irqrestore(&r->lock, flags);
+
++ if (wakeup_write) {
++ wake_up_interruptible(&random_write_wait);
++ kill_fasync(&fasync, SIGIO, POLL_OUT);
++ }
++
+ return nbytes;
+ }
+
+@@ -978,6 +1003,21 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
+ {
ssize_t ret = 0, i;
__u8 tmp[EXTRACT_SIZE];
-
-+ /* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */
-+ if (fips_enabled && !r->last_data_init)
-+ nbytes += EXTRACT_SIZE;
++ unsigned long flags;
+
++ /* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */
++ if (fips_enabled) {
++ spin_lock_irqsave(&r->lock, flags);
++ if (!r->last_data_init) {
++ r->last_data_init = true;
++ spin_unlock_irqrestore(&r->lock, flags);
++ xfer_secondary_pool(r, EXTRACT_SIZE);
++ extract_buf(r, tmp);
++ spin_lock_irqsave(&r->lock, flags);
++ memcpy(r->last_data, tmp, EXTRACT_SIZE);
++ }
++ spin_unlock_irqrestore(&r->lock, flags);
++ }
+
xfer_secondary_pool(r, nbytes);
nbytes = account(r, nbytes, min, reserved);
+@@ -986,8 +1026,6 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
+ extract_buf(r, tmp);
-@@ -988,6 +1005,17 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
if (fips_enabled) {
- unsigned long flags;
-
-+
-+ /* prime last_data value if need be, per fips 140-2 */
-+ if (!r->last_data_init) {
-+ spin_lock_irqsave(&r->lock, flags);
-+ memcpy(r->last_data, tmp, EXTRACT_SIZE);
-+ r->last_data_init = true;
-+ nbytes -= EXTRACT_SIZE;
-+ spin_unlock_irqrestore(&r->lock, flags);
-+ extract_buf(r, tmp);
-+ }
-+
+- unsigned long flags;
+-
spin_lock_irqsave(&r->lock, flags);
if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))
panic("Hardware RNG duplicated output!\n");
-@@ -1028,7 +1056,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
+@@ -1028,7 +1066,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
extract_buf(r, tmp);
i = min_t(int, nbytes, EXTRACT_SIZE);
@@ -32505,7 +32582,7 @@ index 8ae9235..ea94cf2 100644
ret = -EFAULT;
break;
}
-@@ -1105,6 +1133,7 @@ static void init_std_data(struct entropy_store *r)
+@@ -1105,6 +1143,7 @@ static void init_std_data(struct entropy_store *r)
r->entropy_count = 0;
r->entropy_total = 0;
@@ -32513,7 +32590,7 @@ index 8ae9235..ea94cf2 100644
mix_pool_bytes(r, &now, sizeof(now), NULL);
for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof(rv)) {
if (!arch_get_random_long(&rv))
-@@ -1379,7 +1408,7 @@ EXPORT_SYMBOL(generate_random_uuid);
+@@ -1379,7 +1418,7 @@ EXPORT_SYMBOL(generate_random_uuid);
#include <linux/sysctl.h>
static int min_read_thresh = 8, min_write_thresh;
@@ -32522,7 +32599,7 @@ index 8ae9235..ea94cf2 100644
static int max_write_thresh = INPUT_POOL_WORDS * 32;
static char sysctl_bootid[16];
-@@ -1395,7 +1424,7 @@ static char sysctl_bootid[16];
+@@ -1395,7 +1434,7 @@ static char sysctl_bootid[16];
static int proc_do_uuid(ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
@@ -49494,10 +49571,10 @@ index 451b9b8..12e5a03 100644
out_free_fd:
diff --git a/fs/exec.c b/fs/exec.c
-index 312e297..437233e 100644
+index 312e297..4c133f2 100644
--- a/fs/exec.c
+++ b/fs/exec.c
-@@ -55,12 +55,34 @@
+@@ -55,12 +55,35 @@
#include <linux/pipe_fs_i.h>
#include <linux/oom.h>
#include <linux/compat.h>
@@ -49513,6 +49590,7 @@ index 312e297..437233e 100644
+#include <trace/events/fs.h>
#include <asm/uaccess.h>
++#include <asm/sections.h>
#include <asm/mmu_context.h>
#include <asm/tlb.h>
#include "internal.h"
@@ -49532,7 +49610,7 @@ index 312e297..437233e 100644
int core_uses_pid;
char core_pattern[CORENAME_MAX_SIZE] = "core";
unsigned int core_pipe_limit;
-@@ -70,7 +92,7 @@ struct core_name {
+@@ -70,7 +93,7 @@ struct core_name {
char *corename;
int used, size;
};
@@ -49541,7 +49619,7 @@ index 312e297..437233e 100644
/* The maximal length of core_pattern is also specified in sysctl.c */
-@@ -82,8 +104,8 @@ int __register_binfmt(struct linux_binfmt * fmt, int insert)
+@@ -82,8 +105,8 @@ int __register_binfmt(struct linux_binfmt * fmt, int insert)
if (!fmt)
return -EINVAL;
write_lock(&binfmt_lock);
@@ -49552,7 +49630,7 @@ index 312e297..437233e 100644
write_unlock(&binfmt_lock);
return 0;
}
-@@ -93,7 +115,7 @@ EXPORT_SYMBOL(__register_binfmt);
+@@ -93,7 +116,7 @@ EXPORT_SYMBOL(__register_binfmt);
void unregister_binfmt(struct linux_binfmt * fmt)
{
write_lock(&binfmt_lock);
@@ -49561,7 +49639,7 @@ index 312e297..437233e 100644
write_unlock(&binfmt_lock);
}
-@@ -188,18 +210,10 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
+@@ -188,18 +211,10 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
int write)
{
struct page *page;
@@ -49583,7 +49661,7 @@ index 312e297..437233e 100644
return NULL;
if (write) {
-@@ -215,6 +229,17 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
+@@ -215,6 +230,17 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
if (size <= ARG_MAX)
return page;
@@ -49601,7 +49679,7 @@ index 312e297..437233e 100644
/*
* Limit to 1/4-th the stack size for the argv+env strings.
* This ensures that:
-@@ -274,6 +299,11 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
+@@ -274,6 +300,11 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
vma->vm_end = STACK_TOP_MAX;
vma->vm_start = vma->vm_end - PAGE_SIZE;
vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP;
@@ -49613,7 +49691,7 @@ index 312e297..437233e 100644
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
INIT_LIST_HEAD(&vma->anon_vma_chain);
-@@ -288,6 +318,12 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
+@@ -288,6 +319,12 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
mm->stack_vm = mm->total_vm = 1;
up_write(&mm->mmap_sem);
bprm->p = vma->vm_end - sizeof(void *);
@@ -49626,7 +49704,7 @@ index 312e297..437233e 100644
return 0;
err:
up_write(&mm->mmap_sem);
-@@ -403,12 +439,12 @@ struct user_arg_ptr {
+@@ -403,12 +440,12 @@ struct user_arg_ptr {
union {
const char __user *const __user *native;
#ifdef CONFIG_COMPAT
@@ -49641,7 +49719,7 @@ index 312e297..437233e 100644
{
const char __user *native;
-@@ -417,14 +453,14 @@ static const char __user *get_user_arg_ptr(struct user_arg_ptr argv, int nr)
+@@ -417,14 +454,14 @@ static const char __user *get_user_arg_ptr(struct user_arg_ptr argv, int nr)
compat_uptr_t compat;
if (get_user(compat, argv.ptr.compat + nr))
@@ -49658,7 +49736,7 @@ index 312e297..437233e 100644
return native;
}
-@@ -443,11 +479,12 @@ static int count(struct user_arg_ptr argv, int max)
+@@ -443,11 +480,12 @@ static int count(struct user_arg_ptr argv, int max)
if (!p)
break;
@@ -49673,7 +49751,7 @@ index 312e297..437233e 100644
if (fatal_signal_pending(current))
return -ERESTARTNOHAND;
-@@ -477,7 +514,7 @@ static int copy_strings(int argc, struct user_arg_ptr argv,
+@@ -477,7 +515,7 @@ static int copy_strings(int argc, struct user_arg_ptr argv,
ret = -EFAULT;
str = get_user_arg_ptr(argv, argc);
@@ -49682,7 +49760,7 @@ index 312e297..437233e 100644
goto out;
len = strnlen_user(str, MAX_ARG_STRLEN);
-@@ -559,7 +596,7 @@ int copy_strings_kernel(int argc, const char *const *__argv,
+@@ -559,7 +597,7 @@ int copy_strings_kernel(int argc, const char *const *__argv,
int r;
mm_segment_t oldfs = get_fs();
struct user_arg_ptr argv = {
@@ -49691,7 +49769,7 @@ index 312e297..437233e 100644
};
set_fs(KERNEL_DS);
-@@ -594,7 +631,8 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
+@@ -594,7 +632,8 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
unsigned long new_end = old_end - shift;
struct mmu_gather tlb;
@@ -49701,7 +49779,7 @@ index 312e297..437233e 100644
/*
* ensure there are no vmas between where we want to go
-@@ -603,6 +641,10 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
+@@ -603,6 +642,10 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
if (vma != find_vma(mm, new_start))
return -EFAULT;
@@ -49712,7 +49790,7 @@ index 312e297..437233e 100644
/*
* cover the whole range: [new_start, old_end)
*/
-@@ -683,10 +725,6 @@ int setup_arg_pages(struct linux_binprm *bprm,
+@@ -683,10 +726,6 @@ int setup_arg_pages(struct linux_binprm *bprm,
stack_top = arch_align_stack(stack_top);
stack_top = PAGE_ALIGN(stack_top);
@@ -49723,7 +49801,7 @@ index 312e297..437233e 100644
stack_shift = vma->vm_end - stack_top;
bprm->p -= stack_shift;
-@@ -698,8 +736,28 @@ int setup_arg_pages(struct linux_binprm *bprm,
+@@ -698,8 +737,28 @@ int setup_arg_pages(struct linux_binprm *bprm,
bprm->exec -= stack_shift;
down_write(&mm->mmap_sem);
@@ -49752,7 +49830,7 @@ index 312e297..437233e 100644
/*
* Adjust stack execute permissions; explicitly enable for
* EXSTACK_ENABLE_X, disable for EXSTACK_DISABLE_X and leave alone
-@@ -718,13 +776,6 @@ int setup_arg_pages(struct linux_binprm *bprm,
+@@ -718,13 +777,6 @@ int setup_arg_pages(struct linux_binprm *bprm,
goto out_unlock;
BUG_ON(prev != vma);
@@ -49766,7 +49844,7 @@ index 312e297..437233e 100644
/* mprotect_fixup is overkill to remove the temporary stack flags */
vma->vm_flags &= ~VM_STACK_INCOMPLETE_SETUP;
-@@ -748,6 +799,27 @@ int setup_arg_pages(struct linux_binprm *bprm,
+@@ -748,6 +800,27 @@ int setup_arg_pages(struct linux_binprm *bprm,
#endif
current->mm->start_stack = bprm->p;
ret = expand_stack(vma, stack_base);
@@ -49794,7 +49872,7 @@ index 312e297..437233e 100644
if (ret)
ret = -EFAULT;
-@@ -782,6 +854,8 @@ struct file *open_exec(const char *name)
+@@ -782,6 +855,8 @@ struct file *open_exec(const char *name)
fsnotify_open(file);
@@ -49803,7 +49881,7 @@ index 312e297..437233e 100644
err = deny_write_access(file);
if (err)
goto exit;
-@@ -805,7 +879,7 @@ int kernel_read(struct file *file, loff_t offset,
+@@ -805,7 +880,7 @@ int kernel_read(struct file *file, loff_t offset,
old_fs = get_fs();
set_fs(get_ds());
/* The cast to a user pointer is valid due to the set_fs() */
@@ -49812,7 +49890,7 @@ index 312e297..437233e 100644
set_fs(old_fs);
return result;
}
-@@ -1070,6 +1144,21 @@ void set_task_comm(struct task_struct *tsk, char *buf)
+@@ -1070,6 +1145,21 @@ void set_task_comm(struct task_struct *tsk, char *buf)
perf_event_comm(tsk);
}
@@ -49834,7 +49912,7 @@ index 312e297..437233e 100644
int flush_old_exec(struct linux_binprm * bprm)
{
int retval;
-@@ -1084,6 +1173,7 @@ int flush_old_exec(struct linux_binprm * bprm)
+@@ -1084,6 +1174,7 @@ int flush_old_exec(struct linux_binprm * bprm)
set_mm_exe_file(bprm->mm, bprm->file);
@@ -49842,7 +49920,7 @@ index 312e297..437233e 100644
/*
* Release all of the old mmap stuff
*/
-@@ -1116,10 +1206,6 @@ EXPORT_SYMBOL(would_dump);
+@@ -1116,10 +1207,6 @@ EXPORT_SYMBOL(would_dump);
void setup_new_exec(struct linux_binprm * bprm)
{
@@ -49853,7 +49931,7 @@ index 312e297..437233e 100644
arch_pick_mmap_layout(current->mm);
/* This is the point of no return */
-@@ -1130,18 +1216,7 @@ void setup_new_exec(struct linux_binprm * bprm)
+@@ -1130,18 +1217,7 @@ void setup_new_exec(struct linux_binprm * bprm)
else
set_dumpable(current->mm, suid_dumpable);
@@ -49873,7 +49951,7 @@ index 312e297..437233e 100644
/* Set the new mm task size. We have to do that late because it may
* depend on TIF_32BIT which is only updated in flush_thread() on
-@@ -1266,7 +1341,7 @@ int check_unsafe_exec(struct linux_binprm *bprm)
+@@ -1266,7 +1342,7 @@ int check_unsafe_exec(struct linux_binprm *bprm)
}
rcu_read_unlock();
@@ -49882,7 +49960,7 @@ index 312e297..437233e 100644
bprm->unsafe |= LSM_UNSAFE_SHARE;
} else {
res = -EAGAIN;
-@@ -1461,6 +1536,31 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
+@@ -1461,6 +1537,31 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
EXPORT_SYMBOL(search_binary_handler);
@@ -49914,7 +49992,7 @@ index 312e297..437233e 100644
/*
* sys_execve() executes a new program.
*/
-@@ -1469,6 +1569,11 @@ static int do_execve_common(const char *filename,
+@@ -1469,6 +1570,11 @@ static int do_execve_common(const char *filename,
struct user_arg_ptr envp,
struct pt_regs *regs)
{
@@ -49926,7 +50004,7 @@ index 312e297..437233e 100644
struct linux_binprm *bprm;
struct file *file;
struct files_struct *displaced;
-@@ -1476,6 +1581,8 @@ static int do_execve_common(const char *filename,
+@@ -1476,6 +1582,8 @@ static int do_execve_common(const char *filename,
int retval;
const struct cred *cred = current_cred();
@@ -49935,7 +50013,7 @@ index 312e297..437233e 100644
/*
* We move the actual failure in case of RLIMIT_NPROC excess from
* set*uid() to execve() because too many poorly written programs
-@@ -1516,12 +1623,27 @@ static int do_execve_common(const char *filename,
+@@ -1516,12 +1624,27 @@ static int do_execve_common(const char *filename,
if (IS_ERR(file))
goto out_unmark;
@@ -49963,7 +50041,7 @@ index 312e297..437233e 100644
retval = bprm_mm_init(bprm);
if (retval)
goto out_file;
-@@ -1538,24 +1660,65 @@ static int do_execve_common(const char *filename,
+@@ -1538,24 +1661,65 @@ static int do_execve_common(const char *filename,
if (retval < 0)
goto out;
@@ -50033,7 +50111,7 @@ index 312e297..437233e 100644
current->fs->in_exec = 0;
current->in_execve = 0;
acct_update_integrals(current);
-@@ -1564,6 +1727,14 @@ static int do_execve_common(const char *filename,
+@@ -1564,6 +1728,14 @@ static int do_execve_common(const char *filename,
put_files_struct(displaced);
return retval;
@@ -50048,7 +50126,7 @@ index 312e297..437233e 100644
out:
if (bprm->mm) {
acct_arg_size(bprm, 0);
-@@ -1637,7 +1808,7 @@ static int expand_corename(struct core_name *cn)
+@@ -1637,7 +1809,7 @@ static int expand_corename(struct core_name *cn)
{
char *old_corename = cn->corename;
@@ -50057,7 +50135,7 @@ index 312e297..437233e 100644
cn->corename = krealloc(old_corename, cn->size, GFP_KERNEL);
if (!cn->corename) {
-@@ -1734,7 +1905,7 @@ static int format_corename(struct core_name *cn, long signr)
+@@ -1734,7 +1906,7 @@ static int format_corename(struct core_name *cn, long signr)
int pid_in_pattern = 0;
int err = 0;
@@ -50066,7 +50144,7 @@ index 312e297..437233e 100644
cn->corename = kmalloc(cn->size, GFP_KERNEL);
cn->used = 0;
-@@ -1831,6 +2002,250 @@ out:
+@@ -1831,6 +2003,280 @@ out:
return ispipe;
}
@@ -50271,7 +50349,30 @@ index 312e297..437233e 100644
+}
+#endif
+
-+void __check_object_size(const void *ptr, unsigned long n, bool to)
++#ifdef CONFIG_PAX_USERCOPY
++static inline bool check_kernel_text_object(unsigned long low, unsigned long high)
++{
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
++ unsigned long textlow = ktla_ktva((unsigned long)_stext);
++#ifdef CONFIG_MODULES
++ unsigned long texthigh = (unsigned long)MODULES_EXEC_VADDR;
++#else
++ unsigned long texthigh = ktla_ktva((unsigned long)_etext);
++#endif
++
++#else
++ unsigned long textlow = _stext;
++ unsigned long texthigh = _etext;
++#endif
++
++ if (high <= textlow || low > texthigh)
++ return false;
++ else
++ return true;
++}
++#endif
++
++void __check_object_size(const void *ptr, unsigned long n, bool to_user)
+{
+
+#ifdef CONFIG_PAX_USERCOPY
@@ -50282,12 +50383,19 @@ index 312e297..437233e 100644
+
+ type = check_heap_object(ptr, n);
+ if (!type) {
-+ if (check_stack_object(ptr, n) != -1)
++ int ret = check_stack_object(ptr, n);
++ if (ret == 1 || ret == 2)
+ return;
-+ type = "<process stack>";
++ if (ret == 0) {
++ if (check_kernel_text_object((unsigned long)ptr, (unsigned long)ptr + n))
++ type = "<kernel text>";
++ else
++ return;
++ } else
++ type = "<process stack>";
+ }
+
-+ pax_report_usercopy(ptr, n, to, type);
++ pax_report_usercopy(ptr, n, to_user, type);
+#endif
+
+}
@@ -50317,7 +50425,7 @@ index 312e297..437233e 100644
static int zap_process(struct task_struct *start, int exit_code)
{
struct task_struct *t;
-@@ -2004,17 +2419,17 @@ static void coredump_finish(struct mm_struct *mm)
+@@ -2004,17 +2450,17 @@ static void coredump_finish(struct mm_struct *mm)
void set_dumpable(struct mm_struct *mm, int value)
{
switch (value) {
@@ -50338,7 +50446,7 @@ index 312e297..437233e 100644
set_bit(MMF_DUMP_SECURELY, &mm->flags);
smp_wmb();
set_bit(MMF_DUMPABLE, &mm->flags);
-@@ -2027,7 +2442,7 @@ static int __get_dumpable(unsigned long mm_flags)
+@@ -2027,7 +2473,7 @@ static int __get_dumpable(unsigned long mm_flags)
int ret;
ret = mm_flags & MMF_DUMPABLE_MASK;
@@ -50347,7 +50455,7 @@ index 312e297..437233e 100644
}
int get_dumpable(struct mm_struct *mm)
-@@ -2042,17 +2457,17 @@ static void wait_for_dump_helpers(struct file *file)
+@@ -2042,17 +2488,17 @@ static void wait_for_dump_helpers(struct file *file)
pipe = file->f_path.dentry->d_inode->i_pipe;
pipe_lock(pipe);
@@ -50370,7 +50478,7 @@ index 312e297..437233e 100644
pipe_unlock(pipe);
}
-@@ -2113,7 +2528,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2113,7 +2559,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
int retval = 0;
int flag = 0;
int ispipe;
@@ -50380,7 +50488,7 @@ index 312e297..437233e 100644
struct coredump_params cprm = {
.signr = signr,
.regs = regs,
-@@ -2128,6 +2544,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2128,6 +2575,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
audit_core_dumps(signr);
@@ -50390,7 +50498,7 @@ index 312e297..437233e 100644
binfmt = mm->binfmt;
if (!binfmt || !binfmt->core_dump)
goto fail;
-@@ -2138,14 +2557,16 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2138,14 +2588,16 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
if (!cred)
goto fail;
/*
@@ -50411,7 +50519,7 @@ index 312e297..437233e 100644
}
retval = coredump_wait(exit_code, &core_state);
-@@ -2195,7 +2616,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2195,7 +2647,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
}
cprm.limit = RLIM_INFINITY;
@@ -50420,7 +50528,7 @@ index 312e297..437233e 100644
if (core_pipe_limit && (core_pipe_limit < dump_count)) {
printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit\n",
task_tgid_vnr(current), current->comm);
-@@ -2222,9 +2643,19 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2222,9 +2674,19 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
} else {
struct inode *inode;
@@ -50440,7 +50548,7 @@ index 312e297..437233e 100644
cprm.file = filp_open(cn.corename,
O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag,
0600);
-@@ -2265,7 +2696,7 @@ close_fail:
+@@ -2265,7 +2727,7 @@ close_fail:
filp_close(cprm.file, NULL);
fail_dropcount:
if (ispipe)
@@ -50449,7 +50557,7 @@ index 312e297..437233e 100644
fail_unlock:
kfree(cn.corename);
fail_corename:
-@@ -2284,7 +2715,7 @@ fail:
+@@ -2284,7 +2746,7 @@ fail:
*/
int dump_write(struct file *file, const void *addr, int nr)
{
@@ -50753,6 +50861,39 @@ index cc386b2..22725d2 100644
static int __init ext4_init_feat_adverts(void)
{
+diff --git a/fs/fat/inode.c b/fs/fat/inode.c
+index 808cac7..fc33ca1 100644
+--- a/fs/fat/inode.c
++++ b/fs/fat/inode.c
+@@ -1238,6 +1238,19 @@ static int fat_read_root(struct inode *inode)
+ return 0;
+ }
+
++static unsigned long calc_fat_clusters(struct super_block *sb)
++{
++ struct msdos_sb_info *sbi = MSDOS_SB(sb);
++
++ /* Divide first to avoid overflow */
++ if (sbi->fat_bits != 12) {
++ unsigned long ent_per_sec = sb->s_blocksize * 8 / sbi->fat_bits;
++ return ent_per_sec * sbi->fat_length;
++ }
++
++ return sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
++}
++
+ /*
+ * Read the super block of an MS-DOS FS.
+ */
+@@ -1434,7 +1447,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
+ sbi->fat_bits = (total_clusters > MAX_FAT12) ? 16 : 12;
+
+ /* check that FAT table does not overflow */
+- fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
++ fat_clusters = calc_fat_clusters(sb);
+ total_clusters = min(total_clusters, fat_clusters - FAT_START_ENT);
+ if (total_clusters > MAX_FAT(sb)) {
+ if (!silent)
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
index 216b419..350a088 100644
--- a/fs/fat/namei_msdos.c
@@ -67711,7 +67852,7 @@ index dfadc96..23c5182 100644
#if __GNUC_MINOR__ > 0
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
-index 320d6c9..df26a76 100644
+index 320d6c9..2d1df6b 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -5,31 +5,51 @@
@@ -67824,22 +67965,26 @@ index 320d6c9..df26a76 100644
/* Simple shorthand for a section definition */
#ifndef __section
# define __section(S) __attribute__ ((__section__(#S)))
-@@ -294,6 +348,14 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
- # define __compiletime_error(message)
+@@ -292,6 +346,18 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
#endif
-
+ #ifndef __compiletime_error
+ # define __compiletime_error(message)
++# define __compiletime_error_fallback(condition) \
++ do { ((void)sizeof(char[1 - 2*!!(condition)])); } while (0)
++#else
++# define __compiletime_error_fallback(condition) do { } while (0)
++#endif
++
+#ifndef __size_overflow
+# define __size_overflow(...)
+#endif
+
+#ifndef __intentional_overflow
+# define __intentional_overflow(...)
-+#endif
-+
+ #endif
+
/*
- * Prevent the compiler from merging or refetching accesses. The compiler
- * is also forbidden from reordering successive instances of ACCESS_ONCE(),
-@@ -306,6 +368,7 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
+@@ -306,6 +372,7 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
* use is to mediate communication between process-level code and irq/NMI
* handlers, all running on the same CPU.
*/
@@ -69802,6 +69947,53 @@ index 3875719..4cd454c 100644
/* This macro allows us to keep printk typechecking */
static __printf(1, 2)
+diff --git a/include/linux/kernel.h b/include/linux/kernel.h
+index a70783d..77f7750 100644
+--- a/include/linux/kernel.h
++++ b/include/linux/kernel.h
+@@ -696,24 +696,30 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
+ * @condition: the condition which the compiler should know is false.
+ *
+ * If you have some code which relies on certain constants being equal, or
+- * other compile-time-evaluated condition, you should use BUILD_BUG_ON to
++ * some other compile-time-evaluated condition, you should use BUILD_BUG_ON to
+ * detect if someone changes it.
+ *
+- * The implementation uses gcc's reluctance to create a negative array, but
+- * gcc (as of 4.4) only emits that error for obvious cases (eg. not arguments
+- * to inline functions). So as a fallback we use the optimizer; if it can't
+- * prove the condition is false, it will cause a link error on the undefined
+- * "__build_bug_on_failed". This error message can be harder to track down
+- * though, hence the two different methods.
++ * The implementation uses gcc's reluctance to create a negative array, but gcc
++ * (as of 4.4) only emits that error for obvious cases (e.g. not arguments to
++ * inline functions). Luckily, in 4.3 they added the "error" function
++ * attribute just for this type of case. Thus, we use a negative sized array
++ * (should always create an error on gcc versions older than 4.4) and then call
++ * an undefined function with the error attribute (should always create an
++ * error on gcc 4.3 and later). If for some reason, neither creates a
++ * compile-time error, we'll still have a link-time error, which is harder to
++ * track down.
+ */
+ #ifndef __OPTIMIZE__
+ #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
+ #else
+-extern int __build_bug_on_failed;
+-#define BUILD_BUG_ON(condition) \
+- do { \
+- ((void)sizeof(char[1 - 2*!!(condition)])); \
+- if (condition) __build_bug_on_failed = 1; \
++#define BUILD_BUG_ON(condition) \
++ do { \
++ bool __cond = !!(condition); \
++ extern void __build_bug_on_failed(void) \
++ __compiletime_error("BUILD_BUG_ON failed"); \
++ if (__cond) \
++ __build_bug_on_failed(); \
++ __compiletime_error_fallback(__cond); \
+ } while(0)
+ #endif
+ #endif /* __CHECKER__ */
diff --git a/include/linux/key-type.h b/include/linux/key-type.h
index 9efd081..19f989c 100644
--- a/include/linux/key-type.h
@@ -80550,7 +80742,7 @@ index 2a07f97..2cdc054 100644
set_page_address(page, (void *)vaddr);
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
-index 470cbb4..8d01b5a 100644
+index 470cbb4..9fd73bc 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -704,7 +704,7 @@ out:
@@ -80562,6 +80754,20 @@ index 470cbb4..8d01b5a 100644
return VM_FAULT_OOM;
/* if an huge pmd materialized from under us just retry later */
if (unlikely(pmd_trans_huge(*pmd)))
+@@ -1937,7 +1937,12 @@ static void collapse_huge_page(struct mm_struct *mm,
+ pte_unmap(pte);
+ spin_lock(&mm->page_table_lock);
+ BUG_ON(!pmd_none(*pmd));
+- set_pmd_at(mm, address, pmd, _pmd);
++ /*
++ * We can only use set_pmd_at when establishing
++ * hugepmds and never for establishing regular pmds that
++ * points to regular pagetables. Use pmd_populate for that
++ */
++ pmd_populate(mm, pmd, pmd_pgtable(_pmd));
+ spin_unlock(&mm->page_table_lock);
+ anon_vma_unlock(vma->anon_vma);
+ goto out;
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 70b4733..ab692a7 100644
--- a/mm/hugetlb.c
diff --git a/3.9.4/0000_README b/3.9.4/0000_README
index 5540390..66c5468 100644
--- a/3.9.4/0000_README
+++ b/3.9.4/0000_README
@@ -2,7 +2,7 @@ README
-----------------------------------------------------------------------------
Individual Patch Descriptions:
-----------------------------------------------------------------------------
-Patch: 4420_grsecurity-2.9.1-3.9.4-201305251009.patch
+Patch: 4420_grsecurity-2.9.1-3.9.4-201305292151.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/3.9.4/4420_grsecurity-2.9.1-3.9.4-201305251009.patch b/3.9.4/4420_grsecurity-2.9.1-3.9.4-201305292151.patch
index 6715b49..8cdedca 100644
--- a/3.9.4/4420_grsecurity-2.9.1-3.9.4-201305251009.patch
+++ b/3.9.4/4420_grsecurity-2.9.1-3.9.4-201305292151.patch
@@ -17725,6 +17725,19 @@ index 74467fe..18793d5 100644
crash_fixup_ss_esp(&fixed_regs, regs);
regs = &fixed_regs;
}
+diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c
+index afa64ad..dce67dd 100644
+--- a/arch/x86/kernel/crash_dump_64.c
++++ b/arch/x86/kernel/crash_dump_64.c
+@@ -36,7 +36,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
+ return -ENOMEM;
+
+ if (userbuf) {
+- if (copy_to_user(buf, vaddr + offset, csize)) {
++ if (copy_to_user((char __force_user *)buf, vaddr + offset, csize)) {
+ iounmap(vaddr);
+ return -EFAULT;
+ }
diff --git a/arch/x86/kernel/doublefault_32.c b/arch/x86/kernel/doublefault_32.c
index 37250fe..bf2ec74 100644
--- a/arch/x86/kernel/doublefault_32.c
@@ -29551,7 +29564,7 @@ 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 3cbe4538..fd756dc 100644
+index 3cbe4538..003d011 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -12,6 +12,7 @@
@@ -29562,7 +29575,7 @@ index 3cbe4538..fd756dc 100644
/*
* Conventions :
-@@ -49,13 +50,87 @@ static inline u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len)
+@@ -49,13 +50,90 @@ static inline u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len)
return ptr + len;
}
@@ -29599,6 +29612,7 @@ index 3cbe4538..fd756dc 100644
+ 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); \
@@ -29614,6 +29628,10 @@ index 3cbe4538..fd756dc 100644
+ /* mov esi, ecx */ \
+ EMIT2(0x89, 0xce); \
+ break; \
++ case 0xe8: /* call rel imm32, always to known funcs */ \
++ EMIT1(b1); \
++ EMIT(_off, 4); \
++ break; \
+ case 0xe9: /* jmp rel imm32 */ \
+ EMIT1(b1); \
+ EMIT(_off, 4); \
@@ -29622,8 +29640,7 @@ index 3cbe4538..fd756dc 100644
+ EMIT(0xcccccccc, 4); \
+ break; \
+ default: \
-+ EMIT1(b1); \
-+ EMIT(_off, 4); \
++ BUILD_BUG(); \
+ } \
+} while (0)
+
@@ -29639,8 +29656,7 @@ index 3cbe4538..fd756dc 100644
+ /* imul eax, ecx */ \
+ EMIT3(0x0f, 0xaf, 0xc1); \
+ } else { \
-+ EMIT2(b1, b2); \
-+ EMIT(_off, 4); \
++ BUILD_BUG(); \
+ } \
+} while (0)
+#else
@@ -29650,7 +29666,7 @@ index 3cbe4538..fd756dc 100644
#define CLEAR_A() EMIT2(0x31, 0xc0) /* xor %eax,%eax */
#define CLEAR_X() EMIT2(0x31, 0xdb) /* xor %ebx,%ebx */
-@@ -90,6 +165,24 @@ do { \
+@@ -90,6 +168,24 @@ do { \
#define X86_JBE 0x76
#define X86_JA 0x77
@@ -29675,7 +29691,7 @@ index 3cbe4538..fd756dc 100644
#define EMIT_COND_JMP(op, offset) \
do { \
if (is_near(offset)) \
-@@ -97,6 +190,7 @@ do { \
+@@ -97,6 +193,7 @@ do { \
else { \
EMIT2(0x0f, op + 0x10); \
EMIT(offset, 4); /* jxx .+off32 */ \
@@ -29683,7 +29699,7 @@ index 3cbe4538..fd756dc 100644
} \
} while (0)
-@@ -121,6 +215,11 @@ static inline void bpf_flush_icache(void *start, void *end)
+@@ -121,6 +218,11 @@ static inline void bpf_flush_icache(void *start, void *end)
set_fs(old_fs);
}
@@ -29695,7 +29711,7 @@ index 3cbe4538..fd756dc 100644
#define CHOOSE_LOAD_FUNC(K, func) \
((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset)
-@@ -146,7 +245,7 @@ static int pkt_type_offset(void)
+@@ -146,7 +248,7 @@ static int pkt_type_offset(void)
void bpf_jit_compile(struct sk_filter *fp)
{
@@ -29704,7 +29720,7 @@ index 3cbe4538..fd756dc 100644
u8 *prog;
unsigned int proglen, oldproglen = 0;
int ilen, i;
-@@ -159,6 +258,9 @@ void bpf_jit_compile(struct sk_filter *fp)
+@@ -159,6 +261,9 @@ void bpf_jit_compile(struct sk_filter *fp)
unsigned int *addrs;
const struct sock_filter *filter = fp->insns;
int flen = fp->len;
@@ -29714,7 +29730,7 @@ index 3cbe4538..fd756dc 100644
if (!bpf_jit_enable)
return;
-@@ -167,11 +269,19 @@ void bpf_jit_compile(struct sk_filter *fp)
+@@ -167,11 +272,19 @@ void bpf_jit_compile(struct sk_filter *fp)
if (addrs == NULL)
return;
@@ -29736,7 +29752,7 @@ index 3cbe4538..fd756dc 100644
addrs[i] = proglen;
}
cleanup_addr = proglen; /* epilogue address */
-@@ -282,10 +392,8 @@ void bpf_jit_compile(struct sk_filter *fp)
+@@ -282,10 +395,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 */
@@ -29749,7 +29765,7 @@ index 3cbe4538..fd756dc 100644
break;
case BPF_S_ALU_DIV_X: /* A /= X; */
seen |= SEEN_XREG;
-@@ -325,13 +433,23 @@ void bpf_jit_compile(struct sk_filter *fp)
+@@ -325,13 +436,23 @@ void bpf_jit_compile(struct sk_filter *fp)
break;
case BPF_S_ALU_MOD_K: /* A %= K; */
EMIT2(0x31, 0xd2); /* xor %edx,%edx */
@@ -29773,7 +29789,7 @@ index 3cbe4538..fd756dc 100644
EMIT4(0x48, 0xc1, 0xe8, 0x20); /* shr $0x20,%rax */
break;
case BPF_S_ALU_AND_X:
-@@ -602,8 +720,7 @@ common_load_ind: seen |= SEEN_DATAREF | SEEN_XREG;
+@@ -602,8 +723,7 @@ common_load_ind: seen |= SEEN_DATAREF | SEEN_XREG;
if (is_imm8(K)) {
EMIT3(0x8d, 0x73, K); /* lea imm8(%rbx), %esi */
} else {
@@ -29783,7 +29799,7 @@ index 3cbe4538..fd756dc 100644
}
} else {
EMIT2(0x89,0xde); /* mov %ebx,%esi */
-@@ -686,17 +803,18 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
+@@ -686,17 +806,18 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
break;
default:
/* hmm, too complex filter, give up with jit compiler */
@@ -29806,7 +29822,7 @@ index 3cbe4538..fd756dc 100644
}
proglen += ilen;
addrs[i] = proglen;
-@@ -717,11 +835,9 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
+@@ -717,11 +838,9 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
break;
}
if (proglen == oldproglen) {
@@ -29820,7 +29836,7 @@ index 3cbe4538..fd756dc 100644
}
oldproglen = proglen;
}
-@@ -737,7 +853,10 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
+@@ -737,7 +856,10 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
bpf_flush_icache(image, image + proglen);
fp->bpf_func = (void *)image;
@@ -29832,7 +29848,7 @@ index 3cbe4538..fd756dc 100644
out:
kfree(addrs);
return;
-@@ -745,18 +864,20 @@ out:
+@@ -745,18 +867,20 @@ out:
static void jit_free_defer(struct work_struct *arg)
{
@@ -32940,7 +32956,7 @@ index 519865b..e540db3 100644
subsys_dev_iter_init(&iter, subsys, NULL, NULL);
while ((dev = subsys_dev_iter_next(&iter)))
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
-index 01fc5b0..d0ed716 100644
+index 01fc5b0..917801f 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -348,7 +348,7 @@ int devtmpfs_mount(const char *mntdir)
@@ -32952,6 +32968,21 @@ index 01fc5b0..d0ed716 100644
if (err)
printk(KERN_INFO "devtmpfs: error mounting %i\n", err);
else
+@@ -373,11 +373,11 @@ static int devtmpfsd(void *p)
+ *err = sys_unshare(CLONE_NEWNS);
+ if (*err)
+ goto out;
+- *err = sys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options);
++ *err = sys_mount((char __force_user *)"devtmpfs", (char __force_user *)"/", (char __force_user *)"devtmpfs", MS_SILENT, (char __force_user *)options);
+ if (*err)
+ goto out;
+- sys_chdir("/.."); /* will traverse into overmounted root */
+- sys_chroot(".");
++ sys_chdir((char __force_user *)"/.."); /* will traverse into overmounted root */
++ sys_chroot((char __force_user *)".");
+ complete(&setup_done);
+ while (1) {
+ spin_lock(&req_lock);
diff --git a/drivers/base/node.c b/drivers/base/node.c
index fac124a..66bd4ab 100644
--- a/drivers/base/node.c
@@ -33578,8 +33609,21 @@ index 3bb6fa3..34013fb 100644
default y
source "drivers/s390/char/Kconfig"
+diff --git a/drivers/char/agp/compat_ioctl.c b/drivers/char/agp/compat_ioctl.c
+index a48e05b..6bac831 100644
+--- a/drivers/char/agp/compat_ioctl.c
++++ b/drivers/char/agp/compat_ioctl.c
+@@ -108,7 +108,7 @@ static int compat_agpioc_reserve_wrap(struct agp_file_private *priv, void __user
+ return -ENOMEM;
+ }
+
+- if (copy_from_user(usegment, (void __user *) ureserve.seg_list,
++ if (copy_from_user(usegment, (void __force_user *) ureserve.seg_list,
+ sizeof(*usegment) * ureserve.seg_count)) {
+ kfree(usegment);
+ kfree(ksegment);
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
-index 2e04433..22afc64 100644
+index 2e04433..771f2cc 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -817,7 +817,7 @@ static int agpioc_reserve_wrap(struct agp_file_private *priv, void __user *arg)
@@ -33591,6 +33635,15 @@ index 2e04433..22afc64 100644
return -EFAULT;
client = agp_find_client_by_pid(reserve.pid);
+@@ -847,7 +847,7 @@ static int agpioc_reserve_wrap(struct agp_file_private *priv, void __user *arg)
+ if (segment == NULL)
+ return -ENOMEM;
+
+- if (copy_from_user(segment, (void __user *) reserve.seg_list,
++ if (copy_from_user(segment, (void __force_user *) reserve.seg_list,
+ sizeof(struct agp_segment) * reserve.seg_count)) {
+ kfree(segment);
+ return -EFAULT;
diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c
index 21cb980..f15107c 100644
--- a/drivers/char/genrtc.c
@@ -33685,7 +33738,7 @@ index 0ac9b45..6179fb5 100644
new_smi->interrupt_disabled = 1;
atomic_set(&new_smi->stop_operation, 0);
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
-index 2c644af..b867b3e 100644
+index 2c644af..d4d7f17 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -18,6 +18,7 @@
@@ -33766,6 +33819,15 @@ index 2c644af..b867b3e 100644
unxlate_dev_mem_ptr(p, ptr);
if (remaining)
return -EFAULT;
+@@ -378,7 +409,7 @@ static ssize_t read_oldmem(struct file *file, char __user *buf,
+ else
+ csize = count;
+
+- rc = copy_oldmem_page(pfn, buf, csize, offset, 1);
++ rc = copy_oldmem_page(pfn, (char __force_kernel *)buf, csize, offset, 1);
+ if (rc < 0)
+ return rc;
+ buf += csize;
@@ -398,9 +429,8 @@ static ssize_t read_kmem(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
@@ -33909,7 +33971,7 @@ index 5c5cc00..ac9edb7 100644
if (cmd != SIOCWANDEV)
diff --git a/drivers/char/random.c b/drivers/char/random.c
-index 32a6c57..e7f0f7b 100644
+index 32a6c57..98038d5 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -272,8 +272,13 @@
@@ -33955,7 +34017,85 @@ index 32a6c57..e7f0f7b 100644
smp_wmb();
if (out)
-@@ -1024,7 +1036,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
+@@ -865,16 +877,24 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
+ if (r->entropy_count / 8 < min + reserved) {
+ nbytes = 0;
+ } else {
++ int entropy_count, orig;
++retry:
++ entropy_count = orig = ACCESS_ONCE(r->entropy_count);
+ /* If limited, never pull more than available */
+- if (r->limit && nbytes + reserved >= r->entropy_count / 8)
+- nbytes = r->entropy_count/8 - reserved;
++ if (r->limit && nbytes + reserved >= entropy_count / 8)
++ nbytes = entropy_count/8 - reserved;
+
+- if (r->entropy_count / 8 >= nbytes + reserved)
+- r->entropy_count -= nbytes*8;
+- else
+- r->entropy_count = reserved;
++ if (entropy_count / 8 >= nbytes + reserved) {
++ entropy_count -= nbytes*8;
++ if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
++ goto retry;
++ } else {
++ entropy_count = reserved;
++ if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
++ goto retry;
++ }
+
+- if (r->entropy_count < random_write_wakeup_thresh)
++ if (entropy_count < random_write_wakeup_thresh)
+ wakeup_write = 1;
+ }
+
+@@ -957,10 +977,23 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
+ {
+ ssize_t ret = 0, i;
+ __u8 tmp[EXTRACT_SIZE];
++ unsigned long flags;
+
+ /* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */
+- if (fips_enabled && !r->last_data_init)
+- nbytes += EXTRACT_SIZE;
++ if (fips_enabled) {
++ spin_lock_irqsave(&r->lock, flags);
++ if (!r->last_data_init) {
++ r->last_data_init = true;
++ spin_unlock_irqrestore(&r->lock, flags);
++ trace_extract_entropy(r->name, EXTRACT_SIZE,
++ r->entropy_count, _RET_IP_);
++ xfer_secondary_pool(r, EXTRACT_SIZE);
++ extract_buf(r, tmp);
++ spin_lock_irqsave(&r->lock, flags);
++ memcpy(r->last_data, tmp, EXTRACT_SIZE);
++ }
++ spin_unlock_irqrestore(&r->lock, flags);
++ }
+
+ trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_);
+ xfer_secondary_pool(r, nbytes);
+@@ -970,19 +1003,6 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
+ extract_buf(r, tmp);
+
+ if (fips_enabled) {
+- unsigned long flags;
+-
+-
+- /* prime last_data value if need be, per fips 140-2 */
+- if (!r->last_data_init) {
+- spin_lock_irqsave(&r->lock, flags);
+- memcpy(r->last_data, tmp, EXTRACT_SIZE);
+- r->last_data_init = true;
+- nbytes -= EXTRACT_SIZE;
+- spin_unlock_irqrestore(&r->lock, flags);
+- extract_buf(r, tmp);
+- }
+-
+ spin_lock_irqsave(&r->lock, flags);
+ if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))
+ panic("Hardware RNG duplicated output!\n");
+@@ -1024,7 +1044,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
extract_buf(r, tmp);
i = min_t(int, nbytes, EXTRACT_SIZE);
@@ -33964,7 +34104,7 @@ index 32a6c57..e7f0f7b 100644
ret = -EFAULT;
break;
}
-@@ -1360,7 +1372,7 @@ EXPORT_SYMBOL(generate_random_uuid);
+@@ -1360,7 +1380,7 @@ EXPORT_SYMBOL(generate_random_uuid);
#include <linux/sysctl.h>
static int min_read_thresh = 8, min_write_thresh;
@@ -33973,7 +34113,7 @@ index 32a6c57..e7f0f7b 100644
static int max_write_thresh = INPUT_POOL_WORDS * 32;
static char sysctl_bootid[16];
-@@ -1376,7 +1388,7 @@ static char sysctl_bootid[16];
+@@ -1376,7 +1396,7 @@ static char sysctl_bootid[16];
static int proc_do_uuid(ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
@@ -35984,6 +36124,28 @@ index 3eb1486..0a47ee9 100644
} while (*seqno == 0);
if (!(fifo_state->capabilities & SVGA_FIFO_CAP_FENCE)) {
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+index c509d40..3b640c3 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+@@ -138,7 +138,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data,
+ int ret;
+
+ num_clips = arg->num_clips;
+- clips_ptr = (struct drm_vmw_rect *)(unsigned long)arg->clips_ptr;
++ clips_ptr = (struct drm_vmw_rect __user *)(unsigned long)arg->clips_ptr;
+
+ if (unlikely(num_clips == 0))
+ return 0;
+@@ -222,7 +222,7 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data,
+ int ret;
+
+ num_clips = arg->num_clips;
+- clips_ptr = (struct drm_vmw_rect *)(unsigned long)arg->clips_ptr;
++ clips_ptr = (struct drm_vmw_rect __user *)(unsigned long)arg->clips_ptr;
+
+ if (unlikely(num_clips == 0))
+ return 0;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c
index 4640adb..e1384ed 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c
@@ -36341,6 +36503,19 @@ index 29015eb..af2d8e9 100644
/* Wrapper access functions for multiplexed SMBus */
static DEFINE_MUTEX(nforce2_lock);
+diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
+index c3ccdea..5b3dc1a 100644
+--- a/drivers/i2c/i2c-dev.c
++++ b/drivers/i2c/i2c-dev.c
+@@ -271,7 +271,7 @@ static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,
+ break;
+ }
+
+- data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf;
++ data_ptrs[i] = (u8 __force_user *)rdwr_pa[i].buf;
+ rdwr_pa[i].buf = memdup_user(data_ptrs[i], rdwr_pa[i].len);
+ if (IS_ERR(rdwr_pa[i].buf)) {
+ res = PTR_ERR(rdwr_pa[i].buf);
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 8126824..55a2798 100644
--- a/drivers/ide/ide-cd.c
@@ -38425,11 +38600,72 @@ index 9578a67..31aa652 100644
/* debug */
static int dvb_usb_dw2102_debug;
+diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+index 7157af3..139e91a 100644
+--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
++++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+@@ -326,7 +326,7 @@ struct v4l2_buffer32 {
+ __u32 reserved;
+ };
+
+-static int get_v4l2_plane32(struct v4l2_plane *up, struct v4l2_plane32 *up32,
++static int get_v4l2_plane32(struct v4l2_plane __user *up, struct v4l2_plane32 __user *up32,
+ enum v4l2_memory memory)
+ {
+ void __user *up_pln;
+@@ -355,7 +355,7 @@ static int get_v4l2_plane32(struct v4l2_plane *up, struct v4l2_plane32 *up32,
+ return 0;
+ }
+
+-static int put_v4l2_plane32(struct v4l2_plane *up, struct v4l2_plane32 *up32,
++static int put_v4l2_plane32(struct v4l2_plane __user *up, struct v4l2_plane32 __user *up32,
+ enum v4l2_memory memory)
+ {
+ if (copy_in_user(up32, up, 2 * sizeof(__u32)) ||
+@@ -772,7 +772,7 @@ static int put_v4l2_subdev_edid32(struct v4l2_subdev_edid *kp, struct v4l2_subde
+ put_user(kp->start_block, &up->start_block) ||
+ put_user(kp->blocks, &up->blocks) ||
+ put_user(tmp, &up->edid) ||
+- copy_to_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
++ copy_to_user(up->reserved, kp->reserved, sizeof(kp->reserved)))
+ return -EFAULT;
+ return 0;
+ }
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
-index aa6e7c7..4cd8061 100644
+index aa6e7c7..cb5de87 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
-@@ -1923,7 +1923,8 @@ struct v4l2_ioctl_info {
+@@ -236,7 +236,7 @@ static void v4l_print_format(const void *arg, bool write_only)
+ const struct v4l2_vbi_format *vbi;
+ const struct v4l2_sliced_vbi_format *sliced;
+ const struct v4l2_window *win;
+- const struct v4l2_clip *clip;
++ const struct v4l2_clip __user *pclip;
+ unsigned i;
+
+ pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
+@@ -284,12 +284,16 @@ static void v4l_print_format(const void *arg, bool write_only)
+ win->w.left, win->w.top,
+ prt_names(win->field, v4l2_field_names),
+ win->chromakey, win->bitmap, win->global_alpha);
+- clip = win->clips;
++ pclip = win->clips;
+ for (i = 0; i < win->clipcount; i++) {
++ struct v4l2_clip clip;
++
++ if (copy_from_user(&clip, pclip, sizeof clip))
++ break;
+ printk(KERN_DEBUG "clip %u: wxh=%dx%d, x,y=%d,%d\n",
+- i, clip->c.width, clip->c.height,
+- clip->c.left, clip->c.top);
+- clip = clip->next;
++ i, clip.c.width, clip.c.height,
++ clip.c.left, clip.c.top);
++ pclip = clip.next;
+ }
+ break;
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+@@ -1923,7 +1927,8 @@ struct v4l2_ioctl_info {
struct file *file, void *fh, void *p);
} u;
void (*debug)(const void *arg, bool write_only);
@@ -38439,7 +38675,7 @@ index aa6e7c7..4cd8061 100644
/* This control needs a priority check */
#define INFO_FL_PRIO (1 << 0)
-@@ -2108,7 +2109,7 @@ static long __video_do_ioctl(struct file *file,
+@@ -2108,7 +2113,7 @@ static long __video_do_ioctl(struct file *file,
struct video_device *vfd = video_devdata(file);
const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
bool write_only = false;
@@ -38448,6 +38684,33 @@ index aa6e7c7..4cd8061 100644
const struct v4l2_ioctl_info *info;
void *fh = file->private_data;
struct v4l2_fh *vfh = NULL;
+@@ -2193,7 +2198,7 @@ done:
+ }
+
+ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
+- void * __user *user_ptr, void ***kernel_ptr)
++ void __user **user_ptr, void ***kernel_ptr)
+ {
+ int ret = 0;
+
+@@ -2209,7 +2214,7 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
+ ret = -EINVAL;
+ break;
+ }
+- *user_ptr = (void __user *)buf->m.planes;
++ *user_ptr = (void __force_user *)buf->m.planes;
+ *kernel_ptr = (void *)&buf->m.planes;
+ *array_size = sizeof(struct v4l2_plane) * buf->length;
+ ret = 1;
+@@ -2244,7 +2249,7 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
+ ret = -EINVAL;
+ break;
+ }
+- *user_ptr = (void __user *)ctrls->controls;
++ *user_ptr = (void __force_user *)ctrls->controls;
+ *kernel_ptr = (void *)&ctrls->controls;
+ *array_size = sizeof(struct v4l2_ext_control)
+ * ctrls->count;
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index fb69baa..3aeea2e 100644
--- a/drivers/message/fusion/mptbase.c
@@ -47532,6 +47795,19 @@ index fef20db..d28b1ab 100644
if (!file->private_data)
return -ENOMEM;
return 0;
+diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c
+index 0ad61c6..f198bd7 100644
+--- a/fs/9p/vfs_addr.c
++++ b/fs/9p/vfs_addr.c
+@@ -185,7 +185,7 @@ static int v9fs_vfs_writepage_locked(struct page *page)
+
+ retval = v9fs_file_write_internal(inode,
+ v9inode->writeback_fid,
+- (__force const char __user *)buffer,
++ (const char __force_user *)buffer,
+ len, &offset, 0);
+ if (retval > 0)
+ retval = 0;
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index d86edc8..40ff2fb 100644
--- a/fs/9p/vfs_inode.c
@@ -47769,7 +48045,7 @@ index bbc8f88..7c7ac97 100644
fd_offset + ex.a_text);
if (error != N_DATADDR(ex)) {
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
-index 86af964..8a1da7e 100644
+index 86af964..5d53bf6 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -34,6 +34,7 @@
@@ -48004,7 +48280,7 @@ index 86af964..8a1da7e 100644
+#endif
+
+#ifdef CONFIG_PAX_EMUTRAMP
-+ if (pax_flags_softmode & MF_PAX_EMUTRAMP)
++ if ((pax_flags_softmode & MF_PAX_EMUTRAMP) && (pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)))
+ pax_flags |= MF_PAX_EMUTRAMP;
+#endif
+
@@ -48465,6 +48741,15 @@ index 86af964..8a1da7e 100644
fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv);
}
+@@ -1394,7 +1841,7 @@ static void fill_siginfo_note(struct memelfnote *note, user_siginfo_t *csigdata,
+ {
+ mm_segment_t old_fs = get_fs();
+ set_fs(KERNEL_DS);
+- copy_siginfo_to_user((user_siginfo_t __user *) csigdata, siginfo);
++ copy_siginfo_to_user((user_siginfo_t __force_user *) csigdata, siginfo);
+ set_fs(old_fs);
+ fill_note(note, "CORE", NT_SIGINFO, sizeof(*csigdata), csigdata);
+ }
@@ -2015,14 +2462,14 @@ static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
}
@@ -49580,7 +49865,7 @@ index a81147e..20bf2b5 100644
/*
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
-index 3ced75f..1eeca06 100644
+index 3ced75f..b28d192 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -623,7 +623,7 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd,
@@ -49592,6 +49877,17 @@ index 3ced75f..1eeca06 100644
if (__get_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift) ||
__get_user(ss.port_high, &ss32->port_high))
return -EFAULT;
+@@ -704,8 +704,8 @@ static int do_i2c_rdwr_ioctl(unsigned int fd, unsigned int cmd,
+ for (i = 0; i < nmsgs; i++) {
+ if (copy_in_user(&tmsgs[i].addr, &umsgs[i].addr, 3*sizeof(u16)))
+ return -EFAULT;
+- if (get_user(datap, &umsgs[i].buf) ||
+- put_user(compat_ptr(datap), &tmsgs[i].buf))
++ if (get_user(datap, (u8 __user * __user *)&umsgs[i].buf) ||
++ put_user(compat_ptr(datap), (u8 __user * __user *)&tmsgs[i].buf))
+ return -EFAULT;
+ }
+ return sys_ioctl(fd, cmd, (unsigned long)tdata);
@@ -798,7 +798,7 @@ static int compat_ioctl_preallocate(struct file *file,
copy_in_user(&p->l_len, &p32->l_len, sizeof(s64)) ||
copy_in_user(&p->l_sysid, &p32->l_sysid, sizeof(s32)) ||
@@ -49839,7 +50135,7 @@ index 6a16053..2155147 100644
return rc;
}
diff --git a/fs/exec.c b/fs/exec.c
-index 6d56ff2..fe44505 100644
+index 6d56ff2..3bc6638 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -55,8 +55,20 @@
@@ -50016,7 +50312,7 @@ index 6d56ff2..fe44505 100644
mm_segment_t oldfs = get_fs();
struct user_arg_ptr argv = {
- .ptr.native = (const char __user *const __user *)__argv,
-+ .ptr.native = (const char __force_user *const __force_user *)__argv,
++ .ptr.native = (const char __force_user * const __force_user *)__argv,
};
set_fs(KERNEL_DS);
@@ -50540,8 +50836,8 @@ index 6d56ff2..fe44505 100644
+#endif
+
+#else
-+ unsigned long textlow = _stext;
-+ unsigned long texthigh = _etext;
++ unsigned long textlow = (unsigned long)_stext;
++ unsigned long texthigh = (unsigned long)_etext;
+#endif
+
+ if (high <= textlow || low > texthigh)
@@ -50813,6 +51109,39 @@ index febbe0e..782c4fd 100644
static int parse_strtoul(const char *buf,
unsigned long max, unsigned long *value)
+diff --git a/fs/fat/inode.c b/fs/fat/inode.c
+index acf6e47..e7a7fde 100644
+--- a/fs/fat/inode.c
++++ b/fs/fat/inode.c
+@@ -1223,6 +1223,19 @@ static int fat_read_root(struct inode *inode)
+ return 0;
+ }
+
++static unsigned long calc_fat_clusters(struct super_block *sb)
++{
++ struct msdos_sb_info *sbi = MSDOS_SB(sb);
++
++ /* Divide first to avoid overflow */
++ if (sbi->fat_bits != 12) {
++ unsigned long ent_per_sec = sb->s_blocksize * 8 / sbi->fat_bits;
++ return ent_per_sec * sbi->fat_length;
++ }
++
++ return sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
++}
++
+ /*
+ * Read the super block of an MS-DOS FS.
+ */
+@@ -1427,7 +1440,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
+ sbi->dirty = b->fat16.state & FAT_STATE_DIRTY;
+
+ /* check that FAT table does not overflow */
+- fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
++ fat_clusters = calc_fat_clusters(sb);
+ total_clusters = min(total_clusters, fat_clusters - FAT_START_ENT);
+ if (total_clusters > MAX_FAT(sb)) {
+ if (!silent)
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 6599222..e7bf0de 100644
--- a/fs/fcntl.c
@@ -53240,7 +53569,7 @@ index 85e40d1..b66744e 100644
out:
return len;
diff --git a/fs/namespace.c b/fs/namespace.c
-index e945b81..1dd8104 100644
+index e945b81..fc018e2 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1219,6 +1219,9 @@ static int do_umount(struct mount *mnt, int flags)
@@ -53263,6 +53592,24 @@ index e945b81..1dd8104 100644
return retval;
}
+@@ -1257,7 +1263,7 @@ static inline bool may_mount(void)
+ * unixes. Our API is identical to OSF/1 to avoid making a mess of AMD
+ */
+
+-SYSCALL_DEFINE2(umount, char __user *, name, int, flags)
++SYSCALL_DEFINE2(umount, const char __user *, name, int, flags)
+ {
+ struct path path;
+ struct mount *mnt;
+@@ -1297,7 +1303,7 @@ out:
+ /*
+ * The 2.0 compatible umount. No flags.
+ */
+-SYSCALL_DEFINE1(oldumount, char __user *, name)
++SYSCALL_DEFINE1(oldumount, const char __user *, name)
+ {
+ return sys_umount(name, 0);
+ }
@@ -2267,6 +2273,16 @@ long do_mount(const char *dev_name, const char *dir_name,
MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
MS_STRICTATIME);
@@ -53290,6 +53637,17 @@ index e945b81..1dd8104 100644
return retval;
}
+@@ -2454,8 +2473,8 @@ struct dentry *mount_subtree(struct vfsmount *mnt, const char *name)
+ }
+ EXPORT_SYMBOL(mount_subtree);
+
+-SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
+- char __user *, type, unsigned long, flags, void __user *, data)
++SYSCALL_DEFINE5(mount, const char __user *, dev_name, const char __user *, dir_name,
++ const char __user *, type, unsigned long, flags, void __user *, data)
+ {
+ int ret;
+ char *kernel_type;
@@ -2567,6 +2586,11 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
if (error)
goto out2;
@@ -55257,6 +55615,36 @@ index 56123a6..5a2f6ec 100644
} else if (mm) {
pid_t tid = vm_is_stack(priv->task, vma, is_pid);
+diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
+index b870f74..e9048df 100644
+--- a/fs/proc/vmcore.c
++++ b/fs/proc/vmcore.c
+@@ -98,9 +98,13 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
+ nr_bytes = count;
+
+ /* If pfn is not ram, return zeros for sparse dump files */
+- if (pfn_is_ram(pfn) == 0)
+- memset(buf, 0, nr_bytes);
+- else {
++ if (pfn_is_ram(pfn) == 0) {
++ if (userbuf) {
++ if (clear_user((char __force_user *)buf, nr_bytes))
++ return -EFAULT;
++ } else
++ memset(buf, 0, nr_bytes);
++ } else {
+ tmp = copy_oldmem_page(pfn, buf, nr_bytes,
+ offset, userbuf);
+ if (tmp < 0)
+@@ -185,7 +189,7 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer,
+ if (tsz > nr_bytes)
+ tsz = nr_bytes;
+
+- tmp = read_from_oldmem(buffer, tsz, &start, 1);
++ tmp = read_from_oldmem((char __force_kernel *)buffer, tsz, &start, 1);
+ if (tmp < 0)
+ return tmp;
+ buflen -= tsz;
diff --git a/fs/qnx6/qnx6.h b/fs/qnx6/qnx6.h
index b00fcc9..e0c6381 100644
--- a/fs/qnx6/qnx6.h
@@ -55301,6 +55689,19 @@ index 16e8abb..2dcf914 100644
&quota_genl_family, 0, QUOTA_NL_C_WARNING);
if (!msg_head) {
printk(KERN_ERR
+diff --git a/fs/read_write.c b/fs/read_write.c
+index e6ddc8d..9155227 100644
+--- a/fs/read_write.c
++++ b/fs/read_write.c
+@@ -429,7 +429,7 @@ ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t
+
+ old_fs = get_fs();
+ set_fs(get_ds());
+- p = (__force const char __user *)buf;
++ p = (const char __force_user *)buf;
+ if (count > MAX_RW_COUNT)
+ count = MAX_RW_COUNT;
+ if (file->f_op->write)
diff --git a/fs/readdir.c b/fs/readdir.c
index fee38e0..12fdf47 100644
--- a/fs/readdir.c
@@ -71166,9 +71567,25 @@ index a5ffd32..0935dea 100644
extern dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size,
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
-index 313a8e0..1da8fc6 100644
+index 313a8e0..6b273a9 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
+@@ -418,11 +418,11 @@ asmlinkage long sys_sync(void);
+ asmlinkage long sys_fsync(unsigned int fd);
+ asmlinkage long sys_fdatasync(unsigned int fd);
+ asmlinkage long sys_bdflush(int func, long data);
+-asmlinkage long sys_mount(char __user *dev_name, char __user *dir_name,
+- char __user *type, unsigned long flags,
++asmlinkage long sys_mount(const char __user *dev_name, const char __user *dir_name,
++ const char __user *type, unsigned long flags,
+ void __user *data);
+-asmlinkage long sys_umount(char __user *name, int flags);
+-asmlinkage long sys_oldumount(char __user *name);
++asmlinkage long sys_umount(const char __user *name, int flags);
++asmlinkage long sys_oldumount(const char __user *name);
+ asmlinkage long sys_truncate(const char __user *path, long length);
+ asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length);
+ asmlinkage long sys_stat(const char __user *filename,
@@ -634,7 +634,7 @@ asmlinkage long sys_getsockname(int, struct sockaddr __user *, int __user *);
asmlinkage long sys_getpeername(int, struct sockaddr __user *, int __user *);
asmlinkage long sys_send(int, void __user *, size_t, unsigned);
@@ -72924,9 +73341,27 @@ index f5b978a..69dbfe8 100644
if (!S_ISBLK(stat.st_mode))
return 0;
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
-index a32ec1c..ac08811 100644
+index a32ec1c..60a6659 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
+@@ -37,13 +37,13 @@ static int init_linuxrc(struct subprocess_info *info, struct cred *new)
+ {
+ sys_unshare(CLONE_FS | CLONE_FILES);
+ /* stdin/stdout/stderr for /linuxrc */
+- sys_open("/dev/console", O_RDWR, 0);
++ sys_open((const char __force_user *)"/dev/console", O_RDWR, 0);
+ sys_dup(0);
+ sys_dup(0);
+ /* move initrd over / and chdir/chroot in initrd root */
+- sys_chdir("/root");
+- sys_mount(".", "/", NULL, MS_MOVE, NULL);
+- sys_chroot(".");
++ sys_chdir((const char __force_user *)"/root");
++ sys_mount((char __force_user *)".", (char __force_user *)"/", NULL, MS_MOVE, NULL);
++ sys_chroot((const char __force_user *)".");
+ sys_setsid();
+ return 0;
+ }
@@ -58,8 +58,8 @@ static void __init handle_initrd(void)
create_dev("/dev/root.old", Root_RAM0);
/* mount initrd on rootfs' /root */
@@ -73149,7 +73584,7 @@ index a67ef9d..3d88592 100644
next_state = Reset;
return 0;
diff --git a/init/main.c b/init/main.c
-index 63534a1..8abcaf1 100644
+index 63534a1..85feae2 100644
--- a/init/main.c
+++ b/init/main.c
@@ -98,6 +98,8 @@ static inline void mark_rodata_ro(void) { }
@@ -73286,6 +73721,17 @@ index 63534a1..8abcaf1 100644
}
/*
+@@ -811,8 +884,8 @@ static int run_init_process(const char *init_filename)
+ {
+ argv_init[0] = init_filename;
+ return do_execve(init_filename,
+- (const char __user *const __user *)argv_init,
+- (const char __user *const __user *)envp_init);
++ (const char __user *const __force_user *)argv_init,
++ (const char __user *const __force_user *)envp_init);
+ }
+
+ static noinline void __init kernel_init_freeable(void);
@@ -890,7 +963,7 @@ static noinline void __init kernel_init_freeable(void)
do_basic_setup();
@@ -74134,7 +74580,7 @@ index 00eb8f7..d7e3244 100644
#ifdef CONFIG_MODULE_UNLOAD
{
diff --git a/kernel/events/core.c b/kernel/events/core.c
-index 9fcb094..5c06aeb 100644
+index 9fcb094..fd68c54 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -155,7 +155,11 @@ static struct srcu_struct pmus_srcu;
@@ -74193,6 +74639,15 @@ index 9fcb094..5c06aeb 100644
arch_perf_update_userpage(userpg, now);
+@@ -3886,7 +3890,7 @@ perf_output_sample_ustack(struct perf_output_handle *handle, u64 dump_size,
+
+ /* Data. */
+ sp = perf_user_stack_pointer(regs);
+- rem = __output_copy_user(handle, (void *) sp, dump_size);
++ rem = __output_copy_user(handle, (void __user *) sp, dump_size);
+ dyn_size = dump_size - rem;
+
+ perf_output_skip(handle, rem);
@@ -3974,11 +3978,11 @@ static void perf_output_read_one(struct perf_output_handle *handle,
values[n++] = perf_event_count(event);
if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
@@ -74245,6 +74700,44 @@ index 9fcb094..5c06aeb 100644
&parent_event->child_total_time_running);
/*
+diff --git a/kernel/events/internal.h b/kernel/events/internal.h
+index eb675c4..54912ff 100644
+--- a/kernel/events/internal.h
++++ b/kernel/events/internal.h
+@@ -77,10 +77,10 @@ static inline unsigned long perf_data_size(struct ring_buffer *rb)
+ return rb->nr_pages << (PAGE_SHIFT + page_order(rb));
+ }
+
+-#define DEFINE_OUTPUT_COPY(func_name, memcpy_func) \
++#define DEFINE_OUTPUT_COPY(func_name, memcpy_func, user) \
+ static inline unsigned int \
+ func_name(struct perf_output_handle *handle, \
+- const void *buf, unsigned int len) \
++ const void user *buf, unsigned int len) \
+ { \
+ unsigned long size, written; \
+ \
+@@ -112,17 +112,17 @@ static inline int memcpy_common(void *dst, const void *src, size_t n)
+ return n;
+ }
+
+-DEFINE_OUTPUT_COPY(__output_copy, memcpy_common)
++DEFINE_OUTPUT_COPY(__output_copy, memcpy_common, )
+
+ #define MEMCPY_SKIP(dst, src, n) (n)
+
+-DEFINE_OUTPUT_COPY(__output_skip, MEMCPY_SKIP)
++DEFINE_OUTPUT_COPY(__output_skip, MEMCPY_SKIP, )
+
+ #ifndef arch_perf_out_copy_user
+ #define arch_perf_out_copy_user __copy_from_user_inatomic
+ #endif
+
+-DEFINE_OUTPUT_COPY(__output_copy_user, arch_perf_out_copy_user)
++DEFINE_OUTPUT_COPY(__output_copy_user, arch_perf_out_copy_user, __user)
+
+ /* Callchain handling */
+ extern struct perf_callchain_entry *
diff --git a/kernel/exit.c b/kernel/exit.c
index 60bc027..ca6d727 100644
--- a/kernel/exit.c
@@ -79822,6 +80315,24 @@ index b32b70c..e512eb0 100644
pkmap_count[last_pkmap_nr] = 1;
set_page_address(page, (void *)vaddr);
+diff --git a/mm/huge_memory.c b/mm/huge_memory.c
+index e2f7f5aa..a4510d4 100644
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -2318,7 +2318,12 @@ static void collapse_huge_page(struct mm_struct *mm,
+ pte_unmap(pte);
+ spin_lock(&mm->page_table_lock);
+ BUG_ON(!pmd_none(*pmd));
+- set_pmd_at(mm, address, pmd, _pmd);
++ /*
++ * We can only use set_pmd_at when establishing
++ * hugepmds and never for establishing regular pmds that
++ * points to regular pagetables. Use pmd_populate for that
++ */
++ pmd_populate(mm, pmd, pmd_pgtable(_pmd));
+ spin_unlock(&mm->page_table_lock);
+ anon_vma_unlock_write(vma->anon_vma);
+ goto out;
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 1a12f5b..a85b8fc 100644
--- a/mm/hugetlb.c
@@ -82287,6 +82798,133 @@ index 0dceed8..671951c 100644
vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c
+index be04122..6725ff1 100644
+--- a/mm/mmu_notifier.c
++++ b/mm/mmu_notifier.c
+@@ -40,48 +40,44 @@ void __mmu_notifier_release(struct mm_struct *mm)
+ int id;
+
+ /*
+- * srcu_read_lock() here will block synchronize_srcu() in
+- * mmu_notifier_unregister() until all registered
+- * ->release() callouts this function makes have
+- * returned.
++ * SRCU here will block mmu_notifier_unregister until
++ * ->release returns.
+ */
+ id = srcu_read_lock(&srcu);
++ hlist_for_each_entry_rcu(mn, &mm->mmu_notifier_mm->list, hlist)
++ /*
++ * If ->release runs before mmu_notifier_unregister it must be
++ * handled, as it's the only way for the driver to flush all
++ * existing sptes and stop the driver from establishing any more
++ * sptes before all the pages in the mm are freed.
++ */
++ if (mn->ops->release)
++ mn->ops->release(mn, mm);
++ srcu_read_unlock(&srcu, id);
++
+ spin_lock(&mm->mmu_notifier_mm->lock);
+ while (unlikely(!hlist_empty(&mm->mmu_notifier_mm->list))) {
+ mn = hlist_entry(mm->mmu_notifier_mm->list.first,
+ struct mmu_notifier,
+ hlist);
+-
+ /*
+- * Unlink. This will prevent mmu_notifier_unregister()
+- * from also making the ->release() callout.
++ * We arrived before mmu_notifier_unregister so
++ * mmu_notifier_unregister will do nothing other than to wait
++ * for ->release to finish and for mmu_notifier_unregister to
++ * return.
+ */
+ hlist_del_init_rcu(&mn->hlist);
+- spin_unlock(&mm->mmu_notifier_mm->lock);
+-
+- /*
+- * Clear sptes. (see 'release' description in mmu_notifier.h)
+- */
+- if (mn->ops->release)
+- mn->ops->release(mn, mm);
+-
+- spin_lock(&mm->mmu_notifier_mm->lock);
+ }
+ spin_unlock(&mm->mmu_notifier_mm->lock);
+
+ /*
+- * All callouts to ->release() which we have done are complete.
+- * Allow synchronize_srcu() in mmu_notifier_unregister() to complete
+- */
+- srcu_read_unlock(&srcu, id);
+-
+- /*
+- * mmu_notifier_unregister() may have unlinked a notifier and may
+- * still be calling out to it. Additionally, other notifiers
+- * may have been active via vmtruncate() et. al. Block here
+- * to ensure that all notifier callouts for this mm have been
+- * completed and the sptes are really cleaned up before returning
+- * to exit_mmap().
++ * synchronize_srcu here prevents mmu_notifier_release from returning to
++ * exit_mmap (which would proceed with freeing all pages in the mm)
++ * until the ->release method returns, if it was invoked by
++ * mmu_notifier_unregister.
++ *
++ * The mmu_notifier_mm can't go away from under us because one mm_count
++ * is held by exit_mmap.
+ */
+ synchronize_srcu(&srcu);
+ }
+@@ -292,31 +288,34 @@ void mmu_notifier_unregister(struct mmu_notifier *mn, struct mm_struct *mm)
+ {
+ BUG_ON(atomic_read(&mm->mm_count) <= 0);
+
+- spin_lock(&mm->mmu_notifier_mm->lock);
+ if (!hlist_unhashed(&mn->hlist)) {
++ /*
++ * SRCU here will force exit_mmap to wait for ->release to
++ * finish before freeing the pages.
++ */
+ int id;
+
+- /*
+- * Ensure we synchronize up with __mmu_notifier_release().
+- */
+ id = srcu_read_lock(&srcu);
+-
+- hlist_del_rcu(&mn->hlist);
+- spin_unlock(&mm->mmu_notifier_mm->lock);
+-
+- if (mn->ops->release)
+- mn->ops->release(mn, mm);
+-
+ /*
+- * Allow __mmu_notifier_release() to complete.
++ * exit_mmap will block in mmu_notifier_release to guarantee
++ * that ->release is called before freeing the pages.
+ */
++ if (mn->ops->release)
++ mn->ops->release(mn, mm);
+ srcu_read_unlock(&srcu, id);
+- } else
++
++ spin_lock(&mm->mmu_notifier_mm->lock);
++ /*
++ * Can not use list_del_rcu() since __mmu_notifier_release
++ * can delete it before we hold the lock.
++ */
++ hlist_del_init_rcu(&mn->hlist);
+ spin_unlock(&mm->mmu_notifier_mm->lock);
++ }
+
+ /*
+- * Wait for any running method to finish, including ->release() if it
+- * was run by __mmu_notifier_release() instead of us.
++ * Wait for any running method to finish, of course including
++ * ->release if it was run by mmu_notifier_relase instead of us.
+ */
+ synchronize_srcu(&srcu);
+
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 94722a4..07d9926 100644
--- a/mm/mprotect.c
@@ -82811,6 +83449,19 @@ index 8fcced7..ebcd481 100644
if (order && (gfp_flags & __GFP_COMP))
prep_compound_page(page, order);
+diff --git a/mm/page_io.c b/mm/page_io.c
+index 6182870..4bba6a2 100644
+--- a/mm/page_io.c
++++ b/mm/page_io.c
+@@ -205,7 +205,7 @@ int swap_writepage(struct page *page, struct writeback_control *wbc)
+ struct file *swap_file = sis->swap_file;
+ struct address_space *mapping = swap_file->f_mapping;
+ struct iovec iov = {
+- .iov_base = kmap(page),
++ .iov_base = (void __force_user *)kmap(page),
+ .iov_len = PAGE_SIZE,
+ };
+
diff --git a/mm/percpu.c b/mm/percpu.c
index 8c8e08f..73a5cda 100644
--- a/mm/percpu.c
@@ -91446,6 +92097,19 @@ index d65fa7f..cbfe366 100644
err:
if (iov != iovstack)
kfree(iov);
+diff --git a/security/keys/internal.h b/security/keys/internal.h
+index 8bbefc3..299d03f 100644
+--- a/security/keys/internal.h
++++ b/security/keys/internal.h
+@@ -240,7 +240,7 @@ extern long keyctl_instantiate_key_iov(key_serial_t,
+ extern long keyctl_invalidate_key(key_serial_t);
+
+ extern long keyctl_instantiate_key_common(key_serial_t,
+- const struct iovec *,
++ const struct iovec __user *,
+ unsigned, size_t, key_serial_t);
+
+ /*
diff --git a/security/keys/key.c b/security/keys/key.c
index 8fb7c7b..ba3610d 100644
--- a/security/keys/key.c
@@ -92335,10 +92999,10 @@ index 0000000..144dbee
+targets += size_overflow_hash.h
diff --git a/tools/gcc/checker_plugin.c b/tools/gcc/checker_plugin.c
new file mode 100644
-index 0000000..d41b5af
+index 0000000..22f03c0
--- /dev/null
+++ b/tools/gcc/checker_plugin.c
-@@ -0,0 +1,171 @@
+@@ -0,0 +1,172 @@
+/*
+ * Copyright 2011 by the PaX Team <pageexec@freemail.hu>
+ * Licensed under the GPL v2
@@ -92392,6 +93056,7 @@ index 0000000..d41b5af
+
+static struct plugin_info checker_plugin_info = {
+ .version = "201111150100",
++ .help = NULL,
+};
+
+#define ADDR_SPACE_KERNEL 0