summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--2.6.32/0000_README2
-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_README2
-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