diff options
-rw-r--r-- | main/linux-grsec/APKBUILD | 10 | ||||
-rw-r--r-- | main/linux-grsec/grsecurity-2.9.1-3.9.4-201306011536.patch (renamed from main/linux-grsec/grsecurity-2.9.1-3.9.4-201305251009.patch) | 816 |
2 files changed, 771 insertions, 55 deletions
diff --git a/main/linux-grsec/APKBUILD b/main/linux-grsec/APKBUILD index 7bda3c711..fc6b18a8d 100644 --- a/main/linux-grsec/APKBUILD +++ b/main/linux-grsec/APKBUILD @@ -7,7 +7,7 @@ case $pkgver in *.*.*) _kernver=${pkgver%.*};; *.*) _kernver=${pkgver};; esac -pkgrel=0 +pkgrel=1 pkgdesc="Linux kernel with grsecurity" url=http://grsecurity.net depends="mkinitfs linux-firmware" @@ -17,7 +17,7 @@ _config=${config:-kernelconfig.${CARCH}} install= source="http://ftp.kernel.org/pub/linux/kernel/v3.x/linux-$_kernver.tar.xz http://ftp.kernel.org/pub/linux/kernel/v3.x/patch-$pkgver.xz - grsecurity-2.9.1-3.9.4-201305251009.patch + grsecurity-2.9.1-3.9.4-201306011536.patch leds-leds-gpio-reserve-gpio-before-using-it.patch ipsec-xfrm-properly-handle-invalid-states-as-an-error.patch @@ -153,7 +153,7 @@ dev() { md5sums="4348c9b6b2eb3144d601e87c19d5d909 linux-3.9.tar.xz 922c4553299e6692a28761d3032fc012 patch-3.9.4.xz -3cdc3cb458f27c7cb3260a0a72f55658 grsecurity-2.9.1-3.9.4-201305251009.patch +08c33c99cb779ebd296d2b274c2deeda grsecurity-2.9.1-3.9.4-201306011536.patch 83db7136608d8101ae130728539dc376 leds-leds-gpio-reserve-gpio-before-using-it.patch ac9a50bdbe91ba6e5205e83f7e734ff5 ipsec-xfrm-properly-handle-invalid-states-as-an-error.patch a16f11b12381efb3bec79b9bfb329836 0001-net-inform-NETDEV_CHANGE-callbacks-which-flags-were-.patch @@ -166,7 +166,7 @@ fd6fd35309c0e8c1f05cb725df958f22 kernelconfig.x86 fd61ff58d25155997c0d6f73e7ca7a7d kernelconfig.x86_64" sha256sums="60bc3e64ee5dc778de2cd7cd7640abf518a4c9d4f31b8ed624e16fad53f54541 linux-3.9.tar.xz 694ea0d527556c5a214597596f37cdb598d2a0652d6f5e86b8c0de718990ccec patch-3.9.4.xz -e69455746a99a9a146a9472dd50eff1868db7663721ab7bb746a73f7f0ac0cf4 grsecurity-2.9.1-3.9.4-201305251009.patch +3bf95754ba94f3dfa7a91d92726e83c9092feab9e990f70d31bc52974bff27b0 grsecurity-2.9.1-3.9.4-201306011536.patch 13676bc5610a8d03e788ac76734babd1338b023bb39559452ee54652b046e6f4 leds-leds-gpio-reserve-gpio-before-using-it.patch ab0dcb52342990ad05af5ce21acd1e95fb65cc7e76ec98e45c7ece7433bc9f23 ipsec-xfrm-properly-handle-invalid-states-as-an-error.patch 6af3757ac36a6cd3cda7b0a71b08143726383b19261294a569ad7f4042c72df3 0001-net-inform-NETDEV_CHANGE-callbacks-which-flags-were-.patch @@ -179,7 +179,7 @@ b44c6671b344ddae1da94e6c051a0e708af8609c1f2ff40d962301ed5023c83a kernelconfig.x 7a6700a6db89f8c2c7f8cce7d77f4ddb3fcad889d72c709c2833af795ef1bc79 kernelconfig.x86_64" sha512sums="77fa521f42380409f8ab400c26f7b00e225cb075ef40834bb263325cfdcc3e65aef8511ec2fc2b50bbf4f50e226fb5ab07d7a479aaf09162adbbf318325d0790 linux-3.9.tar.xz 2a2eb511a610e8e3ddbc38b8bce0b96e60875009b7981542c98f0de3a601632a205fa9f90c6912094196dbda6536083b3990b28204c243a406f5595c40df0965 patch-3.9.4.xz -729fa4e7914e1042c495711060d3f3337757237089942211ad52c87faa0f4d5cd042c79792c5772cb50fe94825941cdbb66e5b5d5d71ea4df6432382901e2bf7 grsecurity-2.9.1-3.9.4-201305251009.patch +eb326ded756cbe086c7999c5a982b6b695ae8ee3c25523a22acd480d97de0603d86eeef5252fe957ed5ccd4e7736db271a253264108e757b23a9bd3e82b32529 grsecurity-2.9.1-3.9.4-201306011536.patch 10d2cf4fb308d1bc8cb5b9df3f9a6d7b9cef453244673bcbe66bd9b64af410a498e203d4dfa51f53461362ad981736eadc46537616b2c0514f57f4d8864c830d leds-leds-gpio-reserve-gpio-before-using-it.patch 769291e92f2f5ae5375d98b80bf8790b089c87437f1660cf8d5e9d45d7221280b6824bcb1d2564cbe12310a88df48443c56ecc9ce5468858829088221aa80327 ipsec-xfrm-properly-handle-invalid-states-as-an-error.patch 81e78593288e8b0fd2c03ea9fc1450323887707f087e911f172450a122bc9b591ee83394836789730d951aeec13d0b75a64e1c05f04364abf8f80d883ddc4a02 0001-net-inform-NETDEV_CHANGE-callbacks-which-flags-were-.patch diff --git a/main/linux-grsec/grsecurity-2.9.1-3.9.4-201305251009.patch b/main/linux-grsec/grsecurity-2.9.1-3.9.4-201306011536.patch index 6715b495c..9a1a55c81 100644 --- a/main/linux-grsec/grsecurity-2.9.1-3.9.4-201305251009.patch +++ b/main/linux-grsec/grsecurity-2.9.1-3.9.4-201306011536.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 @@ -42488,6 +42751,48 @@ index adbe5a8..d387359 100644 extern void tmem_register_hostops(struct tmem_hostops *m); /* core tmem accessor functions */ +diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c +index ca2be40..93ae910 100644 +--- a/drivers/target/iscsi/iscsi_target_parameters.c ++++ b/drivers/target/iscsi/iscsi_target_parameters.c +@@ -712,9 +712,9 @@ static int iscsi_add_notunderstood_response( + } + INIT_LIST_HEAD(&extra_response->er_list); + +- strncpy(extra_response->key, key, strlen(key) + 1); +- strncpy(extra_response->value, NOTUNDERSTOOD, +- strlen(NOTUNDERSTOOD) + 1); ++ strlcpy(extra_response->key, key, sizeof(extra_response->key)); ++ strlcpy(extra_response->value, NOTUNDERSTOOD, ++ sizeof(extra_response->value)); + + list_add_tail(&extra_response->er_list, + ¶m_list->extra_response_list); +@@ -1583,8 +1583,6 @@ int iscsi_decode_text_input( + + if (phase & PHASE_SECURITY) { + if (iscsi_check_for_auth_key(key) > 0) { +- char *tmpptr = key + strlen(key); +- *tmpptr = '='; + kfree(tmpbuf); + return 1; + } +diff --git a/drivers/target/iscsi/iscsi_target_parameters.h b/drivers/target/iscsi/iscsi_target_parameters.h +index 1e1b750..2c536a0 100644 +--- a/drivers/target/iscsi/iscsi_target_parameters.h ++++ b/drivers/target/iscsi/iscsi_target_parameters.h +@@ -1,8 +1,10 @@ + #ifndef ISCSI_PARAMETERS_H + #define ISCSI_PARAMETERS_H + ++#include <scsi/iscsi_proto.h> ++ + struct iscsi_extra_response { +- char key[64]; ++ char key[KEY_MAXLEN]; + char value[32]; + struct list_head er_list; + } ____cacheline_aligned; diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 2e4d655..fd72e68 100644 --- a/drivers/target/target_core_device.c @@ -43773,7 +44078,7 @@ index c8b9262..7e824e6 100644 ret = uio_get_minor(idev); if (ret) diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c -index b7eb86a..36d28af 100644 +index b7eb86a..c00402f 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -473,7 +473,7 @@ static ssize_t cxacru_sysfs_store_adsl_config(struct device *dev, @@ -43785,6 +44090,16 @@ index b7eb86a..36d28af 100644 return -EINVAL; pos += tmp; +@@ -686,7 +686,8 @@ static int cxacru_cm_get_array(struct cxacru_data *instance, enum cxacru_cm_requ + { + int ret, len; + __le32 *buf; +- int offb, offd; ++ int offb; ++ unsigned int offd; + const int stride = CMD_PACKET_SIZE / (4 * 2) - 1; + int buflen = ((size - 1) / stride + 1 + size * 2) * 4; + diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 35f10bf..6a38a0b 100644 --- a/drivers/usb/atm/usbatm.c @@ -47532,6 +47847,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 +48097,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 +48332,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 +48793,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 +49917,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 +49929,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 +50187,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 +50364,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 +50888,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 +51161,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 +53621,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 +53644,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 +53689,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 +55667,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 +55741,19 @@ index 16e8abb..2dcf914 100644 "a_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 +71619,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 +73393,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 +73636,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 +73773,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 +74632,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 +74691,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 +74752,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 @@ -77877,7 +78422,7 @@ index 01d5ccb..cdcbee6 100644 return idx; } diff --git a/kernel/sys.c b/kernel/sys.c -index 0da73cf..a22106a 100644 +index 0da73cf..5c2af3c 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -158,6 +158,12 @@ static int set_one_prio(struct task_struct *p, int niceval, int error) @@ -78034,7 +78579,7 @@ index 0da73cf..a22106a 100644 + user in between this limit change and an execve by this task, force + a recheck only for this task by setting PF_NPROC_EXCEEDED + */ -+ if (resource == RLIMIT_NPROC) ++ if (resource == RLIMIT_NPROC && tsk->real_cred->user != INIT_USER) + tsk->flags |= PF_NPROC_EXCEEDED; } if (!retval) { @@ -79822,6 +80367,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 @@ -81004,7 +81567,7 @@ index 3bbaf5d..299b0e9 100644 err = -EPERM; goto out; diff --git a/mm/mlock.c b/mm/mlock.c -index 79b7cf7..c60424f 100644 +index 79b7cf7..9944291 100644 --- a/mm/mlock.c +++ b/mm/mlock.c @@ -13,6 +13,7 @@ @@ -81054,7 +81617,7 @@ index 79b7cf7..c60424f 100644 if ((locked <= lock_limit) || capable(CAP_IPC_LOCK)) error = do_mlock(start, len, 1); up_write(¤t->mm->mmap_sem); -@@ -500,6 +510,12 @@ static int do_mlockall(int flags) +@@ -500,6 +510,11 @@ static int do_mlockall(int flags) for (vma = current->mm->mmap; vma ; vma = prev->vm_next) { vm_flags_t newflags; @@ -81063,11 +81626,10 @@ index 79b7cf7..c60424f 100644 + break; +#endif + -+ BUG_ON(vma->vm_end > TASK_SIZE); newflags = vma->vm_flags & ~VM_LOCKED; if (flags & MCL_CURRENT) newflags |= VM_LOCKED; -@@ -532,6 +548,7 @@ SYSCALL_DEFINE1(mlockall, int, flags) +@@ -532,6 +547,7 @@ SYSCALL_DEFINE1(mlockall, int, flags) lock_limit >>= PAGE_SHIFT; ret = -ENOMEM; @@ -82287,6 +82849,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 +83500,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 +92148,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 +93050,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 +93107,7 @@ index 0000000..d41b5af + +static struct plugin_info checker_plugin_info = { + .version = "201111150100", ++ .help = NULL, +}; + +#define ADDR_SPACE_KERNEL 0 |