diff options
-rw-r--r-- | 2.6.32/0000_README | 2 | ||||
-rw-r--r-- | 2.6.32/4420_grsecurity-2.2.2-2.6.32.55-201201272054.patch (renamed from 2.6.32/4420_grsecurity-2.2.2-2.6.32.55-201201252116.patch) | 718 | ||||
-rw-r--r-- | 3.2.2/0000_README | 2 | ||||
-rw-r--r-- | 3.2.2/4420_grsecurity-2.2.2-3.2.2-201201272014.patch (renamed from 3.2.2/4420_grsecurity-2.2.2-3.2.2-201201252117.patch) | 550 |
4 files changed, 1150 insertions, 122 deletions
diff --git a/2.6.32/0000_README b/2.6.32/0000_README index 22a45d2..c4e9b3d 100644 --- a/2.6.32/0000_README +++ b/2.6.32/0000_README @@ -14,7 +14,7 @@ Patch: 1054_linux-2.6.32.55.patch From: http://www.kernel.org Desc: Linux 2.6.32.55 -Patch: 4420_grsecurity-2.2.2-2.6.32.55-201201252116.patch +Patch: 4420_grsecurity-2.2.2-2.6.32.55-201201272054.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/2.6.32/4420_grsecurity-2.2.2-2.6.32.55-201201252116.patch b/2.6.32/4420_grsecurity-2.2.2-2.6.32.55-201201272054.patch index 62dfa48..4b8b2b0 100644 --- a/2.6.32/4420_grsecurity-2.2.2-2.6.32.55-201201252116.patch +++ b/2.6.32/4420_grsecurity-2.2.2-2.6.32.55-201201272054.patch @@ -27473,6 +27473,109 @@ index b651a55..023297d 100644 /* Copy key, add padding */ for (i = 0; i < keylen; ++i) +diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c +index 9ed9f60..88f160b 100644 +--- a/crypto/sha512_generic.c ++++ b/crypto/sha512_generic.c +@@ -21,8 +21,6 @@ + #include <linux/percpu.h> + #include <asm/byteorder.h> + +-static DEFINE_PER_CPU(u64[80], msg_schedule); +- + static inline u64 Ch(u64 x, u64 y, u64 z) + { + return z ^ (x & (y ^ z)); +@@ -80,7 +78,7 @@ static inline void LOAD_OP(int I, u64 *W, const u8 *input) + + static inline void BLEND_OP(int I, u64 *W) + { +- W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16]; ++ W[I % 16] += s1(W[(I-2) % 16]) + W[(I-7) % 16] + s0(W[(I-15) % 16]); + } + + static void +@@ -89,38 +87,48 @@ sha512_transform(u64 *state, const u8 *input) + u64 a, b, c, d, e, f, g, h, t1, t2; + + int i; +- u64 *W = get_cpu_var(msg_schedule); ++ u64 W[16]; + + /* load the input */ + for (i = 0; i < 16; i++) + LOAD_OP(i, W, input); + +- for (i = 16; i < 80; i++) { +- BLEND_OP(i, W); +- } +- + /* load the state into our registers */ + a=state[0]; b=state[1]; c=state[2]; d=state[3]; + e=state[4]; f=state[5]; g=state[6]; h=state[7]; + +- /* now iterate */ +- for (i=0; i<80; i+=8) { +- t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i ] + W[i ]; +- t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; +- t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[i+1]; +- t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; +- t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[i+2]; +- t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; +- t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[i+3]; +- t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; +- t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[i+4]; +- t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; +- t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[i+5]; +- t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; +- t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[i+6]; +- t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; +- t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[i+7]; +- t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; ++#define SHA512_0_15(i, a, b, c, d, e, f, g, h) \ ++ t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[i]; \ ++ t2 = e0(a) + Maj(a, b, c); \ ++ d += t1; \ ++ h = t1 + t2 ++ ++#define SHA512_16_79(i, a, b, c, d, e, f, g, h) \ ++ BLEND_OP(i, W); \ ++ t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[(i)%16]; \ ++ t2 = e0(a) + Maj(a, b, c); \ ++ d += t1; \ ++ h = t1 + t2 ++ ++ for (i = 0; i < 16; i += 8) { ++ SHA512_0_15(i, a, b, c, d, e, f, g, h); ++ SHA512_0_15(i + 1, h, a, b, c, d, e, f, g); ++ SHA512_0_15(i + 2, g, h, a, b, c, d, e, f); ++ SHA512_0_15(i + 3, f, g, h, a, b, c, d, e); ++ SHA512_0_15(i + 4, e, f, g, h, a, b, c, d); ++ SHA512_0_15(i + 5, d, e, f, g, h, a, b, c); ++ SHA512_0_15(i + 6, c, d, e, f, g, h, a, b); ++ SHA512_0_15(i + 7, b, c, d, e, f, g, h, a); ++ } ++ for (i = 16; i < 80; i += 8) { ++ SHA512_16_79(i, a, b, c, d, e, f, g, h); ++ SHA512_16_79(i + 1, h, a, b, c, d, e, f, g); ++ SHA512_16_79(i + 2, g, h, a, b, c, d, e, f); ++ SHA512_16_79(i + 3, f, g, h, a, b, c, d, e); ++ SHA512_16_79(i + 4, e, f, g, h, a, b, c, d); ++ SHA512_16_79(i + 5, d, e, f, g, h, a, b, c); ++ SHA512_16_79(i + 6, c, d, e, f, g, h, a, b); ++ SHA512_16_79(i + 7, b, c, d, e, f, g, h, a); + } + + state[0] += a; state[1] += b; state[2] += c; state[3] += d; +@@ -128,8 +136,6 @@ sha512_transform(u64 *state, const u8 *input) + + /* erase our data */ + a = b = c = d = e = f = g = h = t1 = t2 = 0; +- memset(W, 0, sizeof(__get_cpu_var(msg_schedule))); +- put_cpu_var(msg_schedule); + } + + static int diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 0d2cdb8..d8de48d 100644 --- a/drivers/acpi/acpi_pad.c @@ -47969,7 +48072,7 @@ index a5bf577..6d19845 100644 return hit; } diff --git a/fs/compat.c b/fs/compat.c -index d1e2411..27064e4 100644 +index d1e2411..b1eda5d 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -133,8 +133,8 @@ asmlinkage long compat_sys_utimes(char __user *filename, struct compat_timeval _ @@ -48126,7 +48229,18 @@ index d1e2411..27064e4 100644 retval = unshare_files(&displaced); if (retval) -@@ -1499,6 +1541,15 @@ int compat_do_execve(char * filename, +@@ -1493,12 +1535,26 @@ int compat_do_execve(char * filename, + if (IS_ERR(file)) + goto out_unmark; + ++ if (gr_ptrace_readexec(file, bprm->unsafe)) { ++ retval = -EPERM; ++ goto out_file; ++ } ++ + sched_exec(); + + bprm->file = file; bprm->filename = filename; bprm->interp = filename; @@ -48142,7 +48256,7 @@ index d1e2411..27064e4 100644 retval = bprm_mm_init(bprm); if (retval) goto out_file; -@@ -1528,9 +1579,40 @@ int compat_do_execve(char * filename, +@@ -1528,9 +1584,40 @@ int compat_do_execve(char * filename, if (retval < 0) goto out; @@ -48169,7 +48283,7 @@ index d1e2411..27064e4 100644 +#endif + + retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt, -+ bprm->unsafe & LSM_UNSAFE_SHARE); ++ bprm->unsafe); + if (retval < 0) + goto out_fail; + @@ -48184,7 +48298,7 @@ index d1e2411..27064e4 100644 /* execve succeeded */ current->fs->in_exec = 0; -@@ -1541,6 +1623,14 @@ int compat_do_execve(char * filename, +@@ -1541,6 +1628,14 @@ int compat_do_execve(char * filename, put_files_struct(displaced); return retval; @@ -48199,7 +48313,7 @@ index d1e2411..27064e4 100644 out: if (bprm->mm) { acct_arg_size(bprm, 0); -@@ -1711,6 +1801,8 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp, +@@ -1711,6 +1806,8 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp, struct fdtable *fdt; long stack_fds[SELECT_STACK_ALLOC/sizeof(long)]; @@ -48208,7 +48322,7 @@ index d1e2411..27064e4 100644 if (n < 0) goto out_nofds; -@@ -2151,7 +2243,7 @@ asmlinkage long compat_sys_nfsservctl(int cmd, +@@ -2151,7 +2248,7 @@ asmlinkage long compat_sys_nfsservctl(int cmd, oldfs = get_fs(); set_fs(KERNEL_DS); /* The __user pointer casts are valid because of the set_fs() */ @@ -48328,6 +48442,78 @@ index c010ecf..a8d8c59 100644 .show = dlm_attr_show, .store = dlm_attr_store, }; +diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c +index 443947f..a871402 100644 +--- a/fs/ecryptfs/crypto.c ++++ b/fs/ecryptfs/crypto.c +@@ -418,17 +418,6 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page, + rc); + goto out; + } +- if (unlikely(ecryptfs_verbosity > 0)) { +- ecryptfs_printk(KERN_DEBUG, "Encrypting extent " +- "with iv:\n"); +- ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes); +- ecryptfs_printk(KERN_DEBUG, "First 8 bytes before " +- "encryption:\n"); +- ecryptfs_dump_hex((char *) +- (page_address(page) +- + (extent_offset * crypt_stat->extent_size)), +- 8); +- } + rc = ecryptfs_encrypt_page_offset(crypt_stat, enc_extent_page, 0, + page, (extent_offset + * crypt_stat->extent_size), +@@ -441,14 +430,6 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page, + goto out; + } + rc = 0; +- if (unlikely(ecryptfs_verbosity > 0)) { +- ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16x]; " +- "rc = [%d]\n", (extent_base + extent_offset), +- rc); +- ecryptfs_printk(KERN_DEBUG, "First 8 bytes after " +- "encryption:\n"); +- ecryptfs_dump_hex((char *)(page_address(enc_extent_page)), 8); +- } + out: + return rc; + } +@@ -545,17 +526,6 @@ static int ecryptfs_decrypt_extent(struct page *page, + rc); + goto out; + } +- if (unlikely(ecryptfs_verbosity > 0)) { +- ecryptfs_printk(KERN_DEBUG, "Decrypting extent " +- "with iv:\n"); +- ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes); +- ecryptfs_printk(KERN_DEBUG, "First 8 bytes before " +- "decryption:\n"); +- ecryptfs_dump_hex((char *) +- (page_address(enc_extent_page) +- + (extent_offset * crypt_stat->extent_size)), +- 8); +- } + rc = ecryptfs_decrypt_page_offset(crypt_stat, page, + (extent_offset + * crypt_stat->extent_size), +@@ -569,6 +539,7 @@ static int ecryptfs_decrypt_extent(struct page *page, + goto out; + } + rc = 0; ++<<<<<<< HEAD + if (unlikely(ecryptfs_verbosity > 0)) { + ecryptfs_printk(KERN_DEBUG, "Decrypt extent [0x%.16x]; " + "rc = [%d]\n", (extent_base + extent_offset), +@@ -579,6 +550,8 @@ static int ecryptfs_decrypt_extent(struct page *page, + + (extent_offset + * crypt_stat->extent_size)), 8); + } ++======= ++>>>>>>> 58ded24... eCryptfs: Fix oops when printing debug info in extent crypto functions + out: + return rc; + } diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 88ba4d4..073f003 100644 --- a/fs/ecryptfs/inode.c @@ -48350,8 +48536,136 @@ index 88ba4d4..073f003 100644 set_fs(old_fs); if (rc < 0) goto out_free; +diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c +index 4ec8f61..c4b0bc5 100644 +--- a/fs/ecryptfs/miscdev.c ++++ b/fs/ecryptfs/miscdev.c +@@ -408,11 +408,47 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, + ssize_t sz = 0; + char *data; + uid_t euid = current_euid(); ++ unsigned char packet_size_peek[3]; + int rc; + +- if (count == 0) ++ if (count == 0) { + goto out; ++ } else if (count == (1 + 4)) { ++ /* Likely a harmless MSG_HELO or MSG_QUIT - no packet length */ ++ goto memdup; ++ } else if (count < (1 + 4 + 1) ++ || count > (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4 ++ + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES)) { ++ printk(KERN_WARNING "%s: Acceptable packet size range is " ++ "[%d-%lu], but amount of data written is [%zu].", ++ __func__, (1 + 4 + 1), ++ (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4 ++ + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES), count); ++ return -EINVAL; ++ } + ++ if (copy_from_user(packet_size_peek, (buf + 1 + 4), ++ sizeof(packet_size_peek))) { ++ printk(KERN_WARNING "%s: Error while inspecting packet size\n", ++ __func__); ++ return -EFAULT; ++ } ++ ++ rc = ecryptfs_parse_packet_length(packet_size_peek, &packet_size, ++ &packet_size_length); ++ if (rc) { ++ printk(KERN_WARNING "%s: Error parsing packet length; " ++ "rc = [%d]\n", __func__, rc); ++ return rc; ++ } ++ ++ if ((1 + 4 + packet_size_length + packet_size) != count) { ++ printk(KERN_WARNING "%s: Invalid packet size [%zu]\n", __func__, ++ packet_size); ++ return -EINVAL; ++ } ++ ++memdup: + data = memdup_user(buf, count); + if (IS_ERR(data)) { + printk(KERN_ERR "%s: memdup_user returned error [%ld]\n", +@@ -434,23 +470,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, + } + memcpy(&counter_nbo, &data[i], 4); + seq = be32_to_cpu(counter_nbo); +- i += 4; +- rc = ecryptfs_parse_packet_length(&data[i], &packet_size, +- &packet_size_length); +- if (rc) { +- printk(KERN_WARNING "%s: Error parsing packet length; " +- "rc = [%d]\n", __func__, rc); +- goto out_free; +- } +- i += packet_size_length; +- if ((1 + 4 + packet_size_length + packet_size) != count) { +- printk(KERN_WARNING "%s: (1 + packet_size_length([%zd])" +- " + packet_size([%zd]))([%zd]) != " +- "count([%zd]). Invalid packet format.\n", +- __func__, packet_size_length, packet_size, +- (1 + packet_size_length + packet_size), count); +- goto out_free; +- } ++ i += 4 + packet_size_length; + rc = ecryptfs_miscdev_response(&data[i], packet_size, + euid, current_user_ns(), + task_pid(current), seq); +diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c +index 0cc4faf..0404659 100644 +--- a/fs/ecryptfs/read_write.c ++++ b/fs/ecryptfs/read_write.c +@@ -134,13 +134,18 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, + pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT); + size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK); + size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page); +- size_t total_remaining_bytes = ((offset + size) - pos); ++ loff_t total_remaining_bytes = ((offset + size) - pos); ++ ++ if (fatal_signal_pending(current)) { ++ rc = -EINTR; ++ break; ++ } + + if (num_bytes > total_remaining_bytes) + num_bytes = total_remaining_bytes; + if (pos < offset) { + /* remaining zeros to write, up to destination offset */ +- size_t total_remaining_zeros = (offset - pos); ++ loff_t total_remaining_zeros = (offset - pos); + + if (num_bytes > total_remaining_zeros) + num_bytes = total_remaining_zeros; +@@ -197,15 +202,19 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, + } + pos += num_bytes; + } +- if ((offset + size) > ecryptfs_file_size) { +- i_size_write(ecryptfs_inode, (offset + size)); ++ if (pos > ecryptfs_file_size) { ++ i_size_write(ecryptfs_inode, pos); + if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) { +- rc = ecryptfs_write_inode_size_to_metadata( ++ int rc2; ++ ++ rc2 = ecryptfs_write_inode_size_to_metadata( + ecryptfs_inode); +- if (rc) { ++ if (rc2) { + printk(KERN_ERR "Problem with " + "ecryptfs_write_inode_size_to_metadata; " +- "rc = [%d]\n", rc); ++ "rc = [%d]\n", rc2); ++ if (!rc) ++ rc = rc2; + goto out; + } + } diff --git a/fs/exec.c b/fs/exec.c -index 86fafc6..6d33cbb 100644 +index 86fafc6..5033350 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -56,12 +56,28 @@ @@ -48572,7 +48886,18 @@ index 86fafc6..6d33cbb 100644 retval = unshare_files(&displaced); if (retval) -@@ -1383,6 +1440,16 @@ int do_execve(char * filename, +@@ -1377,12 +1434,27 @@ int do_execve(char * filename, + if (IS_ERR(file)) + goto out_unmark; + ++ if (gr_ptrace_readexec(file, bprm->unsafe)) { ++ retval = -EPERM; ++ goto out_file; ++ } ++ + sched_exec(); + + bprm->file = file; bprm->filename = filename; bprm->interp = filename; @@ -48589,7 +48914,7 @@ index 86fafc6..6d33cbb 100644 retval = bprm_mm_init(bprm); if (retval) goto out_file; -@@ -1412,10 +1479,41 @@ int do_execve(char * filename, +@@ -1412,10 +1484,41 @@ int do_execve(char * filename, if (retval < 0) goto out; @@ -48616,7 +48941,7 @@ index 86fafc6..6d33cbb 100644 +#endif + + retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt, -+ bprm->unsafe & LSM_UNSAFE_SHARE); ++ bprm->unsafe); + if (retval < 0) + goto out_fail; + @@ -48632,7 +48957,7 @@ index 86fafc6..6d33cbb 100644 /* execve succeeded */ current->fs->in_exec = 0; -@@ -1426,6 +1524,14 @@ int do_execve(char * filename, +@@ -1426,6 +1529,14 @@ int do_execve(char * filename, put_files_struct(displaced); return retval; @@ -48647,7 +48972,7 @@ index 86fafc6..6d33cbb 100644 out: if (bprm->mm) { acct_arg_size(bprm, 0); -@@ -1591,6 +1697,220 @@ out: +@@ -1591,6 +1702,220 @@ out: return ispipe; } @@ -48868,7 +49193,7 @@ index 86fafc6..6d33cbb 100644 static int zap_process(struct task_struct *start) { struct task_struct *t; -@@ -1793,17 +2113,17 @@ static void wait_for_dump_helpers(struct file *file) +@@ -1793,17 +2118,17 @@ static void wait_for_dump_helpers(struct file *file) pipe = file->f_path.dentry->d_inode->i_pipe; pipe_lock(pipe); @@ -48891,7 +49216,7 @@ index 86fafc6..6d33cbb 100644 pipe_unlock(pipe); } -@@ -1826,10 +2146,13 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) +@@ -1826,10 +2151,13 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) char **helper_argv = NULL; int helper_argc = 0; int dump_count = 0; @@ -48906,7 +49231,7 @@ index 86fafc6..6d33cbb 100644 binfmt = mm->binfmt; if (!binfmt || !binfmt->core_dump) goto fail; -@@ -1874,6 +2197,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) +@@ -1874,6 +2202,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) */ clear_thread_flag(TIF_SIGPENDING); @@ -48915,7 +49240,7 @@ index 86fafc6..6d33cbb 100644 /* * lock_kernel() because format_corename() is controlled by sysctl, which * uses lock_kernel() -@@ -1908,7 +2233,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) +@@ -1908,7 +2238,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) goto fail_unlock; } @@ -48924,7 +49249,7 @@ index 86fafc6..6d33cbb 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); -@@ -1972,7 +2297,7 @@ close_fail: +@@ -1972,7 +2302,7 @@ close_fail: filp_close(file, NULL); fail_dropcount: if (dump_count) @@ -54671,10 +54996,10 @@ index e89734e..5e84d8d 100644 *offset = off & 0x7fffffff; return 0; diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c -index 8f32f50..859e8a3 100644 +index 8f32f50..b6a41e8 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c -@@ -564,13 +564,17 @@ xfs_readlink( +@@ -564,13 +564,18 @@ xfs_readlink( xfs_ilock(ip, XFS_ILOCK_SHARED); @@ -54689,7 +55014,8 @@ index 8f32f50..859e8a3 100644 + xfs_fs_cmn_err(CE_ALERT, mp, "%s: inode (%llu) symlink length (%d) too long", + __func__, (unsigned long long)ip->i_ino, pathlen); + ASSERT(0); -+ return XFS_ERROR(EFSCORRUPTED); ++ error = XFS_ERROR(EFSCORRUPTED); ++ goto out; + } + if (ip->i_df.if_flags & XFS_IFINLINE) { @@ -54697,10 +55023,10 @@ index 8f32f50..859e8a3 100644 link[pathlen] = '\0'; diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig new file mode 100644 -index 0000000..f27a8e8 +index 0000000..883b00b --- /dev/null +++ b/grsecurity/Kconfig -@@ -0,0 +1,1036 @@ +@@ -0,0 +1,1064 @@ +# +# grecurity configuration +# @@ -54835,9 +55161,11 @@ index 0000000..f27a8e8 + select GRKERNSEC_PROC_ADD + select GRKERNSEC_CHROOT_CHMOD + select GRKERNSEC_CHROOT_NICE ++ select GRKERNSEC_SETXID + select GRKERNSEC_AUDIT_MOUNT + select GRKERNSEC_MODHARDEN if (MODULES) + select GRKERNSEC_HARDEN_PTRACE ++ select GRKERNSEC_PTRACE_READEXEC + select GRKERNSEC_VM86 if (X86_32) + select GRKERNSEC_KERN_LOCKOUT if (X86 || ARM || PPC || SPARC) + select PAX @@ -55499,6 +55827,32 @@ index 0000000..f27a8e8 + option is enabled, a sysctl option with name "harden_ptrace" is + created. + ++config GRKERNSEC_PTRACE_READEXEC ++ bool "Require read access to ptrace sensitive binaries" ++ help ++ If you say Y here, unprivileged users will not be able to ptrace unreadable ++ binaries. This option is useful in environments that ++ remove the read bits (e.g. file mode 4711) from suid binaries to ++ prevent infoleaking of their contents. This option adds ++ consistency to the use of that file mode, as the binary could normally ++ be read out when run without privileges while ptracing. ++ ++ If the sysctl option is enabled, a sysctl option with name "ptrace_readexec" ++ is created. ++ ++config GRKERNSEC_SETXID ++ bool "Enforce consistent multithreaded privileges" ++ help ++ If you say Y here, a change from a root uid to a non-root uid ++ in a multithreaded application will cause the resulting uids, ++ gids, supplementary groups, and capabilities in that thread ++ to be propagated to the other threads of the process. In most ++ cases this is unnecessary, as glibc will emulate this behavior ++ on behalf of the application. Other libcs do not act in the ++ same way, allowing the other threads of the process to continue ++ running with root privileges. If the sysctl option is enabled, ++ a sysctl option with name "consistent_setxid" is created. ++ +config GRKERNSEC_TPE + bool "Trusted Path Execution (TPE)" + help @@ -55781,10 +56135,10 @@ index 0000000..be9ae3a +endif diff --git a/grsecurity/gracl.c b/grsecurity/gracl.c new file mode 100644 -index 0000000..6bd68d6 +index 0000000..71cb167 --- /dev/null +++ b/grsecurity/gracl.c -@@ -0,0 +1,4141 @@ +@@ -0,0 +1,4140 @@ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/sched.h> @@ -55804,7 +56158,7 @@ index 0000000..6bd68d6 +#include <linux/ptrace.h> +#include <linux/gracl.h> +#include <linux/gralloc.h> -+#include <linux/grsecurity.h> ++#include <linux/security.h> +#include <linux/grinternal.h> +#include <linux/pid_namespace.h> +#include <linux/fdtable.h> @@ -58298,7 +58652,7 @@ index 0000000..6bd68d6 + +int +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt, -+ const int unsafe_share) ++ const int unsafe_flags) +{ + struct task_struct *task = current; + struct acl_subject_label *newacl; @@ -58311,13 +58665,12 @@ index 0000000..6bd68d6 + newacl = chk_subj_label(dentry, mnt, task->role); + + task_lock(task); -+ if ((((task->ptrace & PT_PTRACED) || unsafe_share) && -+ !(task->acl->mode & GR_POVERRIDE) && (task->acl != newacl) && ++ if (unsafe_flags && !(task->acl->mode & GR_POVERRIDE) && (task->acl != newacl) && + !(task->role->roletype & GR_ROLE_GOD) && + !gr_search_file(dentry, GR_PTRACERD, mnt) && -+ !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN)))) { ++ !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) { + task_unlock(task); -+ if (unsafe_share) ++ if (unsafe_flags & LSM_UNSAFE_SHARE) + gr_log_fs_generic(GR_DONT_AUDIT, GR_UNSAFESHARE_EXEC_ACL_MSG, dentry, mnt); + else + gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt); @@ -62727,10 +63080,10 @@ index 0000000..8ca18bf +} diff --git a/grsecurity/grsec_init.c b/grsecurity/grsec_init.c new file mode 100644 -index 0000000..f813c26 +index 0000000..1e995d3 --- /dev/null +++ b/grsecurity/grsec_init.c -@@ -0,0 +1,270 @@ +@@ -0,0 +1,278 @@ +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> @@ -62741,6 +63094,8 @@ index 0000000..f813c26 +#include <linux/percpu.h> +#include <linux/module.h> + ++int grsec_enable_ptrace_readexec; ++int grsec_enable_setxid; +int grsec_enable_brute; +int grsec_enable_link; +int grsec_enable_dmesg; @@ -62921,6 +63276,12 @@ index 0000000..f813c26 +#ifdef CONFIG_GRKERNSEC_EXECLOG + grsec_enable_execlog = 1; +#endif ++#ifdef CONFIG_GRKERNSEC_SETXID ++ grsec_enable_setxid = 1; ++#endif ++#ifdef CONFIG_GRKERNSEC_PTRACE_READEXEC ++ grsec_enable_ptrace_readexec = 1; ++#endif +#ifdef CONFIG_GRKERNSEC_SIGNAL + grsec_enable_signal = 1; +#endif @@ -63529,14 +63890,14 @@ index 0000000..a3b12a0 +} diff --git a/grsecurity/grsec_ptrace.c b/grsecurity/grsec_ptrace.c new file mode 100644 -index 0000000..472c1d6 +index 0000000..78f8733 --- /dev/null +++ b/grsecurity/grsec_ptrace.c -@@ -0,0 +1,14 @@ +@@ -0,0 +1,30 @@ +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/grinternal.h> -+#include <linux/grsecurity.h> ++#include <linux/security.h> + +void +gr_audit_ptrace(struct task_struct *task) @@ -63547,6 +63908,22 @@ index 0000000..472c1d6 +#endif + return; +} ++ ++int ++gr_ptrace_readexec(struct file *file, int unsafe_flags) ++{ ++#ifdef CONFIG_GRKERNSEC_PTRACE_READEXEC ++ const struct dentry *dentry = file->f_path.dentry; ++ const struct vfsmount *mnt = file->f_path.mnt; ++ ++ if (grsec_enable_ptrace_readexec && (unsafe_flags & LSM_UNSAFE_PTRACE) && ++ (inode_permission(dentry->d_inode, MAY_READ) || !gr_acl_handle_open(dentry, mnt, MAY_READ))) { ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_READEXEC_MSG, dentry, mnt); ++ return -EACCES; ++ } ++#endif ++ return 0; ++} diff --git a/grsecurity/grsec_sig.c b/grsecurity/grsec_sig.c new file mode 100644 index 0000000..c648492 @@ -64042,10 +64419,10 @@ index 0000000..7512ea9 +} diff --git a/grsecurity/grsec_sysctl.c b/grsecurity/grsec_sysctl.c new file mode 100644 -index 0000000..2753505 +index 0000000..31f3258 --- /dev/null +++ b/grsecurity/grsec_sysctl.c -@@ -0,0 +1,479 @@ +@@ -0,0 +1,499 @@ +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/sysctl.h> @@ -64113,6 +64490,26 @@ index 0000000..2753505 + .proc_handler = &proc_dointvec, + }, +#endif ++#ifdef CONFIG_GRKERNSEC_PTRACE_READEXEC ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "ptrace_readexec", ++ .data = &grsec_enable_ptrace_readexec, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif ++#ifdef CONFIG_GRKERNSEC_SETXID ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "consistent_setxid", ++ .data = &grsec_enable_setxid, ++ .maxlen = sizeof(int), ++ .mode = 0600, ++ .proc_handler = &proc_dointvec, ++ }, ++#endif +#ifdef CONFIG_GRKERNSEC_BLACKHOLE + { + .ctl_name = CTL_UNNUMBERED, @@ -66732,10 +67129,10 @@ index 0000000..70d6cd5 +#endif diff --git a/include/linux/grinternal.h b/include/linux/grinternal.h new file mode 100644 -index 0000000..e5817d7 +index 0000000..3826b91 --- /dev/null +++ b/include/linux/grinternal.h -@@ -0,0 +1,218 @@ +@@ -0,0 +1,219 @@ +#ifndef __GRINTERNAL_H +#define __GRINTERNAL_H + @@ -66772,6 +67169,7 @@ index 0000000..e5817d7 +char *gr_to_filename3(const struct dentry *dentry, + const struct vfsmount *mnt); + ++extern int grsec_enable_ptrace_readexec; +extern int grsec_enable_harden_ptrace; +extern int grsec_enable_link; +extern int grsec_enable_fifo; @@ -66956,10 +67354,10 @@ index 0000000..e5817d7 +#endif diff --git a/include/linux/grmsg.h b/include/linux/grmsg.h new file mode 100644 -index 0000000..9d5fd4a +index 0000000..dfb15ef --- /dev/null +++ b/include/linux/grmsg.h -@@ -0,0 +1,108 @@ +@@ -0,0 +1,109 @@ +#define DEFAULTSECMSG "%.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u, parent %.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u" +#define GR_ACL_PROCACCT_MSG "%.256s[%.16s:%d] IP:%pI4 TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u run time:[%ud %uh %um %us] cpu time:[%ud %uh %um %us] %s with exit code %ld, parent %.256s[%.16s:%d] IP:%pI4 TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u" +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by " @@ -67067,13 +67465,14 @@ index 0000000..9d5fd4a +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by " +#define GR_VM86_MSG "denied use of vm86 by " +#define GR_PTRACE_AUDIT_MSG "process %.950s(%.16s:%d) attached to via ptrace by " ++#define GR_PTRACE_READEXEC_MSG "denied ptrace of unreadable binary %.950s by " +#define GR_INIT_TRANSFER_MSG "persistent special role transferred privilege to init by " diff --git a/include/linux/grsecurity.h b/include/linux/grsecurity.h new file mode 100644 -index 0000000..24676f4 +index 0000000..ebba836 --- /dev/null +++ b/include/linux/grsecurity.h -@@ -0,0 +1,218 @@ +@@ -0,0 +1,223 @@ +#ifndef GR_SECURITY_H +#define GR_SECURITY_H +#include <linux/fs.h> @@ -67217,7 +67616,7 @@ index 0000000..24676f4 + const gid_t gid); +int gr_set_proc_label(const struct dentry *dentry, + const struct vfsmount *mnt, -+ const int unsafe_share); ++ const int unsafe_flags); +__u32 gr_acl_handle_hidden_file(const struct dentry *dentry, + const struct vfsmount *mnt); +__u32 gr_acl_handle_open(const struct dentry *dentry, @@ -67279,6 +67678,8 @@ index 0000000..24676f4 +void gr_audit_ptrace(struct task_struct *task); +dev_t gr_get_dev_from_dentry(struct dentry *dentry); + ++int gr_ptrace_readexec(struct file *file, int unsafe_flags); ++ +#ifdef CONFIG_GRKERNSEC +void task_grsec_rbac(struct seq_file *m, struct task_struct *p); +void gr_handle_vm86(void); @@ -67289,6 +67690,9 @@ index 0000000..24676f4 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK +extern int grsec_enable_chroot_findtask; +#endif ++#ifdef CONFIG_GRKERNSEC_SETXID ++extern int grsec_enable_setxid; ++#endif +#endif + +#endif @@ -68429,7 +68833,7 @@ index 3392c59..a746428 100644 #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) /** diff --git a/include/linux/sched.h b/include/linux/sched.h -index 71849bf..40217dc 100644 +index 71849bf..0ad2f74 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -101,6 +101,7 @@ struct bio; @@ -68556,13 +68960,16 @@ index 71849bf..40217dc 100644 struct io_context *io_context; unsigned long ptrace_message; -@@ -1519,6 +1544,21 @@ struct task_struct { +@@ -1519,6 +1544,24 @@ struct task_struct { unsigned long default_timer_slack_ns; struct list_head *scm_work_list; + +#ifdef CONFIG_GRKERNSEC + /* grsecurity */ ++#ifdef CONFIG_GRKERNSEC_SETXID ++ const struct cred *delayed_cred; ++#endif + struct dentry *gr_chroot_dentry; + struct acl_subject_label *acl; + struct acl_role_label *role; @@ -68578,7 +68985,7 @@ index 71849bf..40217dc 100644 #ifdef CONFIG_FUNCTION_GRAPH_TRACER /* Index of current stored adress in ret_stack */ int curr_ret_stack; -@@ -1542,6 +1582,57 @@ struct task_struct { +@@ -1542,6 +1585,57 @@ struct task_struct { #endif /* CONFIG_TRACING */ }; @@ -68636,7 +69043,7 @@ index 71849bf..40217dc 100644 /* Future-safe accessor for struct task_struct's cpus_allowed. */ #define tsk_cpumask(tsk) (&(tsk)->cpus_allowed) -@@ -1740,7 +1831,7 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t * +@@ -1740,7 +1834,7 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t * #define PF_DUMPCORE 0x00000200 /* dumped core */ #define PF_SIGNALED 0x00000400 /* killed by a signal */ #define PF_MEMALLOC 0x00000800 /* Allocating memory */ @@ -68645,7 +69052,7 @@ index 71849bf..40217dc 100644 #define PF_USED_MATH 0x00002000 /* if unset the fpu must be initialized before use */ #define PF_FREEZING 0x00004000 /* freeze in progress. do not account to load */ #define PF_NOFREEZE 0x00008000 /* this thread should not be frozen */ -@@ -1978,7 +2069,9 @@ void yield(void); +@@ -1978,7 +2072,9 @@ void yield(void); extern struct exec_domain default_exec_domain; union thread_union { @@ -68655,7 +69062,7 @@ index 71849bf..40217dc 100644 unsigned long stack[THREAD_SIZE/sizeof(long)]; }; -@@ -2011,6 +2104,7 @@ extern struct pid_namespace init_pid_ns; +@@ -2011,6 +2107,7 @@ extern struct pid_namespace init_pid_ns; */ extern struct task_struct *find_task_by_vpid(pid_t nr); @@ -68663,7 +69070,7 @@ index 71849bf..40217dc 100644 extern struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns); -@@ -2155,7 +2249,7 @@ extern void __cleanup_sighand(struct sighand_struct *); +@@ -2155,7 +2252,7 @@ extern void __cleanup_sighand(struct sighand_struct *); extern void exit_itimers(struct signal_struct *); extern void flush_itimer_signals(void); @@ -68672,7 +69079,7 @@ index 71849bf..40217dc 100644 extern void daemonize(const char *, ...); extern int allow_signal(int); -@@ -2284,13 +2378,17 @@ static inline unsigned long *end_of_stack(struct task_struct *p) +@@ -2284,13 +2381,17 @@ static inline unsigned long *end_of_stack(struct task_struct *p) #endif @@ -71191,7 +71598,7 @@ index 3f2f04f..4e53ded 100644 /* If set, cpu_up and cpu_down will return -EBUSY and do nothing. * Should always be manipulated under cpu_add_remove_lock diff --git a/kernel/cred.c b/kernel/cred.c -index 0b5b5fc..419b86a 100644 +index 0b5b5fc..f7fe51a 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -160,6 +160,8 @@ static void put_cred_rcu(struct rcu_head *rcu) @@ -71212,7 +71619,23 @@ index 0b5b5fc..419b86a 100644 kdebug("exit_creds(%u,%p,%p,{%d,%d})", tsk->pid, tsk->real_cred, tsk->cred, atomic_read(&tsk->cred->usage), read_cred_subscribers(tsk->cred)); -@@ -222,6 +226,8 @@ const struct cred *get_task_cred(struct task_struct *task) +@@ -206,6 +210,15 @@ void exit_creds(struct task_struct *tsk) + validate_creds(cred); + put_cred(cred); + } ++ ++#ifdef CONFIG_GRKERNSEC_SETXID ++ cred = (struct cred *) tsk->delayed_cred; ++ if (cred) { ++ tsk->delayed_cred = NULL; ++ validate_creds(cred); ++ put_cred(cred); ++ } ++#endif + } + + /** +@@ -222,6 +235,8 @@ const struct cred *get_task_cred(struct task_struct *task) { const struct cred *cred; @@ -71221,7 +71644,7 @@ index 0b5b5fc..419b86a 100644 rcu_read_lock(); do { -@@ -241,6 +247,8 @@ struct cred *cred_alloc_blank(void) +@@ -241,6 +256,8 @@ struct cred *cred_alloc_blank(void) { struct cred *new; @@ -71230,7 +71653,7 @@ index 0b5b5fc..419b86a 100644 new = kmem_cache_zalloc(cred_jar, GFP_KERNEL); if (!new) return NULL; -@@ -289,6 +297,8 @@ struct cred *prepare_creds(void) +@@ -289,6 +306,8 @@ struct cred *prepare_creds(void) const struct cred *old; struct cred *new; @@ -71239,7 +71662,7 @@ index 0b5b5fc..419b86a 100644 validate_process_creds(); new = kmem_cache_alloc(cred_jar, GFP_KERNEL); -@@ -335,6 +345,8 @@ struct cred *prepare_exec_creds(void) +@@ -335,6 +354,8 @@ struct cred *prepare_exec_creds(void) struct thread_group_cred *tgcred = NULL; struct cred *new; @@ -71248,7 +71671,7 @@ index 0b5b5fc..419b86a 100644 #ifdef CONFIG_KEYS tgcred = kmalloc(sizeof(*tgcred), GFP_KERNEL); if (!tgcred) -@@ -441,6 +453,8 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) +@@ -441,6 +462,8 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) struct cred *new; int ret; @@ -71257,7 +71680,13 @@ index 0b5b5fc..419b86a 100644 mutex_init(&p->cred_guard_mutex); if ( -@@ -528,6 +542,8 @@ int commit_creds(struct cred *new) +@@ -523,11 +546,13 @@ error_put: + * Always returns 0 thus allowing this function to be tail-called at the end + * of, say, sys_setgid(). + */ +-int commit_creds(struct cred *new) ++static int __commit_creds(struct cred *new) + { struct task_struct *task = current; const struct cred *old = task->real_cred; @@ -71266,7 +71695,7 @@ index 0b5b5fc..419b86a 100644 kdebug("commit_creds(%p{%d,%d})", new, atomic_read(&new->usage), read_cred_subscribers(new)); -@@ -544,6 +560,8 @@ int commit_creds(struct cred *new) +@@ -544,6 +569,8 @@ int commit_creds(struct cred *new) get_cred(new); /* we will require a ref for the subj creds too */ @@ -71275,7 +71704,7 @@ index 0b5b5fc..419b86a 100644 /* dumpability changes */ if (old->euid != new->euid || old->egid != new->egid || -@@ -563,10 +581,8 @@ int commit_creds(struct cred *new) +@@ -563,10 +590,8 @@ int commit_creds(struct cred *new) key_fsgid_changed(task); /* do it @@ -71288,7 +71717,104 @@ index 0b5b5fc..419b86a 100644 */ alter_cred_subscribers(new, 2); if (new->user != old->user) -@@ -606,6 +622,8 @@ EXPORT_SYMBOL(commit_creds); +@@ -595,8 +620,96 @@ int commit_creds(struct cred *new) + put_cred(old); + return 0; + } ++ ++#ifdef CONFIG_GRKERNSEC_SETXID ++extern int set_user(struct cred *new); ++ ++void gr_delayed_cred_worker(void) ++{ ++ const struct cred *new = current->delayed_cred; ++ struct cred *ncred; ++ ++ current->delayed_cred = NULL; ++ ++ if (current_uid() && new != NULL) { ++ // from doing get_cred on it when queueing this ++ put_cred(new); ++ return; ++ } else if (new == NULL) ++ return; ++ ++ ncred = prepare_creds(); ++ if (!ncred) ++ goto die; ++ // uids ++ ncred->uid = new->uid; ++ ncred->euid = new->euid; ++ ncred->suid = new->suid; ++ ncred->fsuid = new->fsuid; ++ // gids ++ ncred->gid = new->gid; ++ ncred->egid = new->egid; ++ ncred->sgid = new->sgid; ++ ncred->fsgid = new->fsgid; ++ // groups ++ if (set_groups(ncred, new->group_info) < 0) { ++ abort_creds(ncred); ++ goto die; ++ } ++ // caps ++ ncred->securebits = new->securebits; ++ ncred->cap_inheritable = new->cap_inheritable; ++ ncred->cap_permitted = new->cap_permitted; ++ ncred->cap_effective = new->cap_effective; ++ ncred->cap_bset = new->cap_bset; ++ ++ if (set_user(ncred)) { ++ abort_creds(ncred); ++ goto die; ++ } ++ ++ // from doing get_cred on it when queueing this ++ put_cred(new); ++ ++ __commit_creds(ncred); ++ return; ++die: ++ // from doing get_cred on it when queueing this ++ put_cred(new); ++ do_group_exit(SIGKILL); ++} ++#endif ++ ++int commit_creds(struct cred *new) ++{ ++#ifdef CONFIG_GRKERNSEC_SETXID ++ struct task_struct *t; ++ ++ /* we won't get called with tasklist_lock held for writing ++ and interrupts disabled as the cred struct in that case is ++ init_cred ++ */ ++ if (grsec_enable_setxid && !current_is_single_threaded() && ++ !current_uid() && new->uid) { ++ rcu_read_lock(); ++ read_lock(&tasklist_lock); ++ for (t = next_thread(current); t != current; ++ t = next_thread(t)) { ++ if (t->delayed_cred == NULL) { ++ t->delayed_cred = get_cred(new); ++ set_tsk_need_resched(t); ++ } ++ } ++ read_unlock(&tasklist_lock); ++ rcu_read_unlock(); ++ } ++#endif ++ return __commit_creds(new); ++} ++ + EXPORT_SYMBOL(commit_creds); + ++ + /** + * abort_creds - Discard a set of credentials and unlock the current task + * @new: The credentials that were going to be applied +@@ -606,6 +719,8 @@ EXPORT_SYMBOL(commit_creds); */ void abort_creds(struct cred *new) { @@ -71297,7 +71823,7 @@ index 0b5b5fc..419b86a 100644 kdebug("abort_creds(%p{%d,%d})", new, atomic_read(&new->usage), read_cred_subscribers(new)); -@@ -629,6 +647,8 @@ const struct cred *override_creds(const struct cred *new) +@@ -629,6 +744,8 @@ const struct cred *override_creds(const struct cred *new) { const struct cred *old = current->cred; @@ -71306,7 +71832,7 @@ index 0b5b5fc..419b86a 100644 kdebug("override_creds(%p{%d,%d})", new, atomic_read(&new->usage), read_cred_subscribers(new)); -@@ -658,6 +678,8 @@ void revert_creds(const struct cred *old) +@@ -658,6 +775,8 @@ void revert_creds(const struct cred *old) { const struct cred *override = current->cred; @@ -71315,7 +71841,7 @@ index 0b5b5fc..419b86a 100644 kdebug("revert_creds(%p{%d,%d})", old, atomic_read(&old->usage), read_cred_subscribers(old)); -@@ -704,6 +726,8 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon) +@@ -704,6 +823,8 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon) const struct cred *old; struct cred *new; @@ -71324,7 +71850,7 @@ index 0b5b5fc..419b86a 100644 new = kmem_cache_alloc(cred_jar, GFP_KERNEL); if (!new) return NULL; -@@ -758,6 +782,8 @@ EXPORT_SYMBOL(prepare_kernel_cred); +@@ -758,6 +879,8 @@ EXPORT_SYMBOL(prepare_kernel_cred); */ int set_security_override(struct cred *new, u32 secid) { @@ -71333,7 +71859,7 @@ index 0b5b5fc..419b86a 100644 return security_kernel_act_as(new, secid); } EXPORT_SYMBOL(set_security_override); -@@ -777,6 +803,8 @@ int set_security_override_from_ctx(struct cred *new, const char *secctx) +@@ -777,6 +900,8 @@ int set_security_override_from_ctx(struct cred *new, const char *secctx) u32 secid; int ret; @@ -74345,7 +74871,7 @@ index 29bd4ba..8c5de90 100644 WARN_ON(pendowner->pi_blocked_on->lock != lock); diff --git a/kernel/sched.c b/kernel/sched.c -index 0591df8..db35e3d 100644 +index 0591df8..e3af3a4 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -5043,7 +5043,7 @@ out: @@ -74357,7 +74883,27 @@ index 0591df8..db35e3d 100644 { int this_cpu = smp_processor_id(); struct rq *this_rq = cpu_rq(this_cpu); -@@ -5700,6 +5700,8 @@ asmlinkage void __sched schedule(void) +@@ -5690,6 +5690,19 @@ pick_next_task(struct rq *rq) + } + } + ++#ifdef CONFIG_GRKERNSEC_SETXID ++extern void gr_delayed_cred_worker(void); ++static inline void gr_cred_schedule(void) ++{ ++ if (unlikely(current->delayed_cred)) ++ gr_delayed_cred_worker(); ++} ++#else ++static inline void gr_cred_schedule(void) ++{ ++} ++#endif ++ + /* + * schedule() is the main scheduler function. + */ +@@ -5700,6 +5713,8 @@ asmlinkage void __sched schedule(void) struct rq *rq; int cpu; @@ -74366,7 +74912,16 @@ index 0591df8..db35e3d 100644 need_resched: preempt_disable(); cpu = smp_processor_id(); -@@ -5770,7 +5772,7 @@ EXPORT_SYMBOL(schedule); +@@ -5713,6 +5728,8 @@ need_resched_nonpreemptible: + + schedule_debug(prev); + ++ gr_cred_schedule(); ++ + if (sched_feat(HRTICK)) + hrtick_clear(rq); + +@@ -5770,7 +5787,7 @@ EXPORT_SYMBOL(schedule); * Look out! "owner" is an entirely speculative pointer * access and not reliable. */ @@ -74375,7 +74930,7 @@ index 0591df8..db35e3d 100644 { unsigned int cpu; struct rq *rq; -@@ -5784,10 +5786,10 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner) +@@ -5784,10 +5801,10 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner) * DEBUG_PAGEALLOC could have unmapped it if * the mutex owner just released it and exited. */ @@ -74388,7 +74943,7 @@ index 0591df8..db35e3d 100644 #endif /* -@@ -5816,7 +5818,7 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner) +@@ -5816,7 +5833,7 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner) /* * Is that owner really running on that cpu? */ @@ -74397,7 +74952,7 @@ index 0591df8..db35e3d 100644 return 0; cpu_relax(); -@@ -6359,6 +6361,8 @@ int can_nice(const struct task_struct *p, const int nice) +@@ -6359,6 +6376,8 @@ int can_nice(const struct task_struct *p, const int nice) /* convert nice value [19,-20] to rlimit style value [1,40] */ int nice_rlim = 20 - nice; @@ -74406,7 +74961,7 @@ index 0591df8..db35e3d 100644 return (nice_rlim <= p->signal->rlim[RLIMIT_NICE].rlim_cur || capable(CAP_SYS_NICE)); } -@@ -6392,7 +6396,8 @@ SYSCALL_DEFINE1(nice, int, increment) +@@ -6392,7 +6411,8 @@ SYSCALL_DEFINE1(nice, int, increment) if (nice > 19) nice = 19; @@ -74416,7 +74971,7 @@ index 0591df8..db35e3d 100644 return -EPERM; retval = security_task_setnice(current, nice); -@@ -8774,7 +8779,7 @@ static void init_sched_groups_power(int cpu, struct sched_domain *sd) +@@ -8774,7 +8794,7 @@ static void init_sched_groups_power(int cpu, struct sched_domain *sd) long power; int weight; @@ -74656,7 +75211,7 @@ index 04a0252..580c512 100644 struct tasklet_struct *list; diff --git a/kernel/sys.c b/kernel/sys.c -index e9512b1..3c265de 100644 +index e9512b1..f07185f 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -133,6 +133,12 @@ static int set_one_prio(struct task_struct *p, int niceval, int error) @@ -74722,6 +75277,15 @@ index e9512b1..3c265de 100644 if (capable(CAP_SETGID)) new->gid = new->egid = new->sgid = new->fsgid = gid; else if (gid == old->gid || gid == old->sgid) +@@ -559,7 +572,7 @@ error: + /* + * change the user struct in a credentials set to match the new UID + */ +-static int set_user(struct cred *new) ++int set_user(struct cred *new) + { + struct user_struct *new_user; + @@ -567,12 +580,19 @@ static int set_user(struct cred *new) if (!new_user) return -EAGAIN; diff --git a/3.2.2/0000_README b/3.2.2/0000_README index 742124c..a38ba28 100644 --- a/3.2.2/0000_README +++ b/3.2.2/0000_README @@ -6,7 +6,7 @@ Patch: 1001_linux-3.2.2.patch From: http://www.kernel.org Desc: Linux 3.2.2 -Patch: 4420_grsecurity-2.2.2-3.2.2-201201252117.patch +Patch: 4420_grsecurity-2.2.2-3.2.2-201201272014.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.2.2/4420_grsecurity-2.2.2-3.2.2-201201252117.patch b/3.2.2/4420_grsecurity-2.2.2-3.2.2-201201272014.patch index 4d4d52e..3f6029d 100644 --- a/3.2.2/4420_grsecurity-2.2.2-3.2.2-201201252117.patch +++ b/3.2.2/4420_grsecurity-2.2.2-3.2.2-201201272014.patch @@ -12223,9 +12223,18 @@ index 2af127d..8ff7ac0 100644 atomic_set(&mce_callin, 0); atomic_set(&global_nwo, 0); diff --git a/arch/x86/kernel/cpu/mcheck/p5.c b/arch/x86/kernel/cpu/mcheck/p5.c -index 5c0e653..1e82c7c 100644 +index 5c0e653..51ddf2c 100644 --- a/arch/x86/kernel/cpu/mcheck/p5.c +++ b/arch/x86/kernel/cpu/mcheck/p5.c +@@ -11,7 +11,7 @@ + #include <asm/processor.h> + #include <asm/system.h> + #include <asm/mce.h> +-#include <asm/msr.h> ++#include <asm/pgtable.h> + + /* By default disabled */ + int mce_p5_enabled __read_mostly; @@ -50,7 +50,9 @@ void intel_p5_mcheck_init(struct cpuinfo_x86 *c) if (!cpu_has(c, X86_FEATURE_MCE)) return; @@ -12237,10 +12246,18 @@ index 5c0e653..1e82c7c 100644 wmb(); diff --git a/arch/x86/kernel/cpu/mcheck/winchip.c b/arch/x86/kernel/cpu/mcheck/winchip.c -index 54060f5..e6ba93d 100644 +index 54060f5..c1a7577 100644 --- a/arch/x86/kernel/cpu/mcheck/winchip.c +++ b/arch/x86/kernel/cpu/mcheck/winchip.c -@@ -24,7 +24,9 @@ void winchip_mcheck_init(struct cpuinfo_x86 *c) +@@ -11,6 +11,7 @@ + #include <asm/system.h> + #include <asm/mce.h> + #include <asm/msr.h> ++#include <asm/pgtable.h> + + /* Machine check handler for WinChip C6: */ + static void winchip_machine_check(struct pt_regs *regs, long error_code) +@@ -24,7 +25,9 @@ void winchip_mcheck_init(struct cpuinfo_x86 *c) { u32 lo, hi; @@ -15883,7 +15900,7 @@ index 3ca42d0..7cff8cc 100644 static void microcode_fini_cpu(int cpu) diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c -index 925179f..85bec6c 100644 +index 925179f..267ac7a 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c @@ -36,15 +36,60 @@ @@ -15893,7 +15910,8 @@ index 925179f..85bec6c 100644 -void *module_alloc(unsigned long size) +static inline void *__module_alloc(unsigned long size, pgprot_t prot) { - if (PAGE_ALIGN(size) > MODULES_LEN) +- if (PAGE_ALIGN(size) > MODULES_LEN) ++ if (size == 0 || PAGE_ALIGN(size) > MODULES_LEN) return NULL; return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, - GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC, @@ -24976,6 +24994,109 @@ index 671d4d6..5f24030 100644 static void cryptd_queue_worker(struct work_struct *work); +diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c +index 9ed9f60..88f160b 100644 +--- a/crypto/sha512_generic.c ++++ b/crypto/sha512_generic.c +@@ -21,8 +21,6 @@ + #include <linux/percpu.h> + #include <asm/byteorder.h> + +-static DEFINE_PER_CPU(u64[80], msg_schedule); +- + static inline u64 Ch(u64 x, u64 y, u64 z) + { + return z ^ (x & (y ^ z)); +@@ -80,7 +78,7 @@ static inline void LOAD_OP(int I, u64 *W, const u8 *input) + + static inline void BLEND_OP(int I, u64 *W) + { +- W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16]; ++ W[I % 16] += s1(W[(I-2) % 16]) + W[(I-7) % 16] + s0(W[(I-15) % 16]); + } + + static void +@@ -89,38 +87,48 @@ sha512_transform(u64 *state, const u8 *input) + u64 a, b, c, d, e, f, g, h, t1, t2; + + int i; +- u64 *W = get_cpu_var(msg_schedule); ++ u64 W[16]; + + /* load the input */ + for (i = 0; i < 16; i++) + LOAD_OP(i, W, input); + +- for (i = 16; i < 80; i++) { +- BLEND_OP(i, W); +- } +- + /* load the state into our registers */ + a=state[0]; b=state[1]; c=state[2]; d=state[3]; + e=state[4]; f=state[5]; g=state[6]; h=state[7]; + +- /* now iterate */ +- for (i=0; i<80; i+=8) { +- t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i ] + W[i ]; +- t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; +- t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[i+1]; +- t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; +- t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[i+2]; +- t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; +- t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[i+3]; +- t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; +- t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[i+4]; +- t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; +- t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[i+5]; +- t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; +- t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[i+6]; +- t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; +- t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[i+7]; +- t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; ++#define SHA512_0_15(i, a, b, c, d, e, f, g, h) \ ++ t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[i]; \ ++ t2 = e0(a) + Maj(a, b, c); \ ++ d += t1; \ ++ h = t1 + t2 ++ ++#define SHA512_16_79(i, a, b, c, d, e, f, g, h) \ ++ BLEND_OP(i, W); \ ++ t1 = h + e1(e) + Ch(e, f, g) + sha512_K[i] + W[(i)%16]; \ ++ t2 = e0(a) + Maj(a, b, c); \ ++ d += t1; \ ++ h = t1 + t2 ++ ++ for (i = 0; i < 16; i += 8) { ++ SHA512_0_15(i, a, b, c, d, e, f, g, h); ++ SHA512_0_15(i + 1, h, a, b, c, d, e, f, g); ++ SHA512_0_15(i + 2, g, h, a, b, c, d, e, f); ++ SHA512_0_15(i + 3, f, g, h, a, b, c, d, e); ++ SHA512_0_15(i + 4, e, f, g, h, a, b, c, d); ++ SHA512_0_15(i + 5, d, e, f, g, h, a, b, c); ++ SHA512_0_15(i + 6, c, d, e, f, g, h, a, b); ++ SHA512_0_15(i + 7, b, c, d, e, f, g, h, a); ++ } ++ for (i = 16; i < 80; i += 8) { ++ SHA512_16_79(i, a, b, c, d, e, f, g, h); ++ SHA512_16_79(i + 1, h, a, b, c, d, e, f, g); ++ SHA512_16_79(i + 2, g, h, a, b, c, d, e, f); ++ SHA512_16_79(i + 3, f, g, h, a, b, c, d, e); ++ SHA512_16_79(i + 4, e, f, g, h, a, b, c, d); ++ SHA512_16_79(i + 5, d, e, f, g, h, a, b, c); ++ SHA512_16_79(i + 6, c, d, e, f, g, h, a, b); ++ SHA512_16_79(i + 7, b, c, d, e, f, g, h, a); + } + + state[0] += a; state[1] += b; state[2] += c; state[3] += d; +@@ -128,8 +136,6 @@ sha512_transform(u64 *state, const u8 *input) + + /* erase our data */ + a = b = c = d = e = f = g = h = t1 = t2 = 0; +- memset(W, 0, sizeof(__get_cpu_var(msg_schedule))); +- put_cpu_var(msg_schedule); + } + + static int diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c index 5d41894..22021e4 100644 --- a/drivers/acpi/apei/cper.c @@ -41282,8 +41403,80 @@ index f7908ae..920a680 100644 dcache_init(); inode_init(); +diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c +index 2a83425..b082cec 100644 +--- a/fs/ecryptfs/crypto.c ++++ b/fs/ecryptfs/crypto.c +@@ -417,17 +417,6 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page, + (unsigned long long)(extent_base + extent_offset), rc); + goto out; + } +- if (unlikely(ecryptfs_verbosity > 0)) { +- ecryptfs_printk(KERN_DEBUG, "Encrypting extent " +- "with iv:\n"); +- ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes); +- ecryptfs_printk(KERN_DEBUG, "First 8 bytes before " +- "encryption:\n"); +- ecryptfs_dump_hex((char *) +- (page_address(page) +- + (extent_offset * crypt_stat->extent_size)), +- 8); +- } + rc = ecryptfs_encrypt_page_offset(crypt_stat, enc_extent_page, 0, + page, (extent_offset + * crypt_stat->extent_size), +@@ -440,14 +429,6 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page, + goto out; + } + rc = 0; +- if (unlikely(ecryptfs_verbosity > 0)) { +- ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16llx]; " +- "rc = [%d]\n", +- (unsigned long long)(extent_base + extent_offset), rc); +- ecryptfs_printk(KERN_DEBUG, "First 8 bytes after " +- "encryption:\n"); +- ecryptfs_dump_hex((char *)(page_address(enc_extent_page)), 8); +- } + out: + return rc; + } +@@ -543,17 +524,6 @@ static int ecryptfs_decrypt_extent(struct page *page, + (unsigned long long)(extent_base + extent_offset), rc); + goto out; + } +- if (unlikely(ecryptfs_verbosity > 0)) { +- ecryptfs_printk(KERN_DEBUG, "Decrypting extent " +- "with iv:\n"); +- ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes); +- ecryptfs_printk(KERN_DEBUG, "First 8 bytes before " +- "decryption:\n"); +- ecryptfs_dump_hex((char *) +- (page_address(enc_extent_page) +- + (extent_offset * crypt_stat->extent_size)), +- 8); +- } + rc = ecryptfs_decrypt_page_offset(crypt_stat, page, + (extent_offset + * crypt_stat->extent_size), +@@ -567,16 +537,6 @@ static int ecryptfs_decrypt_extent(struct page *page, + goto out; + } + rc = 0; +- if (unlikely(ecryptfs_verbosity > 0)) { +- ecryptfs_printk(KERN_DEBUG, "Decrypt extent [0x%.16llx]; " +- "rc = [%d]\n", +- (unsigned long long)(extent_base + extent_offset), rc); +- ecryptfs_printk(KERN_DEBUG, "First 8 bytes after " +- "decryption:\n"); +- ecryptfs_dump_hex((char *)(page_address(page) +- + (extent_offset +- * crypt_stat->extent_size)), 8); +- } + out: + return rc; + } diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c -index 32f90a3..0be89e0 100644 +index 32f90a3..a766407 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -691,7 +691,7 @@ static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf, @@ -41313,8 +41506,84 @@ index 32f90a3..0be89e0 100644 if (!IS_ERR(buf)) { /* Free the char* */ kfree(buf); +@@ -841,18 +841,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, + size_t num_zeros = (PAGE_CACHE_SIZE + - (ia->ia_size & ~PAGE_CACHE_MASK)); + +- +- /* +- * XXX(truncate) this should really happen at the begginning +- * of ->setattr. But the code is too messy to that as part +- * of a larger patch. ecryptfs is also totally missing out +- * on the inode_change_ok check at the beginning of +- * ->setattr while would include this. +- */ +- rc = inode_newsize_ok(inode, ia->ia_size); +- if (rc) +- goto out; +- + if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { + truncate_setsize(inode, ia->ia_size); + lower_ia->ia_size = ia->ia_size; +@@ -902,6 +890,28 @@ out: + return rc; + } + ++static int ecryptfs_inode_newsize_ok(struct inode *inode, loff_t offset) ++{ ++ struct ecryptfs_crypt_stat *crypt_stat; ++ loff_t lower_oldsize, lower_newsize; ++ ++ crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; ++ lower_oldsize = upper_size_to_lower_size(crypt_stat, ++ i_size_read(inode)); ++ lower_newsize = upper_size_to_lower_size(crypt_stat, offset); ++ if (lower_newsize > lower_oldsize) { ++ /* ++ * The eCryptfs inode and the new *lower* size are mixed here ++ * because we may not have the lower i_mutex held and/or it may ++ * not be appropriate to call inode_newsize_ok() with inodes ++ * from other filesystems. ++ */ ++ return inode_newsize_ok(inode, lower_newsize); ++ } ++ ++ return 0; ++} ++ + /** + * ecryptfs_truncate + * @dentry: The ecryptfs layer dentry +@@ -918,6 +928,10 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) + struct iattr lower_ia = { .ia_valid = 0 }; + int rc; + ++ rc = ecryptfs_inode_newsize_ok(dentry->d_inode, new_length); ++ if (rc) ++ return rc; ++ + rc = truncate_upper(dentry, &ia, &lower_ia); + if (!rc && lower_ia.ia_valid & ATTR_SIZE) { + struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); +@@ -997,6 +1011,16 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) + } + } + mutex_unlock(&crypt_stat->cs_mutex); ++ ++ rc = inode_change_ok(inode, ia); ++ if (rc) ++ goto out; ++ if (ia->ia_valid & ATTR_SIZE) { ++ rc = ecryptfs_inode_newsize_ok(inode, ia->ia_size); ++ if (rc) ++ goto out; ++ } ++ + if (S_ISREG(inode->i_mode)) { + rc = filemap_write_and_wait(inode->i_mapping); + if (rc) diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c -index 940a82e..63af89e 100644 +index 940a82e..d3cdeea 100644 --- a/fs/ecryptfs/miscdev.c +++ b/fs/ecryptfs/miscdev.c @@ -328,7 +328,7 @@ check_list: @@ -41326,8 +41595,82 @@ index 940a82e..63af89e 100644 goto out_unlock_msg_ctx; i += packet_length_size; if (copy_to_user(&buf[i], msg_ctx->msg, msg_ctx->msg_size)) +@@ -409,11 +409,47 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, + ssize_t sz = 0; + char *data; + uid_t euid = current_euid(); ++ unsigned char packet_size_peek[3]; + int rc; + +- if (count == 0) ++ if (count == 0) { + goto out; ++ } else if (count == (1 + 4)) { ++ /* Likely a harmless MSG_HELO or MSG_QUIT - no packet length */ ++ goto memdup; ++ } else if (count < (1 + 4 + 1) ++ || count > (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4 ++ + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES)) { ++ printk(KERN_WARNING "%s: Acceptable packet size range is " ++ "[%d-%lu], but amount of data written is [%zu].", ++ __func__, (1 + 4 + 1), ++ (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4 ++ + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES), count); ++ return -EINVAL; ++ } + ++ if (copy_from_user(packet_size_peek, (buf + 1 + 4), ++ sizeof(packet_size_peek))) { ++ printk(KERN_WARNING "%s: Error while inspecting packet size\n", ++ __func__); ++ return -EFAULT; ++ } ++ ++ rc = ecryptfs_parse_packet_length(packet_size_peek, &packet_size, ++ &packet_size_length); ++ if (rc) { ++ printk(KERN_WARNING "%s: Error parsing packet length; " ++ "rc = [%d]\n", __func__, rc); ++ return rc; ++ } ++ ++ if ((1 + 4 + packet_size_length + packet_size) != count) { ++ printk(KERN_WARNING "%s: Invalid packet size [%zu]\n", __func__, ++ packet_size); ++ return -EINVAL; ++ } ++ ++memdup: + data = memdup_user(buf, count); + if (IS_ERR(data)) { + printk(KERN_ERR "%s: memdup_user returned error [%ld]\n", +@@ -435,23 +471,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, + } + memcpy(&counter_nbo, &data[i], 4); + seq = be32_to_cpu(counter_nbo); +- i += 4; +- rc = ecryptfs_parse_packet_length(&data[i], &packet_size, +- &packet_size_length); +- if (rc) { +- printk(KERN_WARNING "%s: Error parsing packet length; " +- "rc = [%d]\n", __func__, rc); +- goto out_free; +- } +- i += packet_size_length; +- if ((1 + 4 + packet_size_length + packet_size) != count) { +- printk(KERN_WARNING "%s: (1 + packet_size_length([%zd])" +- " + packet_size([%zd]))([%zd]) != " +- "count([%zd]). Invalid packet format.\n", +- __func__, packet_size_length, packet_size, +- (1 + packet_size_length + packet_size), count); +- goto out_free; +- } ++ i += 4 + packet_size_length; + rc = ecryptfs_miscdev_response(&data[i], packet_size, + euid, current_user_ns(), + task_pid(current), seq); diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c -index 3745f7c..89cc7a3 100644 +index 3745f7c..7d040a8 100644 --- a/fs/ecryptfs/read_write.c +++ b/fs/ecryptfs/read_write.c @@ -48,7 +48,7 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, @@ -41339,7 +41682,53 @@ index 3745f7c..89cc7a3 100644 set_fs(fs_save); mark_inode_dirty_sync(ecryptfs_inode); return rc; -@@ -235,7 +235,7 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size, +@@ -130,13 +130,18 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset, + pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT); + size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK); + size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page); +- size_t total_remaining_bytes = ((offset + size) - pos); ++ loff_t total_remaining_bytes = ((offset + size) - pos); ++ ++ if (fatal_signal_pending(current)) { ++ rc = -EINTR; ++ break; ++ } + + if (num_bytes > total_remaining_bytes) + num_bytes = total_remaining_bytes; + if (pos < offset) { + /* remaining zeros to write, up to destination offset */ +- size_t total_remaining_zeros = (offset - pos); ++ loff_t total_remaining_zeros = (offset - pos); + + if (num_bytes > total_remaining_zeros) + num_bytes = total_remaining_zeros; +@@ -193,15 +198,19 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset, + } + pos += num_bytes; + } +- if ((offset + size) > ecryptfs_file_size) { +- i_size_write(ecryptfs_inode, (offset + size)); ++ if (pos > ecryptfs_file_size) { ++ i_size_write(ecryptfs_inode, pos); + if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) { +- rc = ecryptfs_write_inode_size_to_metadata( ++ int rc2; ++ ++ rc2 = ecryptfs_write_inode_size_to_metadata( + ecryptfs_inode); +- if (rc) { ++ if (rc2) { + printk(KERN_ERR "Problem with " + "ecryptfs_write_inode_size_to_metadata; " +- "rc = [%d]\n", rc); ++ "rc = [%d]\n", rc2); ++ if (!rc) ++ rc = rc2; + goto out; + } + } +@@ -235,7 +244,7 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size, return -EIO; fs_save = get_fs(); set_fs(get_ds()); @@ -41349,7 +41738,7 @@ index 3745f7c..89cc7a3 100644 return rc; } diff --git a/fs/exec.c b/fs/exec.c -index 3625464..d08b205 100644 +index 3625464..fac01f4 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -55,12 +55,28 @@ @@ -41671,7 +42060,7 @@ index 3625464..d08b205 100644 +#endif + + retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt, -+ bprm->unsafe & LSM_UNSAFE_SHARE); ++ bprm->unsafe); + if (retval < 0) + goto out_fail; + @@ -46762,12 +47151,26 @@ index 23ce927..e274cc1 100644 if (!IS_ERR(s)) kfree(s); +diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c +index ce9268a..ee98d0b 100644 +--- a/fs/xfs/xfs_vnodeops.c ++++ b/fs/xfs/xfs_vnodeops.c +@@ -131,7 +131,8 @@ xfs_readlink( + __func__, (unsigned long long) ip->i_ino, + (long long) pathlen); + ASSERT(0); +- return XFS_ERROR(EFSCORRUPTED); ++ error = XFS_ERROR(EFSCORRUPTED); ++ goto out; + } + + diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig new file mode 100644 -index 0000000..fbe6950d9 +index 0000000..ab77366 --- /dev/null +++ b/grsecurity/Kconfig -@@ -0,0 +1,1067 @@ +@@ -0,0 +1,1065 @@ +# +# grecurity configuration +# @@ -47572,13 +47975,11 @@ index 0000000..fbe6950d9 +config GRKERNSEC_PTRACE_READEXEC + bool "Require read access to ptrace sensitive binaries" + help -+ If you say Y here, read permission will be required by any unprivileged -+ process to ptrace suid/sgid binaries. Note that the ability to -+ ptrace privileged binaries and retain that binary's privilege is -+ already not possible. This option is useful in environments that ++ If you say Y here, unprivileged users will not be able to ptrace unreadable ++ binaries. This option is useful in environments that + remove the read bits (e.g. file mode 4711) from suid binaries to -+ prevent infoleaking of their contents. What this option adds -+ is consistency to the use of that file mode, as the binary could normally ++ prevent infoleaking of their contents. This option adds ++ consistency to the use of that file mode, as the binary could normally + be read out when run without privileges while ptracing. + + If the sysctl option is enabled, a sysctl option with name "ptrace_readexec" @@ -47879,10 +48280,10 @@ index 0000000..be9ae3a +endif diff --git a/grsecurity/gracl.c b/grsecurity/gracl.c new file mode 100644 -index 0000000..09258e0 +index 0000000..d3b423d --- /dev/null +++ b/grsecurity/gracl.c -@@ -0,0 +1,4156 @@ +@@ -0,0 +1,4155 @@ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/sched.h> @@ -47902,7 +48303,7 @@ index 0000000..09258e0 +#include <linux/ptrace.h> +#include <linux/gracl.h> +#include <linux/gralloc.h> -+#include <linux/grsecurity.h> ++#include <linux/security.h> +#include <linux/grinternal.h> +#include <linux/pid_namespace.h> +#include <linux/fdtable.h> @@ -50411,7 +50812,7 @@ index 0000000..09258e0 + +int +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt, -+ const int unsafe_share) ++ const int unsafe_flags) +{ + struct task_struct *task = current; + struct acl_subject_label *newacl; @@ -50424,13 +50825,12 @@ index 0000000..09258e0 + newacl = chk_subj_label(dentry, mnt, task->role); + + task_lock(task); -+ if ((((task->ptrace & PT_PTRACED) || unsafe_share) && -+ !(task->acl->mode & GR_POVERRIDE) && (task->acl != newacl) && ++ if (unsafe_flags && !(task->acl->mode & GR_POVERRIDE) && (task->acl != newacl) && + !(task->role->roletype & GR_ROLE_GOD) && + !gr_search_file(dentry, GR_PTRACERD, mnt) && -+ !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN)))) { ++ !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) { + task_unlock(task); -+ if (unsafe_share) ++ if (unsafe_flags & LSM_UNSAFE_SHARE) + gr_log_fs_generic(GR_DONT_AUDIT, GR_UNSAFESHARE_EXEC_ACL_MSG, dentry, mnt); + else + gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt); @@ -58614,7 +59014,7 @@ index 0000000..da390f1 +#endif diff --git a/include/linux/grmsg.h b/include/linux/grmsg.h new file mode 100644 -index 0000000..cf49370 +index 0000000..dfb15ef --- /dev/null +++ b/include/linux/grmsg.h @@ -0,0 +1,109 @@ @@ -58725,11 +59125,11 @@ index 0000000..cf49370 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by " +#define GR_VM86_MSG "denied use of vm86 by " +#define GR_PTRACE_AUDIT_MSG "process %.950s(%.16s:%d) attached to via ptrace by " -+#define GR_PTRACE_READEXEC_MSG "denied ptrace of unreadable suid/sgid binary %.950s by " ++#define GR_PTRACE_READEXEC_MSG "denied ptrace of unreadable binary %.950s by " +#define GR_INIT_TRANSFER_MSG "persistent special role transferred privilege to init by " diff --git a/include/linux/grsecurity.h b/include/linux/grsecurity.h new file mode 100644 -index 0000000..1ca3931 +index 0000000..eb4885f --- /dev/null +++ b/include/linux/grsecurity.h @@ -0,0 +1,233 @@ @@ -58886,7 +59286,7 @@ index 0000000..1ca3931 + const gid_t gid); +int gr_set_proc_label(const struct dentry *dentry, + const struct vfsmount *mnt, -+ const int unsafe_share); ++ const int unsafe_flags); +__u32 gr_acl_handle_hidden_file(const struct dentry *dentry, + const struct vfsmount *mnt); +__u32 gr_acl_handle_open(const struct dentry *dentry, @@ -59680,7 +60080,7 @@ index ffc0213..2c1f2cb 100644 return nd->saved_names[nd->depth]; } diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h -index a82ad4d..be68b4b 100644 +index a82ad4d..90d15b7 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -949,6 +949,7 @@ struct net_device_ops { @@ -59691,6 +60091,15 @@ index a82ad4d..be68b4b 100644 /* * The DEVICE structure. +@@ -1088,7 +1089,7 @@ struct net_device { + int iflink; + + struct net_device_stats stats; +- atomic_long_t rx_dropped; /* dropped packets by core network ++ atomic_long_unchecked_t rx_dropped; /* dropped packets by core network + * Do not use this in drivers. + */ + diff --git a/include/linux/netfilter/xt_gradm.h b/include/linux/netfilter/xt_gradm.h new file mode 100644 index 0000000..33f4af8 @@ -60026,7 +60435,7 @@ index 2148b12..519b820 100644 static inline void anon_vma_merge(struct vm_area_struct *vma, diff --git a/include/linux/sched.h b/include/linux/sched.h -index 1c4f3e9..e96dced 100644 +index 1c4f3e9..c5b241a 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -101,6 +101,7 @@ struct bio_list; @@ -60135,14 +60544,16 @@ index 1c4f3e9..e96dced 100644 #ifdef CONFIG_DEBUG_MUTEXES /* mutex deadlock detection */ struct mutex_waiter *blocked_on; -@@ -1540,6 +1566,22 @@ struct task_struct { +@@ -1540,6 +1566,24 @@ struct task_struct { unsigned long default_timer_slack_ns; struct list_head *scm_work_list; + +#ifdef CONFIG_GRKERNSEC + /* grsecurity */ ++#ifdef CONFIG_GRKERNSEC_SETXID + const struct cred *delayed_cred; ++#endif + struct dentry *gr_chroot_dentry; + struct acl_subject_label *acl; + struct acl_role_label *role; @@ -60158,7 +60569,7 @@ index 1c4f3e9..e96dced 100644 #ifdef CONFIG_FUNCTION_GRAPH_TRACER /* Index of current stored address in ret_stack */ int curr_ret_stack; -@@ -1574,6 +1616,51 @@ struct task_struct { +@@ -1574,6 +1618,51 @@ struct task_struct { #endif }; @@ -60210,7 +60621,7 @@ index 1c4f3e9..e96dced 100644 /* Future-safe accessor for struct task_struct's cpus_allowed. */ #define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed) -@@ -2081,7 +2168,9 @@ void yield(void); +@@ -2081,7 +2170,9 @@ void yield(void); extern struct exec_domain default_exec_domain; union thread_union { @@ -60220,7 +60631,7 @@ index 1c4f3e9..e96dced 100644 unsigned long stack[THREAD_SIZE/sizeof(long)]; }; -@@ -2114,6 +2203,7 @@ extern struct pid_namespace init_pid_ns; +@@ -2114,6 +2205,7 @@ extern struct pid_namespace init_pid_ns; */ extern struct task_struct *find_task_by_vpid(pid_t nr); @@ -60228,7 +60639,7 @@ index 1c4f3e9..e96dced 100644 extern struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns); -@@ -2251,7 +2341,7 @@ extern void __cleanup_sighand(struct sighand_struct *); +@@ -2251,7 +2343,7 @@ extern void __cleanup_sighand(struct sighand_struct *); extern void exit_itimers(struct signal_struct *); extern void flush_itimer_signals(void); @@ -60237,7 +60648,7 @@ index 1c4f3e9..e96dced 100644 extern void daemonize(const char *, ...); extern int allow_signal(int); -@@ -2416,13 +2506,17 @@ static inline unsigned long *end_of_stack(struct task_struct *p) +@@ -2416,13 +2508,17 @@ static inline unsigned long *end_of_stack(struct task_struct *p) #endif @@ -69949,7 +70360,7 @@ index 716eb4a..8d10419 100644 static const int *pcpu_unit_map __read_mostly; /* cpu -> unit */ diff --git a/mm/process_vm_access.c b/mm/process_vm_access.c -index e920aa3..c19184f0 100644 +index e920aa3..78fe584 100644 --- a/mm/process_vm_access.c +++ b/mm/process_vm_access.c @@ -13,6 +13,7 @@ @@ -69960,7 +70371,15 @@ index e920aa3..c19184f0 100644 #include <linux/ptrace.h> #include <linux/slab.h> #include <linux/syscalls.h> -@@ -264,13 +265,11 @@ static ssize_t process_vm_rw_core(pid_t pid, const struct iovec *lvec, +@@ -258,19 +259,19 @@ static ssize_t process_vm_rw_core(pid_t pid, const struct iovec *lvec, + size_t iov_l_curr_offset = 0; + ssize_t iov_len; + ++ return -ENOSYS; // PaX: until properly audited ++ + /* + * Work out how many pages of struct pages we're going to need + * when eventually calling get_user_pages */ for (i = 0; i < riovcnt; i++) { iov_len = rvec[i].iov_len; @@ -69979,7 +70398,7 @@ index e920aa3..c19184f0 100644 } if (nr_pages == 0) -@@ -298,8 +297,13 @@ static ssize_t process_vm_rw_core(pid_t pid, const struct iovec *lvec, +@@ -298,8 +299,13 @@ static ssize_t process_vm_rw_core(pid_t pid, const struct iovec *lvec, goto free_proc_pages; } @@ -71914,7 +72333,7 @@ index 68bbf9f..5ef0d12 100644 return err; diff --git a/net/core/dev.c b/net/core/dev.c -index 5a13edf..1bc016b 100644 +index 5a13edf..a6f2bd2 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1139,10 +1139,14 @@ void dev_load(struct net *net, const char *name) @@ -71932,6 +72351,24 @@ index 5a13edf..1bc016b 100644 } } EXPORT_SYMBOL(dev_load); +@@ -1573,7 +1577,7 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) + { + if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) { + if (skb_copy_ubufs(skb, GFP_ATOMIC)) { +- atomic_long_inc(&dev->rx_dropped); ++ atomic_long_inc_unchecked(&dev->rx_dropped); + kfree_skb(skb); + return NET_RX_DROP; + } +@@ -1583,7 +1587,7 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) + nf_reset(skb); + + if (unlikely(!is_skb_forwardable(dev, skb))) { +- atomic_long_inc(&dev->rx_dropped); ++ atomic_long_inc_unchecked(&dev->rx_dropped); + kfree_skb(skb); + return NET_RX_DROP; + } @@ -2036,7 +2040,7 @@ static int illegal_highdma(struct net_device *dev, struct sk_buff *skb) struct dev_gso_cb { @@ -71941,6 +72378,15 @@ index 5a13edf..1bc016b 100644 #define DEV_GSO_CB(skb) ((struct dev_gso_cb *)(skb)->cb) +@@ -2970,7 +2974,7 @@ enqueue: + + local_irq_restore(flags); + +- atomic_long_inc(&skb->dev->rx_dropped); ++ atomic_long_inc_unchecked(&skb->dev->rx_dropped); + kfree_skb(skb); + return NET_RX_DROP; + } @@ -3044,7 +3048,7 @@ int netif_rx_ni(struct sk_buff *skb) } EXPORT_SYMBOL(netif_rx_ni); @@ -71950,6 +72396,15 @@ index 5a13edf..1bc016b 100644 { struct softnet_data *sd = &__get_cpu_var(softnet_data); +@@ -3333,7 +3337,7 @@ ncls: + if (pt_prev) { + ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev); + } else { +- atomic_long_inc(&skb->dev->rx_dropped); ++ atomic_long_inc_unchecked(&skb->dev->rx_dropped); + kfree_skb(skb); + /* Jamal, now you will not able to escape explaining + * me how you were going to use this. :-) @@ -3891,7 +3895,7 @@ void netif_napi_del(struct napi_struct *napi) } EXPORT_SYMBOL(netif_napi_del); @@ -71959,6 +72414,15 @@ index 5a13edf..1bc016b 100644 { struct softnet_data *sd = &__get_cpu_var(softnet_data); unsigned long time_limit = jiffies + 2; +@@ -5949,7 +5953,7 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, + } else { + netdev_stats_to_stats64(storage, &dev->stats); + } +- storage->rx_dropped += atomic_long_read(&dev->rx_dropped); ++ storage->rx_dropped += atomic_long_read_unchecked(&dev->rx_dropped); + return storage; + } + EXPORT_SYMBOL(dev_get_stats); diff --git a/net/core/flow.c b/net/core/flow.c index e318c7e..168b1d0 100644 --- a/net/core/flow.c |