summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2012-08-01 19:18:00 -0400
committerAnthony G. Basile <blueness@gentoo.org>2012-08-01 19:18:00 -0400
commitaa9317219e543d3f6f95d00619ba2af268edced9 (patch)
tree7fd1cef2fb392c92192a8ec9a44c9c3c0f21d54b
parentGrsec/PaX: 2.9.1-{2.6.32.59,3.2.24,3.4.6}-201207281946 (diff)
downloadhardened-patchset-aa9317219e543d3f6f95d00619ba2af268edced9.tar.gz
hardened-patchset-aa9317219e543d3f6f95d00619ba2af268edced9.tar.bz2
hardened-patchset-aa9317219e543d3f6f95d00619ba2af268edced9.zip
Grsec/PaX: 2.9.1-{2.6.32.59,3.2.24,3.4.6}-20120731190820120731
-rw-r--r--2.6.32/0000_README2
-rw-r--r--2.6.32/4420_grsecurity-2.9.1-2.6.32.59-201207311908.patch (renamed from 2.6.32/4420_grsecurity-2.9.1-2.6.32.59-201207281944.patch)168
-rw-r--r--3.2.24/0000_README2
-rw-r--r--3.2.24/4420_grsecurity-2.9.1-3.2.24-201207311909.patch (renamed from 3.2.24/4420_grsecurity-2.9.1-3.2.24-201207281946.patch)463
-rw-r--r--3.4.6/0000_README2
-rw-r--r--3.4.6/4420_grsecurity-2.9.1-3.4.7-201207311909.patch (renamed from 3.4.6/4420_grsecurity-2.9.1-3.4.6-201207281946.patch)618
6 files changed, 863 insertions, 392 deletions
diff --git a/2.6.32/0000_README b/2.6.32/0000_README
index d4f6601..3010d85 100644
--- a/2.6.32/0000_README
+++ b/2.6.32/0000_README
@@ -30,7 +30,7 @@ Patch: 1058_linux-2.6.32.59.patch
From: http://www.kernel.org
Desc: Linux 2.6.32.59
-Patch: 4420_grsecurity-2.9.1-2.6.32.59-201207281944.patch
+Patch: 4420_grsecurity-2.9.1-2.6.32.59-201207311908.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/2.6.32/4420_grsecurity-2.9.1-2.6.32.59-201207281944.patch b/2.6.32/4420_grsecurity-2.9.1-2.6.32.59-201207311908.patch
index 227df5e..a17194d 100644
--- a/2.6.32/4420_grsecurity-2.9.1-2.6.32.59-201207281944.patch
+++ b/2.6.32/4420_grsecurity-2.9.1-2.6.32.59-201207311908.patch
@@ -8939,7 +8939,7 @@ index bcbd36c..b1754af 100644
printf(".section \".rodata.compressed\",\"a\",@progbits\n");
diff --git a/arch/x86/boot/compressed/relocs.c b/arch/x86/boot/compressed/relocs.c
-index bbeb0c3..f5167ab 100644
+index bbeb0c3..1eb0571 100644
--- a/arch/x86/boot/compressed/relocs.c
+++ b/arch/x86/boot/compressed/relocs.c
@@ -10,8 +10,11 @@
@@ -9113,7 +9113,7 @@ index bbeb0c3..f5167ab 100644
+
+#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
+ /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
-+ if (!strcmp(sec_name(sym->st_shndx), ".module.text") && !strcmp(sym_name(sym_strtab, sym), "_etext"))
++ if (!strcmp(sec_name(sym->st_shndx), ".text.end") && !strcmp(sym_name(sym_strtab, sym), "_etext"))
+ continue;
+ if (!strcmp(sec_name(sym->st_shndx), ".init.text"))
+ continue;
@@ -23007,7 +23007,7 @@ index d430e4c..831f817 100644
local_irq_save(flags);
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
-index 3c68fe2..12c8280 100644
+index 3c68fe2..7a8c35b 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -26,6 +26,13 @@
@@ -23088,7 +23088,7 @@ index 3c68fe2..12c8280 100644
HEAD_TEXT
#ifdef CONFIG_X86_32
. = ALIGN(PAGE_SIZE);
-@@ -82,28 +102,71 @@ SECTIONS
+@@ -82,28 +102,72 @@ SECTIONS
IRQENTRY_TEXT
*(.fixup)
*(.gnu.warning)
@@ -23113,8 +23113,8 @@ index 3c68fe2..12c8280 100644
+ MODULES_EXEC_VADDR = .;
+ BYTE(0)
+ . += (CONFIG_PAX_KERNEXEC_MODULE_TEXT * 1024 * 1024);
-+ . = ALIGN(HPAGE_SIZE);
-+ MODULES_EXEC_END = . - 1;
++ . = ALIGN(HPAGE_SIZE) - 1;
++ MODULES_EXEC_END = .;
+#endif
+
+ } :module
@@ -23122,6 +23122,7 @@ index 3c68fe2..12c8280 100644
+
+ .text.end : AT(ADDR(.text.end) - LOAD_OFFSET) {
+ /* End of text section */
++ BYTE(0)
+ _etext = . - __KERNEL_TEXT_OFFSET;
+ }
+
@@ -23167,7 +23168,7 @@ index 3c68fe2..12c8280 100644
PAGE_ALIGNED_DATA(PAGE_SIZE)
-@@ -112,6 +175,8 @@ SECTIONS
+@@ -112,6 +176,8 @@ SECTIONS
DATA_DATA
CONSTRUCTORS
@@ -23176,7 +23177,7 @@ index 3c68fe2..12c8280 100644
/* rarely changed data like cpu maps */
READ_MOSTLY_DATA(CONFIG_X86_INTERNODE_CACHE_BYTES)
-@@ -166,12 +231,6 @@ SECTIONS
+@@ -166,12 +232,6 @@ SECTIONS
}
vgetcpu_mode = VVIRT(.vgetcpu_mode);
@@ -23189,7 +23190,7 @@ index 3c68fe2..12c8280 100644
.vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3)) {
*(.vsyscall_3)
}
-@@ -187,12 +246,19 @@ SECTIONS
+@@ -187,12 +247,19 @@ SECTIONS
#endif /* CONFIG_X86_64 */
/* Init code and data - will be freed after init */
@@ -23212,7 +23213,7 @@ index 3c68fe2..12c8280 100644
/*
* percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the
* output PHDR, so the next output section - .init.text - should
-@@ -201,12 +267,27 @@ SECTIONS
+@@ -201,12 +268,27 @@ SECTIONS
PERCPU_VADDR(0, :percpu)
#endif
@@ -23245,7 +23246,7 @@ index 3c68fe2..12c8280 100644
.x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
__x86_cpu_dev_start = .;
-@@ -232,19 +313,11 @@ SECTIONS
+@@ -232,19 +314,11 @@ SECTIONS
*(.altinstr_replacement)
}
@@ -23266,7 +23267,7 @@ index 3c68fe2..12c8280 100644
PERCPU(PAGE_SIZE)
#endif
-@@ -267,12 +340,6 @@ SECTIONS
+@@ -267,12 +341,6 @@ SECTIONS
. = ALIGN(PAGE_SIZE);
}
@@ -23279,7 +23280,7 @@ index 3c68fe2..12c8280 100644
/* BSS */
. = ALIGN(PAGE_SIZE);
.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
-@@ -288,6 +355,7 @@ SECTIONS
+@@ -288,6 +356,7 @@ SECTIONS
__brk_base = .;
. += 64 * 1024; /* 64k alignment slop space */
*(.brk_reservation) /* areas brk users have reserved */
@@ -23287,7 +23288,7 @@ index 3c68fe2..12c8280 100644
__brk_limit = .;
}
-@@ -316,13 +384,12 @@ SECTIONS
+@@ -316,13 +385,12 @@ SECTIONS
* for the boot processor.
*/
#define INIT_PER_CPU(x) init_per_cpu__##x = per_cpu__##x + __per_cpu_load
@@ -75400,7 +75401,7 @@ index fd38ce2..f5381b8 100644
return -EINVAL;
diff --git a/fs/seq_file.c b/fs/seq_file.c
-index eae7d9d..b7613c6 100644
+index eae7d9d..c6bba46 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -9,6 +9,7 @@
@@ -75421,7 +75422,55 @@ index eae7d9d..b7613c6 100644
/*
* Wrappers around seq_open(e.g. swaps_open) need to be
-@@ -551,7 +555,7 @@ static void single_stop(struct seq_file *p, void *v)
+@@ -76,7 +80,11 @@ static int traverse(struct seq_file *m, loff_t offset)
+ return 0;
+ }
+ if (!m->buf) {
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++ m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL | GFP_USERCOPY);
++#else
+ m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
++#endif
+ if (!m->buf)
+ return -ENOMEM;
+ }
+@@ -116,7 +124,11 @@ static int traverse(struct seq_file *m, loff_t offset)
+ Eoverflow:
+ m->op->stop(m, p);
+ kfree(m->buf);
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++ m->buf = kmalloc(m->size <<= 1, GFP_KERNEL | GFP_USERCOPY);
++#else
+ m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
++#endif
+ return !m->buf ? -ENOMEM : -EAGAIN;
+ }
+
+@@ -169,7 +181,11 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
+ m->version = file->f_version;
+ /* grab buffer if we didn't have one */
+ if (!m->buf) {
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++ m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL | GFP_USERCOPY);
++#else
+ m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
++#endif
+ if (!m->buf)
+ goto Enomem;
+ }
+@@ -210,7 +226,11 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
+ goto Fill;
+ m->op->stop(m, p);
+ kfree(m->buf);
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++ m->buf = kmalloc(m->size <<= 1, GFP_KERNEL | GFP_USERCOPY);
++#else
+ m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
++#endif
+ if (!m->buf)
+ goto Enomem;
+ m->count = 0;
+@@ -551,7 +571,7 @@ static void single_stop(struct seq_file *p, void *v)
int single_open(struct file *file, int (*show)(struct seq_file *, void *),
void *data)
{
@@ -76190,10 +76239,10 @@ index 8f32f50..b6a41e8 100644
link[pathlen] = '\0';
diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig
new file mode 100644
-index 0000000..c20c1db
+index 0000000..bbbfa1c
--- /dev/null
+++ b/grsecurity/Kconfig
-@@ -0,0 +1,939 @@
+@@ -0,0 +1,940 @@
+#
+# grecurity configuration
+#
@@ -76320,6 +76369,7 @@ index 0000000..c20c1db
+
+config GRKERNSEC_HIDESYM
+ bool "Hide kernel symbols"
++ select PAX_USERCOPY_SLABS
+ default y if GRKERNSEC_CONFIG_AUTO
+ help
+ If you say Y here, getting information on loaded modules, and
@@ -95468,10 +95518,25 @@ index 67578ca..4115fbf 100644
static inline void mutex_clear_owner(struct mutex *lock)
diff --git a/kernel/panic.c b/kernel/panic.c
-index 96b45d0..7677a03 100644
+index 96b45d0..98fb1c3 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
-@@ -71,7 +71,11 @@ NORET_TYPE void panic(const char * fmt, ...)
+@@ -59,6 +59,14 @@ NORET_TYPE void panic(const char * fmt, ...)
+ long i;
+
+ /*
++ * Disable local interrupts. This will prevent panic_smp_self_stop
++ * from deadlocking the first cpu that invokes the panic, since
++ * there is nothing to prevent an interrupt handler (that runs
++ * after the panic_lock is acquired) from invoking panic again.
++ */
++ local_irq_disable();
++
++ /*
+ * It's possible to come here directly from a panic-assertion and
+ * not have preempt disabled. Some functions called from here want
+ * preempt to be disabled. No point enabling it later though...
+@@ -71,7 +79,11 @@ NORET_TYPE void panic(const char * fmt, ...)
va_end(args);
printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf);
#ifdef CONFIG_DEBUG_BUGVERBOSE
@@ -95484,7 +95549,7 @@ index 96b45d0..7677a03 100644
#endif
/*
-@@ -352,7 +356,7 @@ static void warn_slowpath_common(const char *file, int line, void *caller, struc
+@@ -352,7 +364,7 @@ static void warn_slowpath_common(const char *file, int line, void *caller, struc
const char *board;
printk(KERN_WARNING "------------[ cut here ]------------\n");
@@ -95493,7 +95558,7 @@ index 96b45d0..7677a03 100644
board = dmi_get_system_info(DMI_PRODUCT_NAME);
if (board)
printk(KERN_WARNING "Hardware name: %s\n", board);
-@@ -392,7 +396,8 @@ EXPORT_SYMBOL(warn_slowpath_null);
+@@ -392,7 +404,8 @@ EXPORT_SYMBOL(warn_slowpath_null);
*/
void __stack_chk_fail(void)
{
@@ -98299,7 +98364,7 @@ index 217d5c4..45aba8a 100644
/**
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
-index 33bed5e..1477e46 100644
+index 33bed5e..ab4e52f 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -16,6 +16,9 @@
@@ -98369,7 +98434,30 @@ index 33bed5e..1477e46 100644
return symbol_string(buf, end, ptr, spec, *fmt);
case 'R':
return resource_string(buf, end, ptr, spec);
-@@ -1445,7 +1458,7 @@ do { \
+@@ -853,7 +866,22 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
+ return ip4_addr_string(buf, end, ptr, spec, fmt);
+ }
+ break;
++ case 'P':
++ break;
+ }
++
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++ /* 'P' = approved pointers to copy to userland,
++ as in the /proc/kallsyms case, as we make it display nothing
++ for non-root users, and the real contents for root users
++ */
++ if (ptr > TASK_SIZE && *fmt != 'P' && is_usercopy_object(buf)) {
++ printk(KERN_ALERT "grsec: kernel infoleak detected! Please report this log to spender@grsecurity.net.\n");
++ dump_stack();
++ ptr = NULL;
++ }
++#endif
++
+ spec.flags |= SMALL;
+ if (spec.field_width == -1) {
+ spec.field_width = 2*sizeof(void *);
+@@ -1445,7 +1473,7 @@ do { \
size_t len;
if ((unsigned long)save_str > (unsigned long)-PAGE_SIZE
|| (unsigned long)save_str < PAGE_SIZE)
@@ -98378,7 +98466,7 @@ index 33bed5e..1477e46 100644
len = strlen(save_str);
if (str + len + 1 < end)
memcpy(str, save_str, len + 1);
-@@ -1555,11 +1568,11 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
+@@ -1555,11 +1583,11 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
typeof(type) value; \
if (sizeof(type) == 8) { \
args = PTR_ALIGN(args, sizeof(u32)); \
@@ -98393,7 +98481,7 @@ index 33bed5e..1477e46 100644
} \
args += sizeof(type); \
value; \
-@@ -1622,7 +1635,7 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
+@@ -1622,7 +1650,7 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
const char *str_arg = args;
size_t len = strlen(str_arg);
args += len + 1;
@@ -105574,6 +105662,27 @@ index de4a1b1..94ec861 100644
src_addr = (struct sockaddr_in *)&cm_id->route.addr.src_addr;
dst_addr = (struct sockaddr_in *)&cm_id->route.addr.dst_addr;
+diff --git a/net/rds/recv.c b/net/rds/recv.c
+index 6a2654a..c45a881c 100644
+--- a/net/rds/recv.c
++++ b/net/rds/recv.c
+@@ -410,6 +410,8 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
+
+ rdsdebug("size %zu flags 0x%x timeo %ld\n", size, msg_flags, timeo);
+
++ msg->msg_namelen = 0;
++
+ if (msg_flags & MSG_OOB)
+ goto out;
+
+@@ -486,6 +488,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
+ sin->sin_port = inc->i_hdr.h_sport;
+ sin->sin_addr.s_addr = inc->i_saddr;
+ memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
++ msg->msg_namelen = sizeof(*sin);
+ }
+ break;
+ }
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index b5198ae..8b9fb90 100644
--- a/net/rds/tcp.c
@@ -107155,10 +107264,10 @@ index d52f7a0..b66cdd9 100755
rm -f tags
xtags ctags
diff --git a/security/Kconfig b/security/Kconfig
-index fb363cd..6426142 100644
+index fb363cd..124d914 100644
--- a/security/Kconfig
+++ b/security/Kconfig
-@@ -4,6 +4,869 @@
+@@ -4,6 +4,870 @@
menu "Security options"
@@ -107190,6 +107299,7 @@ index fb363cd..6426142 100644
+ bool "Grsecurity"
+ select CRYPTO
+ select CRYPTO_SHA256
++ select PROC_FS
+ select STOP_MACHINE
+ help
+ If you say Y here, you will be able to configure many features
@@ -108028,7 +108138,7 @@ index fb363cd..6426142 100644
config KEYS
bool "Enable access key retention support"
help
-@@ -146,7 +1009,7 @@ config INTEL_TXT
+@@ -146,7 +1010,7 @@ config INTEL_TXT
config LSM_MMAP_MIN_ADDR
int "Low address space for LSM to protect from user allocation"
depends on SECURITY && SECURITY_SELINUX
diff --git a/3.2.24/0000_README b/3.2.24/0000_README
index 51bc4a5..e45dbd8 100644
--- a/3.2.24/0000_README
+++ b/3.2.24/0000_README
@@ -14,7 +14,7 @@ Patch: 1023_linux-3.2.24.patch
From: http://www.kernel.org
Desc: Linux 3.2.24
-Patch: 4420_grsecurity-2.9.1-3.2.24-201207281946.patch
+Patch: 4420_grsecurity-2.9.1-3.2.24-201207311909.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/3.2.24/4420_grsecurity-2.9.1-3.2.24-201207281946.patch b/3.2.24/4420_grsecurity-2.9.1-3.2.24-201207311909.patch
index d960312..4c10305 100644
--- a/3.2.24/4420_grsecurity-2.9.1-3.2.24-201207281946.patch
+++ b/3.2.24/4420_grsecurity-2.9.1-3.2.24-201207311909.patch
@@ -211,6 +211,39 @@ index 81c287f..d456d02 100644
pcbit= [HW,ISDN]
pcd. [PARIDE]
+diff --git a/Documentation/sysctl/fs.txt b/Documentation/sysctl/fs.txt
+index 88fd7f5..b318a78 100644
+--- a/Documentation/sysctl/fs.txt
++++ b/Documentation/sysctl/fs.txt
+@@ -163,16 +163,22 @@ This value can be used to query and set the core dump mode for setuid
+ or otherwise protected/tainted binaries. The modes are
+
+ 0 - (default) - traditional behaviour. Any process which has changed
+- privilege levels or is execute only will not be dumped
++ privilege levels or is execute only will not be dumped.
+ 1 - (debug) - all processes dump core when possible. The core dump is
+ owned by the current user and no security is applied. This is
+ intended for system debugging situations only. Ptrace is unchecked.
++ This is insecure as it allows regular users to examine the memory
++ contents of privileged processes.
+ 2 - (suidsafe) - any binary which normally would not be dumped is dumped
+- readable by root only. This allows the end user to remove
+- such a dump but not access it directly. For security reasons
+- core dumps in this mode will not overwrite one another or
+- other files. This mode is appropriate when administrators are
+- attempting to debug problems in a normal environment.
++ anyway, but only if the "core_pattern" kernel sysctl is set to
++ either a pipe handler or a fully qualified path. (For more details
++ on this limitation, see CVE-2006-2451.) This mode is appropriate
++ when administrators are attempting to debug problems in a normal
++ environment, and either have a core dump pipe handler that knows
++ to treat privileged core dumps with care, or specific directory
++ defined for catching core dumps. If a core dump happens without
++ a pipe handler or fully qualifid path, a message will be emitted
++ to syslog warning about the lack of a correct setting.
+
+ ==============================================================
+
diff --git a/Makefile b/Makefile
index 80bb4fd..964ea28 100644
--- a/Makefile
@@ -20032,7 +20065,7 @@ index 04b8726..0c35b29 100644
goto cannot_handle;
if ((segoffs >> 16) == BIOSSEG)
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
-index 0f703f1..9e15f64 100644
+index 0f703f1..3b426f3 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -26,6 +26,13 @@
@@ -20101,7 +20134,7 @@ index 0f703f1..9e15f64 100644
HEAD_TEXT
#ifdef CONFIG_X86_32
. = ALIGN(PAGE_SIZE);
-@@ -108,13 +128,47 @@ SECTIONS
+@@ -108,13 +128,48 @@ SECTIONS
IRQENTRY_TEXT
*(.fixup)
*(.gnu.warning)
@@ -20121,8 +20154,8 @@ index 0f703f1..9e15f64 100644
+ MODULES_EXEC_VADDR = .;
+ BYTE(0)
+ . += (CONFIG_PAX_KERNEXEC_MODULE_TEXT * 1024 * 1024);
-+ . = ALIGN(HPAGE_SIZE);
-+ MODULES_EXEC_END = . - 1;
++ . = ALIGN(HPAGE_SIZE) - 1;
++ MODULES_EXEC_END = .;
+#endif
+
+ } :module
@@ -20130,6 +20163,7 @@ index 0f703f1..9e15f64 100644
+
+ .text.end : AT(ADDR(.text.end) - LOAD_OFFSET) {
+ /* End of text section */
++ BYTE(0)
+ _etext = . - __KERNEL_TEXT_OFFSET;
+ }
+
@@ -20153,7 +20187,7 @@ index 0f703f1..9e15f64 100644
#if defined(CONFIG_DEBUG_RODATA)
/* .text should occupy whole number of pages */
-@@ -126,16 +180,20 @@ SECTIONS
+@@ -126,16 +181,20 @@ SECTIONS
/* Data */
.data : AT(ADDR(.data) - LOAD_OFFSET) {
@@ -20177,7 +20211,7 @@ index 0f703f1..9e15f64 100644
PAGE_ALIGNED_DATA(PAGE_SIZE)
-@@ -176,12 +234,19 @@ SECTIONS
+@@ -176,12 +235,19 @@ SECTIONS
#endif /* CONFIG_X86_64 */
/* Init code and data - will be freed after init */
@@ -20200,7 +20234,7 @@ index 0f703f1..9e15f64 100644
/*
* percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the
* output PHDR, so the next output section - .init.text - should
-@@ -190,12 +255,27 @@ SECTIONS
+@@ -190,12 +256,27 @@ SECTIONS
PERCPU_VADDR(INTERNODE_CACHE_BYTES, 0, :percpu)
#endif
@@ -20233,7 +20267,7 @@ index 0f703f1..9e15f64 100644
/*
* Code and data for a variety of lowlevel trampolines, to be
-@@ -269,19 +349,12 @@ SECTIONS
+@@ -269,19 +350,12 @@ SECTIONS
}
. = ALIGN(8);
@@ -20254,7 +20288,7 @@ index 0f703f1..9e15f64 100644
PERCPU_SECTION(INTERNODE_CACHE_BYTES)
#endif
-@@ -300,16 +373,10 @@ SECTIONS
+@@ -300,16 +374,10 @@ SECTIONS
.smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
__smp_locks = .;
*(.smp_locks)
@@ -20272,7 +20306,7 @@ index 0f703f1..9e15f64 100644
/* BSS */
. = ALIGN(PAGE_SIZE);
.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
-@@ -325,6 +392,7 @@ SECTIONS
+@@ -325,6 +393,7 @@ SECTIONS
__brk_base = .;
. += 64 * 1024; /* 64k alignment slop space */
*(.brk_reservation) /* areas brk users have reserved */
@@ -20280,7 +20314,7 @@ index 0f703f1..9e15f64 100644
__brk_limit = .;
}
-@@ -351,13 +419,12 @@ SECTIONS
+@@ -351,13 +420,12 @@ SECTIONS
* for the boot processor.
*/
#define INIT_PER_CPU(x) init_per_cpu__##x = x + __per_cpu_load
@@ -26837,7 +26871,7 @@ index f10c0af..3ec1f95 100644
syscall_init(); /* This sets MSR_*STAR and related */
#endif
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
-index e529730..574ed56 100644
+index e529730..8d08690 100644
--- a/arch/x86/tools/relocs.c
+++ b/arch/x86/tools/relocs.c
@@ -11,10 +11,13 @@
@@ -26930,7 +26964,7 @@ index e529730..574ed56 100644
}
+ base = 0;
+
-+#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
++#ifdef CONFIG_X86_32
+ for (j = 0; j < ehdr.e_phnum; j++) {
+ if (phdr[j].p_type != PT_LOAD )
+ continue;
@@ -27007,7 +27041,7 @@ index e529730..574ed56 100644
+
+#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
+ /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
-+ if (!strcmp(sec_name(sym->st_shndx), ".module.text") && !strcmp(sym_name(sym_strtab, sym), "_etext"))
++ if (!strcmp(sec_name(sym->st_shndx), ".text.end") && !strcmp(sym_name(sym_strtab, sym), "_etext"))
+ continue;
+ if (!strcmp(sec_name(sym->st_shndx), ".init.text"))
+ continue;
@@ -34820,6 +34854,19 @@ index 2b1482a..5d33616 100644
union axis_conversion ac; /* hw -> logical axis */
int mapped_btns[3];
+diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c
+index 150cd70..1d5d99b 100644
+--- a/drivers/misc/lkdtm.c
++++ b/drivers/misc/lkdtm.c
+@@ -473,6 +473,8 @@ static ssize_t lkdtm_debugfs_read(struct file *f, char __user *user_buf,
+ int i, n, out;
+
+ buf = (char *)__get_free_page(GFP_KERNEL);
++ if (buf == NULL)
++ return -ENOMEM;
+
+ n = snprintf(buf, PAGE_SIZE, "Available crash types:\n");
+ for (i = 0; i < ARRAY_SIZE(cp_type); i++)
diff --git a/drivers/misc/sgi-gru/gruhandles.c b/drivers/misc/sgi-gru/gruhandles.c
index 2f30bad..c4c13d0 100644
--- a/drivers/misc/sgi-gru/gruhandles.c
@@ -35090,6 +35137,22 @@ index 8d082b4..aa749ae 100644
/*
* Timer function to enforce the timelimit on the partition disengage.
+diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c
+index ba168a7..399925d 100644
+--- a/drivers/misc/ti-st/st_core.c
++++ b/drivers/misc/ti-st/st_core.c
+@@ -347,6 +347,11 @@ void st_int_recv(void *disc_data,
+ st_gdata->rx_skb = alloc_skb(
+ st_gdata->list[type]->max_frame_size,
+ GFP_ATOMIC);
++ if (st_gdata->rx_skb == NULL) {
++ pr_err("out of memory: dropping\n");
++ goto done;
++ }
++
+ skb_reserve(st_gdata->rx_skb,
+ st_gdata->list[type]->reserve);
+ /* next 2 required for BT only */
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 6878a94..fe5c5f1 100644
--- a/drivers/mmc/host/sdhci-pci.c
@@ -44481,7 +44544,7 @@ index 608c1c3..7d040a8 100644
return rc;
}
diff --git a/fs/exec.c b/fs/exec.c
-index 160cd2f..5cc2091 100644
+index 160cd2f..78b8d86 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -55,12 +55,33 @@
@@ -45252,6 +45315,36 @@ index 160cd2f..5cc2091 100644
static int zap_process(struct task_struct *start, int exit_code)
{
struct task_struct *t;
+@@ -1988,17 +2365,17 @@ static void coredump_finish(struct mm_struct *mm)
+ void set_dumpable(struct mm_struct *mm, int value)
+ {
+ switch (value) {
+- case 0:
++ case SUID_DUMPABLE_DISABLED:
+ clear_bit(MMF_DUMPABLE, &mm->flags);
+ smp_wmb();
+ clear_bit(MMF_DUMP_SECURELY, &mm->flags);
+ break;
+- case 1:
++ case SUID_DUMPABLE_ENABLED:
+ set_bit(MMF_DUMPABLE, &mm->flags);
+ smp_wmb();
+ clear_bit(MMF_DUMP_SECURELY, &mm->flags);
+ break;
+- case 2:
++ case SUID_DUMPABLE_SAFE:
+ set_bit(MMF_DUMP_SECURELY, &mm->flags);
+ smp_wmb();
+ set_bit(MMF_DUMPABLE, &mm->flags);
+@@ -2011,7 +2388,7 @@ static int __get_dumpable(unsigned long mm_flags)
+ int ret;
+
+ ret = mm_flags & MMF_DUMPABLE_MASK;
+- return (ret >= 2) ? 2 : ret;
++ return (ret > SUID_DUMPABLE_ENABLED) ? SUID_DUMPABLE_SAFE : ret;
+ }
+
+ int get_dumpable(struct mm_struct *mm)
@@ -2026,17 +2403,17 @@ static void wait_for_dump_helpers(struct file *file)
pipe = file->f_path.dentry->d_inode->i_pipe;
@@ -45275,16 +45368,17 @@ index 160cd2f..5cc2091 100644
pipe_unlock(pipe);
}
-@@ -2097,7 +2474,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2097,7 +2474,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
int retval = 0;
int flag = 0;
int ispipe;
- static atomic_t core_dump_count = ATOMIC_INIT(0);
++ bool need_nonrelative = false;
+ static atomic_unchecked_t core_dump_count = ATOMIC_INIT(0);
struct coredump_params cprm = {
.signr = signr,
.regs = regs,
-@@ -2112,6 +2489,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2112,6 +2490,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
audit_core_dumps(signr);
@@ -45294,7 +45388,28 @@ index 160cd2f..5cc2091 100644
binfmt = mm->binfmt;
if (!binfmt || !binfmt->core_dump)
goto fail;
-@@ -2179,7 +2559,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2122,14 +2503,16 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+ if (!cred)
+ goto fail;
+ /*
+- * We cannot trust fsuid as being the "true" uid of the
+- * process nor do we know its entire history. We only know it
+- * was tainted so we dump it as root in mode 2.
++ * We cannot trust fsuid as being the "true" uid of the process
++ * nor do we know its entire history. We only know it was tainted
++ * so we dump it as root in mode 2, and only into a controlled
++ * environment (pipe handler or fully qualified path).
+ */
+- if (__get_dumpable(cprm.mm_flags) == 2) {
++ if (__get_dumpable(cprm.mm_flags) == SUID_DUMPABLE_SAFE) {
+ /* Setuid core dump mode */
+ flag = O_EXCL; /* Stop rewrite attacks */
+ cred->fsuid = 0; /* Dump root private */
++ need_nonrelative = true;
+ }
+
+ retval = coredump_wait(exit_code, &core_state);
+@@ -2179,7 +2562,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
}
cprm.limit = RLIM_INFINITY;
@@ -45303,7 +45418,7 @@ index 160cd2f..5cc2091 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);
-@@ -2206,6 +2586,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2206,9 +2589,19 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
} else {
struct inode *inode;
@@ -45312,7 +45427,18 @@ index 160cd2f..5cc2091 100644
if (cprm.limit < binfmt->min_coredump)
goto fail_unlock;
-@@ -2249,7 +2631,7 @@ close_fail:
++ if (need_nonrelative && cn.corename[0] != '/') {
++ printk(KERN_WARNING "Pid %d(%s) can only dump core "\
++ "to fully qualified path!\n",
++ task_tgid_vnr(current), current->comm);
++ printk(KERN_WARNING "Skipping core dump\n");
++ goto fail_unlock;
++ }
++
+ cprm.file = filp_open(cn.corename,
+ O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag,
+ 0600);
+@@ -2249,7 +2642,7 @@ close_fail:
filp_close(cprm.file, NULL);
fail_dropcount:
if (ispipe)
@@ -45321,7 +45447,7 @@ index 160cd2f..5cc2091 100644
fail_unlock:
kfree(cn.corename);
fail_corename:
-@@ -2268,7 +2650,7 @@ fail:
+@@ -2268,7 +2661,7 @@ fail:
*/
int dump_write(struct file *file, const void *addr, int nr)
{
@@ -50014,7 +50140,7 @@ index d33418f..2a5345e 100644
return -EINVAL;
diff --git a/fs/seq_file.c b/fs/seq_file.c
-index dba43c3..4b3f701 100644
+index dba43c3..9ae2292 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -9,6 +9,7 @@
@@ -50035,7 +50161,55 @@ index dba43c3..4b3f701 100644
/*
* Wrappers around seq_open(e.g. swaps_open) need to be
-@@ -549,7 +553,7 @@ static void single_stop(struct seq_file *p, void *v)
+@@ -76,7 +80,11 @@ static int traverse(struct seq_file *m, loff_t offset)
+ return 0;
+ }
+ if (!m->buf) {
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++ m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL | GFP_USERCOPY);
++#else
+ m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
++#endif
+ if (!m->buf)
+ return -ENOMEM;
+ }
+@@ -116,7 +124,11 @@ static int traverse(struct seq_file *m, loff_t offset)
+ Eoverflow:
+ m->op->stop(m, p);
+ kfree(m->buf);
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++ m->buf = kmalloc(m->size <<= 1, GFP_KERNEL | GFP_USERCOPY);
++#else
+ m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
++#endif
+ return !m->buf ? -ENOMEM : -EAGAIN;
+ }
+
+@@ -169,7 +181,11 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
+ m->version = file->f_version;
+ /* grab buffer if we didn't have one */
+ if (!m->buf) {
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++ m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL | GFP_USERCOPY);
++#else
+ m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
++#endif
+ if (!m->buf)
+ goto Enomem;
+ }
+@@ -210,7 +226,11 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
+ goto Fill;
+ m->op->stop(m, p);
+ kfree(m->buf);
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++ m->buf = kmalloc(m->size <<= 1, GFP_KERNEL | GFP_USERCOPY);
++#else
+ m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
++#endif
+ if (!m->buf)
+ goto Enomem;
+ m->count = 0;
+@@ -549,7 +569,7 @@ static void single_stop(struct seq_file *p, void *v)
int single_open(struct file *file, int (*show)(struct seq_file *, void *),
void *data)
{
@@ -50452,10 +50626,10 @@ index 23ce927..e274cc1 100644
kfree(s);
diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig
new file mode 100644
-index 0000000..b9e7d6f
+index 0000000..cb7b8ea
--- /dev/null
+++ b/grsecurity/Kconfig
-@@ -0,0 +1,940 @@
+@@ -0,0 +1,941 @@
+#
+# grecurity configuration
+#
@@ -50583,6 +50757,7 @@ index 0000000..b9e7d6f
+
+config GRKERNSEC_HIDESYM
+ bool "Hide kernel symbols"
++ select PAX_USERCOPY_SLABS
+ default y if GRKERNSEC_CONFIG_AUTO
+ help
+ If you say Y here, getting information on loaded modules, and
@@ -64045,7 +64220,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 5afa2a3..98df553 100644
+index 5afa2a3..d74a9b4 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -101,6 +101,7 @@ struct bio_list;
@@ -64070,7 +64245,19 @@ index 5afa2a3..98df553 100644
extern void arch_pick_mmap_layout(struct mm_struct *mm);
extern unsigned long
arch_get_unmapped_area(struct file *, unsigned long, unsigned long,
-@@ -629,6 +633,17 @@ struct signal_struct {
+@@ -402,6 +406,11 @@ static inline void arch_pick_mmap_layout(struct mm_struct *mm) {}
+ extern void set_dumpable(struct mm_struct *mm, int value);
+ extern int get_dumpable(struct mm_struct *mm);
+
++/* get/set_dumpable() values */
++#define SUID_DUMPABLE_DISABLED 0
++#define SUID_DUMPABLE_ENABLED 1
++#define SUID_DUMPABLE_SAFE 2
++
+ /* mm flags */
+ /* dumpable bits */
+ #define MMF_DUMPABLE 0 /* core dump is permitted */
+@@ -629,6 +638,17 @@ struct signal_struct {
#ifdef CONFIG_TASKSTATS
struct taskstats *stats;
#endif
@@ -64088,7 +64275,7 @@ index 5afa2a3..98df553 100644
#ifdef CONFIG_AUDIT
unsigned audit_tty;
struct tty_audit_buf *tty_audit_buf;
-@@ -710,6 +725,11 @@ struct user_struct {
+@@ -710,6 +730,11 @@ struct user_struct {
struct key *session_keyring; /* UID's default session keyring */
#endif
@@ -64100,7 +64287,7 @@ index 5afa2a3..98df553 100644
/* Hash table maintenance information */
struct hlist_node uidhash_node;
uid_t uid;
-@@ -1337,8 +1357,8 @@ struct task_struct {
+@@ -1337,8 +1362,8 @@ struct task_struct {
struct list_head thread_group;
struct completion *vfork_done; /* for vfork() */
@@ -64111,7 +64298,7 @@ index 5afa2a3..98df553 100644
cputime_t utime, stime, utimescaled, stimescaled;
cputime_t gtime;
-@@ -1354,13 +1374,6 @@ struct task_struct {
+@@ -1354,13 +1379,6 @@ struct task_struct {
struct task_cputime cputime_expires;
struct list_head cpu_timers[3];
@@ -64125,7 +64312,7 @@ index 5afa2a3..98df553 100644
char comm[TASK_COMM_LEN]; /* executable name excluding path
- access with [gs]et_task_comm (which lock
it with task_lock())
-@@ -1377,8 +1390,16 @@ struct task_struct {
+@@ -1377,8 +1395,16 @@ struct task_struct {
#endif
/* CPU-specific state of this task */
struct thread_struct thread;
@@ -64142,7 +64329,7 @@ index 5afa2a3..98df553 100644
/* open file information */
struct files_struct *files;
/* namespaces */
-@@ -1425,6 +1446,11 @@ struct task_struct {
+@@ -1425,6 +1451,11 @@ struct task_struct {
struct rt_mutex_waiter *pi_blocked_on;
#endif
@@ -64154,7 +64341,7 @@ index 5afa2a3..98df553 100644
#ifdef CONFIG_DEBUG_MUTEXES
/* mutex deadlock detection */
struct mutex_waiter *blocked_on;
-@@ -1540,6 +1566,27 @@ struct task_struct {
+@@ -1540,6 +1571,27 @@ struct task_struct {
unsigned long default_timer_slack_ns;
struct list_head *scm_work_list;
@@ -64182,7 +64369,7 @@ index 5afa2a3..98df553 100644
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
/* Index of current stored address in ret_stack */
int curr_ret_stack;
-@@ -1574,6 +1621,51 @@ struct task_struct {
+@@ -1574,6 +1626,51 @@ struct task_struct {
#endif
};
@@ -64234,7 +64421,7 @@ index 5afa2a3..98df553 100644
/* Future-safe accessor for struct task_struct's cpus_allowed. */
#define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed)
-@@ -2089,7 +2181,9 @@ void yield(void);
+@@ -2089,7 +2186,9 @@ void yield(void);
extern struct exec_domain default_exec_domain;
union thread_union {
@@ -64244,7 +64431,7 @@ index 5afa2a3..98df553 100644
unsigned long stack[THREAD_SIZE/sizeof(long)];
};
-@@ -2122,6 +2216,7 @@ extern struct pid_namespace init_pid_ns;
+@@ -2122,6 +2221,7 @@ extern struct pid_namespace init_pid_ns;
*/
extern struct task_struct *find_task_by_vpid(pid_t nr);
@@ -64252,7 +64439,7 @@ index 5afa2a3..98df553 100644
extern struct task_struct *find_task_by_pid_ns(pid_t nr,
struct pid_namespace *ns);
-@@ -2243,6 +2338,12 @@ static inline void mmdrop(struct mm_struct * mm)
+@@ -2243,6 +2343,12 @@ static inline void mmdrop(struct mm_struct * mm)
extern void mmput(struct mm_struct *);
/* Grab a reference to a task's mm, if it is not already going away */
extern struct mm_struct *get_task_mm(struct task_struct *task);
@@ -64265,7 +64452,7 @@ index 5afa2a3..98df553 100644
/* Remove the current tasks stale references to the old mm_struct */
extern void mm_release(struct task_struct *, struct mm_struct *);
/* Allocate a new mm structure and copy contents from tsk->mm */
-@@ -2259,7 +2360,7 @@ extern void __cleanup_sighand(struct sighand_struct *);
+@@ -2259,7 +2365,7 @@ extern void __cleanup_sighand(struct sighand_struct *);
extern void exit_itimers(struct signal_struct *);
extern void flush_itimer_signals(void);
@@ -64274,7 +64461,7 @@ index 5afa2a3..98df553 100644
extern void daemonize(const char *, ...);
extern int allow_signal(int);
-@@ -2424,9 +2525,9 @@ static inline unsigned long *end_of_stack(struct task_struct *p)
+@@ -2424,9 +2530,9 @@ static inline unsigned long *end_of_stack(struct task_struct *p)
#endif
@@ -67642,7 +67829,7 @@ index 66ff710..794bc5a 100644
static int
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
-index 079f1d3..a407562 100644
+index 079f1d3..5299c80 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -11,6 +11,9 @@
@@ -67738,7 +67925,22 @@ index 079f1d3..a407562 100644
/* Some debugging symbols have no name. Ignore them. */
if (!iter->name[0])
return 0;
-@@ -540,7 +583,7 @@ static int kallsyms_open(struct inode *inode, struct file *file)
+@@ -515,8 +558,14 @@ static int s_show(struct seq_file *m, void *p)
+ */
+ type = iter->exported ? toupper(iter->type) :
+ tolower(iter->type);
++
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++ seq_printf(m, "%pP %c %s\t[%s]\n", (void *)iter->value,
++ type, iter->name, iter->module_name);
++#else
+ seq_printf(m, "%pK %c %s\t[%s]\n", (void *)iter->value,
+ type, iter->name, iter->module_name);
++#endif
+ } else
+ seq_printf(m, "%pK %c %s\n", (void *)iter->value,
+ iter->type, iter->name);
+@@ -540,7 +589,7 @@ static int kallsyms_open(struct inode *inode, struct file *file)
struct kallsym_iter *iter;
int ret;
@@ -68832,10 +69034,25 @@ index b452599..5d68f4e 100644
atomic_set(&pd->refcnt, 0);
pd->pinst = pinst;
diff --git a/kernel/panic.c b/kernel/panic.c
-index 3458469..3492363 100644
+index 3458469..3ed0694 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
-@@ -78,7 +78,11 @@ NORET_TYPE void panic(const char * fmt, ...)
+@@ -65,6 +65,14 @@ NORET_TYPE void panic(const char * fmt, ...)
+ int state = 0;
+
+ /*
++ * Disable local interrupts. This will prevent panic_smp_self_stop
++ * from deadlocking the first cpu that invokes the panic, since
++ * there is nothing to prevent an interrupt handler (that runs
++ * after the panic_lock is acquired) from invoking panic again.
++ */
++ local_irq_disable();
++
++ /*
+ * It's possible to come here directly from a panic-assertion and
+ * not have preempt disabled. Some functions called from here want
+ * preempt to be disabled. No point enabling it later though...
+@@ -78,7 +86,11 @@ NORET_TYPE void panic(const char * fmt, ...)
va_end(args);
printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf);
#ifdef CONFIG_DEBUG_BUGVERBOSE
@@ -68848,7 +69065,7 @@ index 3458469..3492363 100644
#endif
/*
-@@ -382,7 +386,7 @@ static void warn_slowpath_common(const char *file, int line, void *caller,
+@@ -382,7 +394,7 @@ static void warn_slowpath_common(const char *file, int line, void *caller,
const char *board;
printk(KERN_WARNING "------------[ cut here ]------------\n");
@@ -68857,7 +69074,7 @@ index 3458469..3492363 100644
board = dmi_get_system_info(DMI_PRODUCT_NAME);
if (board)
printk(KERN_WARNING "Hardware name: %s\n", board);
-@@ -437,7 +441,8 @@ EXPORT_SYMBOL(warn_slowpath_null);
+@@ -437,7 +449,8 @@ EXPORT_SYMBOL(warn_slowpath_null);
*/
void __stack_chk_fail(void)
{
@@ -70297,7 +70514,7 @@ index 481611f..0754d86 100644
break;
}
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
-index ea7ec7f..5b76fb9 100644
+index ea7ec7f..23d4094 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -86,6 +86,13 @@
@@ -70314,7 +70531,7 @@ index ea7ec7f..5b76fb9 100644
/* External variables not in a header file. */
extern int sysctl_overcommit_memory;
-@@ -165,10 +172,8 @@ static int proc_taint(struct ctl_table *table, int write,
+@@ -165,10 +172,13 @@ static int proc_taint(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos);
#endif
@@ -70322,10 +70539,15 @@ index ea7ec7f..5b76fb9 100644
static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos);
-#endif
++
++static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write,
++ void __user *buffer, size_t *lenp, loff_t *ppos);
++static int proc_dostring_coredump(struct ctl_table *table, int write,
++ void __user *buffer, size_t *lenp, loff_t *ppos);
#ifdef CONFIG_MAGIC_SYSRQ
/* Note: sysrq code uses it's own private copy */
-@@ -191,6 +196,7 @@ static int sysrq_sysctl_handler(ctl_table *table, int write,
+@@ -191,6 +201,7 @@ static int sysrq_sysctl_handler(ctl_table *table, int write,
}
#endif
@@ -70333,7 +70555,7 @@ index ea7ec7f..5b76fb9 100644
static struct ctl_table root_table[];
static struct ctl_table_root sysctl_table_root;
-@@ -220,6 +226,20 @@ extern struct ctl_table epoll_table[];
+@@ -220,6 +231,20 @@ extern struct ctl_table epoll_table[];
int sysctl_legacy_va_layout;
#endif
@@ -70354,7 +70576,7 @@ index ea7ec7f..5b76fb9 100644
/* The default sysctl tables: */
static struct ctl_table root_table[] = {
-@@ -266,6 +286,22 @@ static int max_extfrag_threshold = 1000;
+@@ -266,6 +291,22 @@ static int max_extfrag_threshold = 1000;
#endif
static struct ctl_table kern_table[] = {
@@ -70377,7 +70599,16 @@ index ea7ec7f..5b76fb9 100644
{
.procname = "sched_child_runs_first",
.data = &sysctl_sched_child_runs_first,
-@@ -550,7 +586,7 @@ static struct ctl_table kern_table[] = {
+@@ -420,7 +461,7 @@ static struct ctl_table kern_table[] = {
+ .data = core_pattern,
+ .maxlen = CORENAME_MAX_SIZE,
+ .mode = 0644,
+- .proc_handler = proc_dostring,
++ .proc_handler = proc_dostring_coredump,
+ },
+ {
+ .procname = "core_pipe_limit",
+@@ -550,7 +591,7 @@ static struct ctl_table kern_table[] = {
.data = &modprobe_path,
.maxlen = KMOD_PATH_LEN,
.mode = 0644,
@@ -70386,7 +70617,7 @@ index ea7ec7f..5b76fb9 100644
},
{
.procname = "modules_disabled",
-@@ -717,16 +753,20 @@ static struct ctl_table kern_table[] = {
+@@ -717,16 +758,20 @@ static struct ctl_table kern_table[] = {
.extra1 = &zero,
.extra2 = &one,
},
@@ -70408,7 +70639,7 @@ index ea7ec7f..5b76fb9 100644
{
.procname = "ngroups_max",
.data = &ngroups_max,
-@@ -1216,6 +1256,13 @@ static struct ctl_table vm_table[] = {
+@@ -1216,6 +1261,13 @@ static struct ctl_table vm_table[] = {
.proc_handler = proc_dointvec_minmax,
.extra1 = &zero,
},
@@ -70422,7 +70653,16 @@ index ea7ec7f..5b76fb9 100644
#else
{
.procname = "nr_trim_pages",
-@@ -1720,6 +1767,17 @@ static int test_perm(int mode, int op)
+@@ -1499,7 +1551,7 @@ static struct ctl_table fs_table[] = {
+ .data = &suid_dumpable,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+- .proc_handler = proc_dointvec_minmax,
++ .proc_handler = proc_dointvec_minmax_coredump,
+ .extra1 = &zero,
+ .extra2 = &two,
+ },
+@@ -1720,6 +1772,17 @@ static int test_perm(int mode, int op)
int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op)
{
int mode;
@@ -70440,7 +70680,7 @@ index ea7ec7f..5b76fb9 100644
if (root->permissions)
mode = root->permissions(root, current->nsproxy, table);
-@@ -2124,6 +2182,16 @@ int proc_dostring(struct ctl_table *table, int write,
+@@ -2124,6 +2187,16 @@ int proc_dostring(struct ctl_table *table, int write,
buffer, lenp, ppos);
}
@@ -70457,7 +70697,7 @@ index ea7ec7f..5b76fb9 100644
static size_t proc_skip_spaces(char **buf)
{
size_t ret;
-@@ -2229,6 +2297,8 @@ static int proc_put_long(void __user **buf, size_t *size, unsigned long val,
+@@ -2229,6 +2302,8 @@ static int proc_put_long(void __user **buf, size_t *size, unsigned long val,
len = strlen(tmp);
if (len > *size)
len = *size;
@@ -70466,7 +70706,7 @@ index ea7ec7f..5b76fb9 100644
if (copy_to_user(*buf, tmp, len))
return -EFAULT;
*size -= len;
-@@ -2421,7 +2491,6 @@ static int proc_taint(struct ctl_table *table, int write,
+@@ -2421,7 +2496,6 @@ static int proc_taint(struct ctl_table *table, int write,
return err;
}
@@ -70474,7 +70714,7 @@ index ea7ec7f..5b76fb9 100644
static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
-@@ -2430,7 +2499,6 @@ static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
+@@ -2430,7 +2504,6 @@ static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
}
@@ -70482,7 +70722,42 @@ index ea7ec7f..5b76fb9 100644
struct do_proc_dointvec_minmax_conv_param {
int *min;
-@@ -2545,8 +2613,11 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
+@@ -2488,6 +2561,34 @@ int proc_dointvec_minmax(struct ctl_table *table, int write,
+ do_proc_dointvec_minmax_conv, &param);
+ }
+
++static void validate_coredump_safety(void)
++{
++ if (suid_dumpable == SUID_DUMPABLE_SAFE &&
++ core_pattern[0] != '/' && core_pattern[0] != '|') {
++ printk(KERN_WARNING "Unsafe core_pattern used with "\
++ "suid_dumpable=2. Pipe handler or fully qualified "\
++ "core dump path required.\n");
++ }
++}
++
++static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write,
++ void __user *buffer, size_t *lenp, loff_t *ppos)
++{
++ int error = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
++ if (!error)
++ validate_coredump_safety();
++ return error;
++}
++
++static int proc_dostring_coredump(struct ctl_table *table, int write,
++ void __user *buffer, size_t *lenp, loff_t *ppos)
++{
++ int error = proc_dostring(table, write, buffer, lenp, ppos);
++ if (!error)
++ validate_coredump_safety();
++ return error;
++}
++
+ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write,
+ void __user *buffer,
+ size_t *lenp, loff_t *ppos,
+@@ -2545,8 +2646,11 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
*i = val;
} else {
val = convdiv * (*i) / convmul;
@@ -70495,7 +70770,7 @@ index ea7ec7f..5b76fb9 100644
err = proc_put_long(&buffer, &left, val, false);
if (err)
break;
-@@ -2941,6 +3012,12 @@ int proc_dostring(struct ctl_table *table, int write,
+@@ -2941,6 +3045,12 @@ int proc_dostring(struct ctl_table *table, int write,
return -ENOSYS;
}
@@ -70508,7 +70783,7 @@ index ea7ec7f..5b76fb9 100644
int proc_dointvec(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
-@@ -2997,6 +3074,7 @@ EXPORT_SYMBOL(proc_dointvec_minmax);
+@@ -2997,6 +3107,7 @@ EXPORT_SYMBOL(proc_dointvec_minmax);
EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
EXPORT_SYMBOL(proc_dostring);
@@ -71306,7 +71581,7 @@ index d9df745..e73c2fe 100644
static inline void *ptr_to_indirect(void *ptr)
{
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
-index 993599e..f1dbc14 100644
+index 993599e..9b1cb1f 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -16,6 +16,9 @@
@@ -71378,7 +71653,7 @@ index 993599e..f1dbc14 100644
case 'B':
return symbol_string(buf, end, ptr, spec, *fmt);
case 'R':
-@@ -878,9 +894,15 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
+@@ -878,15 +894,24 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
case 'U':
return uuid_string(buf, end, ptr, spec, fmt);
case 'V':
@@ -71394,10 +71669,40 @@ index 993599e..f1dbc14 100644
+ va_end(va);
+ return buf;
+ }
++ case 'P':
++ break;
case 'K':
/*
* %pK cannot be used in IRQ context because its test
-@@ -1608,11 +1630,11 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
+ * for CAP_SYSLOG would be meaningless.
+ */
+- if (in_irq() || in_serving_softirq() || in_nmi()) {
++ if (kptr_restrict && (in_irq() || in_serving_softirq() ||
++ in_nmi())) {
+ if (spec.field_width == -1)
+ spec.field_width = 2 * sizeof(void *);
+ return string(buf, end, "pK-error", spec);
+@@ -897,6 +922,19 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
+ ptr = NULL;
+ break;
+ }
++
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++ /* 'P' = approved pointers to copy to userland,
++ as in the /proc/kallsyms case, as we make it display nothing
++ for non-root users, and the real contents for root users
++ */
++ if (ptr > TASK_SIZE && *fmt != 'P' && is_usercopy_object(buf)) {
++ printk(KERN_ALERT "grsec: kernel infoleak detected! Please report this log to spender@grsecurity.net.\n");
++ dump_stack();
++ ptr = NULL;
++ }
++#endif
++
+ spec.flags |= SMALL;
+ if (spec.field_width == -1) {
+ spec.field_width = 2 * sizeof(void *);
+@@ -1608,11 +1646,11 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
typeof(type) value; \
if (sizeof(type) == 8) { \
args = PTR_ALIGN(args, sizeof(u32)); \
@@ -71412,7 +71717,7 @@ index 993599e..f1dbc14 100644
} \
args += sizeof(type); \
value; \
-@@ -1675,7 +1697,7 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
+@@ -1675,7 +1713,7 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
case FORMAT_TYPE_STR: {
const char *str_arg = args;
args += strlen(str_arg) + 1;
@@ -78727,6 +79032,27 @@ index 5e57347..3916042 100644
}
#endif
+diff --git a/net/rds/recv.c b/net/rds/recv.c
+index bc3f8cd..fc57d31 100644
+--- a/net/rds/recv.c
++++ b/net/rds/recv.c
+@@ -410,6 +410,8 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
+
+ rdsdebug("size %zu flags 0x%x timeo %ld\n", size, msg_flags, timeo);
+
++ msg->msg_namelen = 0;
++
+ if (msg_flags & MSG_OOB)
+ goto out;
+
+@@ -485,6 +487,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
+ sin->sin_port = inc->i_hdr.h_sport;
+ sin->sin_addr.s_addr = inc->i_saddr;
+ memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
++ msg->msg_namelen = sizeof(*sin);
+ }
+ break;
+ }
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index edac9ef..16bcb98 100644
--- a/net/rds/tcp.c
@@ -80276,10 +80602,10 @@ index 38f6617..e70b72b 100755
exuberant()
diff --git a/security/Kconfig b/security/Kconfig
-index 51bd5a0..f94ba7f 100644
+index 51bd5a0..7963a07 100644
--- a/security/Kconfig
+++ b/security/Kconfig
-@@ -4,6 +4,875 @@
+@@ -4,6 +4,876 @@
menu "Security options"
@@ -80311,6 +80637,7 @@ index 51bd5a0..f94ba7f 100644
+ bool "Grsecurity"
+ select CRYPTO
+ select CRYPTO_SHA256
++ select PROC_FS
+ select STOP_MACHINE
+ help
+ If you say Y here, you will be able to configure many features
@@ -81155,7 +81482,7 @@ index 51bd5a0..f94ba7f 100644
config KEYS
bool "Enable access key retention support"
help
-@@ -169,7 +1038,7 @@ config INTEL_TXT
+@@ -169,7 +1039,7 @@ config INTEL_TXT
config LSM_MMAP_MIN_ADDR
int "Low address space for LSM to protect from user allocation"
depends on SECURITY && SECURITY_SELINUX
diff --git a/3.4.6/0000_README b/3.4.6/0000_README
index 0a9e8d9..14b45fc 100644
--- a/3.4.6/0000_README
+++ b/3.4.6/0000_README
@@ -6,7 +6,7 @@ Patch: 1005_linux-3.4.6.patch
From: http://www.kernel.org
Desc: Linux 3.4.6
-Patch: 4420_grsecurity-2.9.1-3.4.6-201207281946.patch
+Patch: 4420_grsecurity-2.9.1-3.4.7-201207311909.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/3.4.6/4420_grsecurity-2.9.1-3.4.6-201207281946.patch b/3.4.6/4420_grsecurity-2.9.1-3.4.7-201207311909.patch
index 357f472..9da1ccd 100644
--- a/3.4.6/4420_grsecurity-2.9.1-3.4.6-201207281946.patch
+++ b/3.4.6/4420_grsecurity-2.9.1-3.4.7-201207311909.patch
@@ -235,8 +235,41 @@ index c1601e5..08557ce 100644
pcbit= [HW,ISDN]
pcd. [PARIDE]
+diff --git a/Documentation/sysctl/fs.txt b/Documentation/sysctl/fs.txt
+index 88fd7f5..b318a78 100644
+--- a/Documentation/sysctl/fs.txt
++++ b/Documentation/sysctl/fs.txt
+@@ -163,16 +163,22 @@ This value can be used to query and set the core dump mode for setuid
+ or otherwise protected/tainted binaries. The modes are
+
+ 0 - (default) - traditional behaviour. Any process which has changed
+- privilege levels or is execute only will not be dumped
++ privilege levels or is execute only will not be dumped.
+ 1 - (debug) - all processes dump core when possible. The core dump is
+ owned by the current user and no security is applied. This is
+ intended for system debugging situations only. Ptrace is unchecked.
++ This is insecure as it allows regular users to examine the memory
++ contents of privileged processes.
+ 2 - (suidsafe) - any binary which normally would not be dumped is dumped
+- readable by root only. This allows the end user to remove
+- such a dump but not access it directly. For security reasons
+- core dumps in this mode will not overwrite one another or
+- other files. This mode is appropriate when administrators are
+- attempting to debug problems in a normal environment.
++ anyway, but only if the "core_pattern" kernel sysctl is set to
++ either a pipe handler or a fully qualified path. (For more details
++ on this limitation, see CVE-2006-2451.) This mode is appropriate
++ when administrators are attempting to debug problems in a normal
++ environment, and either have a core dump pipe handler that knows
++ to treat privileged core dumps with care, or specific directory
++ defined for catching core dumps. If a core dump happens without
++ a pipe handler or fully qualifid path, a message will be emitted
++ to syslog warning about the lack of a correct setting.
+
+ ==============================================================
+
diff --git a/Makefile b/Makefile
-index 5d0edcb..f69ee4c 100644
+index e17a98c..e3197fa 100644
--- a/Makefile
+++ b/Makefile
@@ -245,8 +245,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
@@ -2907,7 +2940,7 @@ index 881d18b..cea38bc 100644
/*
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
-index 0d85d8e..ec71487 100644
+index abb13e8..cd2d702 100644
--- a/arch/mips/include/asm/thread_info.h
+++ b/arch/mips/include/asm/thread_info.h
@@ -123,6 +123,8 @@ register struct thread_info *__current_thread_info __asm__("$28");
@@ -20079,7 +20112,7 @@ index 255f58a..5e91150 100644
goto cannot_handle;
if ((segoffs >> 16) == BIOSSEG)
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
-index 0f703f1..9e15f64 100644
+index 0f703f1..3b426f3 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -26,6 +26,13 @@
@@ -20148,7 +20181,7 @@ index 0f703f1..9e15f64 100644
HEAD_TEXT
#ifdef CONFIG_X86_32
. = ALIGN(PAGE_SIZE);
-@@ -108,13 +128,47 @@ SECTIONS
+@@ -108,13 +128,48 @@ SECTIONS
IRQENTRY_TEXT
*(.fixup)
*(.gnu.warning)
@@ -20168,8 +20201,8 @@ index 0f703f1..9e15f64 100644
+ MODULES_EXEC_VADDR = .;
+ BYTE(0)
+ . += (CONFIG_PAX_KERNEXEC_MODULE_TEXT * 1024 * 1024);
-+ . = ALIGN(HPAGE_SIZE);
-+ MODULES_EXEC_END = . - 1;
++ . = ALIGN(HPAGE_SIZE) - 1;
++ MODULES_EXEC_END = .;
+#endif
+
+ } :module
@@ -20177,6 +20210,7 @@ index 0f703f1..9e15f64 100644
+
+ .text.end : AT(ADDR(.text.end) - LOAD_OFFSET) {
+ /* End of text section */
++ BYTE(0)
+ _etext = . - __KERNEL_TEXT_OFFSET;
+ }
+
@@ -20200,7 +20234,7 @@ index 0f703f1..9e15f64 100644
#if defined(CONFIG_DEBUG_RODATA)
/* .text should occupy whole number of pages */
-@@ -126,16 +180,20 @@ SECTIONS
+@@ -126,16 +181,20 @@ SECTIONS
/* Data */
.data : AT(ADDR(.data) - LOAD_OFFSET) {
@@ -20224,7 +20258,7 @@ index 0f703f1..9e15f64 100644
PAGE_ALIGNED_DATA(PAGE_SIZE)
-@@ -176,12 +234,19 @@ SECTIONS
+@@ -176,12 +235,19 @@ SECTIONS
#endif /* CONFIG_X86_64 */
/* Init code and data - will be freed after init */
@@ -20247,7 +20281,7 @@ index 0f703f1..9e15f64 100644
/*
* percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the
* output PHDR, so the next output section - .init.text - should
-@@ -190,12 +255,27 @@ SECTIONS
+@@ -190,12 +256,27 @@ SECTIONS
PERCPU_VADDR(INTERNODE_CACHE_BYTES, 0, :percpu)
#endif
@@ -20280,7 +20314,7 @@ index 0f703f1..9e15f64 100644
/*
* Code and data for a variety of lowlevel trampolines, to be
-@@ -269,19 +349,12 @@ SECTIONS
+@@ -269,19 +350,12 @@ SECTIONS
}
. = ALIGN(8);
@@ -20301,7 +20335,7 @@ index 0f703f1..9e15f64 100644
PERCPU_SECTION(INTERNODE_CACHE_BYTES)
#endif
-@@ -300,16 +373,10 @@ SECTIONS
+@@ -300,16 +374,10 @@ SECTIONS
.smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
__smp_locks = .;
*(.smp_locks)
@@ -20319,7 +20353,7 @@ index 0f703f1..9e15f64 100644
/* BSS */
. = ALIGN(PAGE_SIZE);
.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
-@@ -325,6 +392,7 @@ SECTIONS
+@@ -325,6 +393,7 @@ SECTIONS
__brk_base = .;
. += 64 * 1024; /* 64k alignment slop space */
*(.brk_reservation) /* areas brk users have reserved */
@@ -20327,7 +20361,7 @@ index 0f703f1..9e15f64 100644
__brk_limit = .;
}
-@@ -351,13 +419,12 @@ SECTIONS
+@@ -351,13 +420,12 @@ SECTIONS
* for the boot processor.
*/
#define INIT_PER_CPU(x) init_per_cpu__##x = x + __per_cpu_load
@@ -26764,7 +26798,7 @@ index 218cdb1..fd55c08 100644
syscall_init(); /* This sets MSR_*STAR and related */
#endif
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
-index b685296..e00eb65 100644
+index b685296..4ac6aaa 100644
--- a/arch/x86/tools/relocs.c
+++ b/arch/x86/tools/relocs.c
@@ -12,10 +12,13 @@
@@ -26857,7 +26891,7 @@ index b685296..e00eb65 100644
}
+ base = 0;
+
-+#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
++#ifdef CONFIG_X86_32
+ for (j = 0; j < ehdr.e_phnum; j++) {
+ if (phdr[j].p_type != PT_LOAD )
+ continue;
@@ -26934,7 +26968,7 @@ index b685296..e00eb65 100644
+
+#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
+ /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
-+ if (!strcmp(sec_name(sym->st_shndx), ".module.text") && !strcmp(sym_name(sym_strtab, sym), "_etext"))
++ if (!strcmp(sec_name(sym->st_shndx), ".text.end") && !strcmp(sym_name(sym_strtab, sym), "_etext"))
+ continue;
+ if (!strcmp(sec_name(sym->st_shndx), ".init.text"))
+ continue;
@@ -31272,10 +31306,10 @@ index 8a8725c..afed796 100644
marker = list_first_entry(&queue->head,
struct vmw_marker, head);
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
-index 054677b..741672a 100644
+index 973c238..981f5ed 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
-@@ -2070,7 +2070,7 @@ static bool hid_ignore(struct hid_device *hdev)
+@@ -2071,7 +2071,7 @@ static bool hid_ignore(struct hid_device *hdev)
int hid_add_device(struct hid_device *hdev)
{
@@ -31284,7 +31318,7 @@ index 054677b..741672a 100644
int ret;
if (WARN_ON(hdev->status & HID_STAT_ADDED))
-@@ -2085,7 +2085,7 @@ int hid_add_device(struct hid_device *hdev)
+@@ -2086,7 +2086,7 @@ int hid_add_device(struct hid_device *hdev)
/* XXX hack, any other cleaner solution after the driver core
* is converted to allow more than 20 bytes as the device name? */
dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus,
@@ -33142,7 +33176,7 @@ index a1a3e6d..1918bfc 100644
DMWARN("name not supplied when creating device");
return -EINVAL;
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
-index d039de8..0cf5b87 100644
+index b58b7a3..8018b19 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -40,7 +40,7 @@ enum dm_raid1_error {
@@ -33208,7 +33242,7 @@ index d039de8..0cf5b87 100644
ms->mirror[mirror].error_type = 0;
ms->mirror[mirror].offset = offset;
-@@ -1351,7 +1351,7 @@ static void mirror_resume(struct dm_target *ti)
+@@ -1352,7 +1352,7 @@ static void mirror_resume(struct dm_target *ti)
*/
static char device_status_char(struct mirror *m)
{
@@ -33353,7 +33387,7 @@ index e24143c..ce2f21a1 100644
void dm_uevent_add(struct mapped_device *md, struct list_head *elist)
diff --git a/drivers/md/md.c b/drivers/md/md.c
-index 2b30ffd..362b519 100644
+index 9ee8ce3..362b519 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -277,10 +277,10 @@ EXPORT_SYMBOL_GPL(md_trim_bio);
@@ -33425,125 +33459,7 @@ index 2b30ffd..362b519 100644
INIT_LIST_HEAD(&rdev->same_set);
init_waitqueue_head(&rdev->blocked_wait);
-@@ -3744,8 +3744,8 @@ array_state_show(struct mddev *mddev, char *page)
- return sprintf(page, "%s\n", array_states[st]);
- }
-
--static int do_md_stop(struct mddev * mddev, int ro, int is_open);
--static int md_set_readonly(struct mddev * mddev, int is_open);
-+static int do_md_stop(struct mddev * mddev, int ro, struct block_device *bdev);
-+static int md_set_readonly(struct mddev * mddev, struct block_device *bdev);
- static int do_md_run(struct mddev * mddev);
- static int restart_array(struct mddev *mddev);
-
-@@ -3761,14 +3761,14 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
- /* stopping an active array */
- if (atomic_read(&mddev->openers) > 0)
- return -EBUSY;
-- err = do_md_stop(mddev, 0, 0);
-+ err = do_md_stop(mddev, 0, NULL);
- break;
- case inactive:
- /* stopping an active array */
- if (mddev->pers) {
- if (atomic_read(&mddev->openers) > 0)
- return -EBUSY;
-- err = do_md_stop(mddev, 2, 0);
-+ err = do_md_stop(mddev, 2, NULL);
- } else
- err = 0; /* already inactive */
- break;
-@@ -3776,7 +3776,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
- break; /* not supported yet */
- case readonly:
- if (mddev->pers)
-- err = md_set_readonly(mddev, 0);
-+ err = md_set_readonly(mddev, NULL);
- else {
- mddev->ro = 1;
- set_disk_ro(mddev->gendisk, 1);
-@@ -3786,7 +3786,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len)
- case read_auto:
- if (mddev->pers) {
- if (mddev->ro == 0)
-- err = md_set_readonly(mddev, 0);
-+ err = md_set_readonly(mddev, NULL);
- else if (mddev->ro == 1)
- err = restart_array(mddev);
- if (err == 0) {
-@@ -5124,15 +5124,17 @@ void md_stop(struct mddev *mddev)
- }
- EXPORT_SYMBOL_GPL(md_stop);
-
--static int md_set_readonly(struct mddev *mddev, int is_open)
-+static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
- {
- int err = 0;
- mutex_lock(&mddev->open_mutex);
-- if (atomic_read(&mddev->openers) > is_open) {
-+ if (atomic_read(&mddev->openers) > !!bdev) {
- printk("md: %s still in use.\n",mdname(mddev));
- err = -EBUSY;
- goto out;
- }
-+ if (bdev)
-+ sync_blockdev(bdev);
- if (mddev->pers) {
- __md_stop_writes(mddev);
-
-@@ -5154,18 +5156,26 @@ out:
- * 0 - completely stop and dis-assemble array
- * 2 - stop but do not disassemble array
- */
--static int do_md_stop(struct mddev * mddev, int mode, int is_open)
-+static int do_md_stop(struct mddev * mddev, int mode,
-+ struct block_device *bdev)
- {
- struct gendisk *disk = mddev->gendisk;
- struct md_rdev *rdev;
-
- mutex_lock(&mddev->open_mutex);
-- if (atomic_read(&mddev->openers) > is_open ||
-+ if (atomic_read(&mddev->openers) > !!bdev ||
- mddev->sysfs_active) {
- printk("md: %s still in use.\n",mdname(mddev));
- mutex_unlock(&mddev->open_mutex);
- return -EBUSY;
- }
-+ if (bdev)
-+ /* It is possible IO was issued on some other
-+ * open file which was closed before we took ->open_mutex.
-+ * As that was not the last close __blkdev_put will not
-+ * have called sync_blockdev, so we must.
-+ */
-+ sync_blockdev(bdev);
-
- if (mddev->pers) {
- if (mddev->ro)
-@@ -5239,7 +5249,7 @@ static void autorun_array(struct mddev *mddev)
- err = do_md_run(mddev);
- if (err) {
- printk(KERN_WARNING "md: do_md_run() returned %d\n", err);
-- do_md_stop(mddev, 0, 0);
-+ do_md_stop(mddev, 0, NULL);
- }
- }
-
-@@ -6237,11 +6247,11 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
- goto done_unlock;
-
- case STOP_ARRAY:
-- err = do_md_stop(mddev, 0, 1);
-+ err = do_md_stop(mddev, 0, bdev);
- goto done_unlock;
-
- case STOP_ARRAY_RO:
-- err = md_set_readonly(mddev, 1);
-+ err = md_set_readonly(mddev, bdev);
- goto done_unlock;
-
- case BLKROSET:
-@@ -6738,7 +6748,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
+@@ -6748,7 +6748,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
spin_unlock(&pers_lock);
seq_printf(seq, "\n");
@@ -33552,7 +33468,7 @@ index 2b30ffd..362b519 100644
return 0;
}
if (v == (void*)2) {
-@@ -6841,7 +6851,7 @@ static int md_seq_open(struct inode *inode, struct file *file)
+@@ -6851,7 +6851,7 @@ static int md_seq_open(struct inode *inode, struct file *file)
return error;
seq = file->private_data;
@@ -33561,7 +33477,7 @@ index 2b30ffd..362b519 100644
return error;
}
-@@ -6855,7 +6865,7 @@ static unsigned int mdstat_poll(struct file *filp, poll_table *wait)
+@@ -6865,7 +6865,7 @@ static unsigned int mdstat_poll(struct file *filp, poll_table *wait)
/* always allow read */
mask = POLLIN | POLLRDNORM;
@@ -33570,7 +33486,7 @@ index 2b30ffd..362b519 100644
mask |= POLLERR | POLLPRI;
return mask;
}
-@@ -6899,7 +6909,7 @@ static int is_mddev_idle(struct mddev *mddev, int init)
+@@ -6909,7 +6909,7 @@ static int is_mddev_idle(struct mddev *mddev, int init)
struct gendisk *disk = rdev->bdev->bd_contains->bd_disk;
curr_events = (int)part_stat_read(&disk->part0, sectors[0]) +
(int)part_stat_read(&disk->part0, sectors[1]) -
@@ -33660,7 +33576,7 @@ index 1cbfc6b..56e1dbb 100644
/*----------------------------------------------------------------*/
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
-index d1f74ab..d1b24fd 100644
+index d7add9d..68e3dde 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1688,7 +1688,7 @@ static int fix_sync_read_error(struct r1bio *r1_bio)
@@ -33672,7 +33588,7 @@ index d1f74ab..d1b24fd 100644
}
sectors -= s;
sect += s;
-@@ -1902,7 +1902,7 @@ static void fix_read_error(struct r1conf *conf, int read_disk,
+@@ -1908,7 +1908,7 @@ static void fix_read_error(struct r1conf *conf, int read_disk,
test_bit(In_sync, &rdev->flags)) {
if (r1_sync_page_io(rdev, sect, s,
conf->tmppage, READ)) {
@@ -34311,6 +34227,19 @@ index 2b1482a..5d33616 100644
union axis_conversion ac; /* hw -> logical axis */
int mapped_btns[3];
+diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c
+index 28adefe..08aad69 100644
+--- a/drivers/misc/lkdtm.c
++++ b/drivers/misc/lkdtm.c
+@@ -477,6 +477,8 @@ static ssize_t lkdtm_debugfs_read(struct file *f, char __user *user_buf,
+ int i, n, out;
+
+ buf = (char *)__get_free_page(GFP_KERNEL);
++ if (buf == NULL)
++ return -ENOMEM;
+
+ n = snprintf(buf, PAGE_SIZE, "Available crash types:\n");
+ for (i = 0; i < ARRAY_SIZE(cp_type); i++)
diff --git a/drivers/misc/sgi-gru/gruhandles.c b/drivers/misc/sgi-gru/gruhandles.c
index 2f30bad..c4c13d0 100644
--- a/drivers/misc/sgi-gru/gruhandles.c
@@ -34581,6 +34510,22 @@ index 8d082b4..aa749ae 100644
/*
* Timer function to enforce the timelimit on the partition disengage.
+diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c
+index 2b62232..acfaeeb 100644
+--- a/drivers/misc/ti-st/st_core.c
++++ b/drivers/misc/ti-st/st_core.c
+@@ -349,6 +349,11 @@ void st_int_recv(void *disc_data,
+ st_gdata->rx_skb = alloc_skb(
+ st_gdata->list[type]->max_frame_size,
+ GFP_ATOMIC);
++ if (st_gdata->rx_skb == NULL) {
++ pr_err("out of memory: dropping\n");
++ goto done;
++ }
++
+ skb_reserve(st_gdata->rx_skb,
+ st_gdata->list[type]->reserve);
+ /* next 2 required for BT only */
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 69ef0be..f3ef91e 100644
--- a/drivers/mmc/host/sdhci-pci.c
@@ -37585,51 +37530,6 @@ index 0d4aa82..f7832d4 100644
extern void tmem_register_hostops(struct tmem_hostops *m);
/* core tmem accessor functions */
-diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c
-index 30a6770..fa323f8 100644
---- a/drivers/target/target_core_cdb.c
-+++ b/drivers/target/target_core_cdb.c
-@@ -1107,7 +1107,7 @@ int target_emulate_write_same(struct se_task *task)
- if (num_blocks != 0)
- range = num_blocks;
- else
-- range = (dev->transport->get_blocks(dev) - lba);
-+ range = (dev->transport->get_blocks(dev) - lba) + 1;
-
- pr_debug("WRITE_SAME UNMAP: LBA: %llu Range: %llu\n",
- (unsigned long long)lba, (unsigned long long)range);
-diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
-index c3148b1..89d10e6 100644
---- a/drivers/target/target_core_pr.c
-+++ b/drivers/target/target_core_pr.c
-@@ -2038,7 +2038,7 @@ static int __core_scsi3_write_aptpl_to_file(
- if (IS_ERR(file) || !file || !file->f_dentry) {
- pr_err("filp_open(%s) for APTPL metadata"
- " failed\n", path);
-- return (PTR_ERR(file) < 0 ? PTR_ERR(file) : -ENOENT);
-+ return IS_ERR(file) ? PTR_ERR(file) : -ENOENT;
- }
-
- iov[0].iov_base = &buf[0];
-@@ -3826,7 +3826,7 @@ int target_scsi3_emulate_pr_out(struct se_task *task)
- " SPC-2 reservation is held, returning"
- " RESERVATION_CONFLICT\n");
- cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT;
-- ret = EINVAL;
-+ ret = -EINVAL;
- goto out;
- }
-
-@@ -3836,7 +3836,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task)
- */
- if (!cmd->se_sess) {
- cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
-- return -EINVAL;
-+ ret = -EINVAL;
-+ goto out;
- }
-
- if (cmd->data_length < 24) {
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c
index f015839..b15dfc4 100644
--- a/drivers/target/target_core_tmr.c
@@ -37686,19 +37586,6 @@ index 443704f..92d3517 100644
cmd->t_task_list_num)
cmd->transport_state |= CMD_T_SENT;
-diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c
-index a375f25..da90f64 100644
---- a/drivers/target/tcm_fc/tfc_cmd.c
-+++ b/drivers/target/tcm_fc/tfc_cmd.c
-@@ -240,6 +240,8 @@ u32 ft_get_task_tag(struct se_cmd *se_cmd)
- {
- struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd);
-
-+ if (cmd->aborted)
-+ return ~0;
- return fc_seq_exch(cmd->seq)->rxid;
- }
-
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c
index 3436436..772237b 100644
--- a/drivers/tty/hvc/hvcs.c
@@ -43719,7 +43606,7 @@ index b2a34a1..162fa69 100644
return rc;
}
diff --git a/fs/exec.c b/fs/exec.c
-index 29e5f84..8bfc7cb 100644
+index 29e5f84..7acfbdb 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -55,6 +55,15 @@
@@ -44430,6 +44317,36 @@ index 29e5f84..8bfc7cb 100644
static int zap_process(struct task_struct *start, int exit_code)
{
struct task_struct *t;
+@@ -1980,17 +2356,17 @@ static void coredump_finish(struct mm_struct *mm)
+ void set_dumpable(struct mm_struct *mm, int value)
+ {
+ switch (value) {
+- case 0:
++ case SUID_DUMPABLE_DISABLED:
+ clear_bit(MMF_DUMPABLE, &mm->flags);
+ smp_wmb();
+ clear_bit(MMF_DUMP_SECURELY, &mm->flags);
+ break;
+- case 1:
++ case SUID_DUMPABLE_ENABLED:
+ set_bit(MMF_DUMPABLE, &mm->flags);
+ smp_wmb();
+ clear_bit(MMF_DUMP_SECURELY, &mm->flags);
+ break;
+- case 2:
++ case SUID_DUMPABLE_SAFE:
+ set_bit(MMF_DUMP_SECURELY, &mm->flags);
+ smp_wmb();
+ set_bit(MMF_DUMPABLE, &mm->flags);
+@@ -2003,7 +2379,7 @@ static int __get_dumpable(unsigned long mm_flags)
+ int ret;
+
+ ret = mm_flags & MMF_DUMPABLE_MASK;
+- return (ret >= 2) ? 2 : ret;
++ return (ret > SUID_DUMPABLE_ENABLED) ? SUID_DUMPABLE_SAFE : ret;
+ }
+
+ int get_dumpable(struct mm_struct *mm)
@@ -2018,17 +2394,17 @@ static void wait_for_dump_helpers(struct file *file)
pipe = file->f_path.dentry->d_inode->i_pipe;
@@ -44453,16 +44370,17 @@ index 29e5f84..8bfc7cb 100644
pipe_unlock(pipe);
}
-@@ -2089,7 +2465,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2089,7 +2465,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
int retval = 0;
int flag = 0;
int ispipe;
- static atomic_t core_dump_count = ATOMIC_INIT(0);
++ bool need_nonrelative = false;
+ static atomic_unchecked_t core_dump_count = ATOMIC_INIT(0);
struct coredump_params cprm = {
.signr = signr,
.regs = regs,
-@@ -2104,6 +2480,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2104,6 +2481,9 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
audit_core_dumps(signr);
@@ -44472,7 +44390,28 @@ index 29e5f84..8bfc7cb 100644
binfmt = mm->binfmt;
if (!binfmt || !binfmt->core_dump)
goto fail;
-@@ -2171,7 +2550,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2114,14 +2494,16 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+ if (!cred)
+ goto fail;
+ /*
+- * We cannot trust fsuid as being the "true" uid of the
+- * process nor do we know its entire history. We only know it
+- * was tainted so we dump it as root in mode 2.
++ * We cannot trust fsuid as being the "true" uid of the process
++ * nor do we know its entire history. We only know it was tainted
++ * so we dump it as root in mode 2, and only into a controlled
++ * environment (pipe handler or fully qualified path).
+ */
+- if (__get_dumpable(cprm.mm_flags) == 2) {
++ if (__get_dumpable(cprm.mm_flags) == SUID_DUMPABLE_SAFE) {
+ /* Setuid core dump mode */
+ flag = O_EXCL; /* Stop rewrite attacks */
+ cred->fsuid = 0; /* Dump root private */
++ need_nonrelative = true;
+ }
+
+ retval = coredump_wait(exit_code, &core_state);
+@@ -2171,7 +2553,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
}
cprm.limit = RLIM_INFINITY;
@@ -44481,7 +44420,7 @@ index 29e5f84..8bfc7cb 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);
-@@ -2198,6 +2577,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
+@@ -2198,9 +2580,19 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
} else {
struct inode *inode;
@@ -44490,7 +44429,18 @@ index 29e5f84..8bfc7cb 100644
if (cprm.limit < binfmt->min_coredump)
goto fail_unlock;
-@@ -2241,7 +2622,7 @@ close_fail:
++ if (need_nonrelative && cn.corename[0] != '/') {
++ printk(KERN_WARNING "Pid %d(%s) can only dump core "\
++ "to fully qualified path!\n",
++ task_tgid_vnr(current), current->comm);
++ printk(KERN_WARNING "Skipping core dump\n");
++ goto fail_unlock;
++ }
++
+ cprm.file = filp_open(cn.corename,
+ O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag,
+ 0600);
+@@ -2241,7 +2633,7 @@ close_fail:
filp_close(cprm.file, NULL);
fail_dropcount:
if (ispipe)
@@ -44499,7 +44449,7 @@ index 29e5f84..8bfc7cb 100644
fail_unlock:
kfree(cn.corename);
fail_corename:
-@@ -2260,7 +2641,7 @@ fail:
+@@ -2260,7 +2652,7 @@ fail:
*/
int dump_write(struct file *file, const void *addr, int nr)
{
@@ -44587,18 +44537,6 @@ index 0e01e90..ae2bd5e 100644
atomic_t s_lock_busy;
/* locality groups */
-diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
-index 1365903..9727522 100644
---- a/fs/ext4/ioctl.c
-+++ b/fs/ext4/ioctl.c
-@@ -261,7 +261,6 @@ group_extend_out:
- err = ext4_move_extents(filp, donor_filp, me.orig_start,
- me.donor_start, me.len, &me.moved_len);
- mnt_drop_write_file(filp);
-- mnt_drop_write(filp->f_path.mnt);
-
- if (copy_to_user((struct move_extent __user *)arg,
- &me, sizeof(me)))
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 6b0a57e..1955a44 100644
--- a/fs/ext4/mballoc.c
@@ -63021,7 +62959,7 @@ index fd07c45..4676b8e 100644
static inline void anon_vma_merge(struct vm_area_struct *vma,
struct vm_area_struct *next)
diff --git a/include/linux/sched.h b/include/linux/sched.h
-index 7b06169..c92adbe 100644
+index 7b06169..eb46ae3 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -100,6 +100,7 @@ struct bio_list;
@@ -63046,7 +62984,19 @@ index 7b06169..c92adbe 100644
extern void arch_pick_mmap_layout(struct mm_struct *mm);
extern unsigned long
arch_get_unmapped_area(struct file *, unsigned long, unsigned long,
-@@ -643,6 +647,17 @@ struct signal_struct {
+@@ -404,6 +408,11 @@ static inline void arch_pick_mmap_layout(struct mm_struct *mm) {}
+ extern void set_dumpable(struct mm_struct *mm, int value);
+ extern int get_dumpable(struct mm_struct *mm);
+
++/* get/set_dumpable() values */
++#define SUID_DUMPABLE_DISABLED 0
++#define SUID_DUMPABLE_ENABLED 1
++#define SUID_DUMPABLE_SAFE 2
++
+ /* mm flags */
+ /* dumpable bits */
+ #define MMF_DUMPABLE 0 /* core dump is permitted */
+@@ -643,6 +652,17 @@ struct signal_struct {
#ifdef CONFIG_TASKSTATS
struct taskstats *stats;
#endif
@@ -63064,7 +63014,7 @@ index 7b06169..c92adbe 100644
#ifdef CONFIG_AUDIT
unsigned audit_tty;
struct tty_audit_buf *tty_audit_buf;
-@@ -726,6 +741,11 @@ struct user_struct {
+@@ -726,6 +746,11 @@ struct user_struct {
struct key *session_keyring; /* UID's default session keyring */
#endif
@@ -63076,7 +63026,7 @@ index 7b06169..c92adbe 100644
/* Hash table maintenance information */
struct hlist_node uidhash_node;
uid_t uid;
-@@ -1386,8 +1406,8 @@ struct task_struct {
+@@ -1386,8 +1411,8 @@ struct task_struct {
struct list_head thread_group;
struct completion *vfork_done; /* for vfork() */
@@ -63087,7 +63037,7 @@ index 7b06169..c92adbe 100644
cputime_t utime, stime, utimescaled, stimescaled;
cputime_t gtime;
-@@ -1403,13 +1423,6 @@ struct task_struct {
+@@ -1403,13 +1428,6 @@ struct task_struct {
struct task_cputime cputime_expires;
struct list_head cpu_timers[3];
@@ -63101,7 +63051,7 @@ index 7b06169..c92adbe 100644
char comm[TASK_COMM_LEN]; /* executable name excluding path
- access with [gs]et_task_comm (which lock
it with task_lock())
-@@ -1426,8 +1439,16 @@ struct task_struct {
+@@ -1426,8 +1444,16 @@ struct task_struct {
#endif
/* CPU-specific state of this task */
struct thread_struct thread;
@@ -63118,7 +63068,7 @@ index 7b06169..c92adbe 100644
/* open file information */
struct files_struct *files;
/* namespaces */
-@@ -1469,6 +1490,11 @@ struct task_struct {
+@@ -1469,6 +1495,11 @@ struct task_struct {
struct rt_mutex_waiter *pi_blocked_on;
#endif
@@ -63130,7 +63080,7 @@ index 7b06169..c92adbe 100644
#ifdef CONFIG_DEBUG_MUTEXES
/* mutex deadlock detection */
struct mutex_waiter *blocked_on;
-@@ -1585,6 +1611,27 @@ struct task_struct {
+@@ -1585,6 +1616,27 @@ struct task_struct {
unsigned long default_timer_slack_ns;
struct list_head *scm_work_list;
@@ -63158,7 +63108,7 @@ index 7b06169..c92adbe 100644
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
/* Index of current stored address in ret_stack */
int curr_ret_stack;
-@@ -1619,6 +1666,51 @@ struct task_struct {
+@@ -1619,6 +1671,51 @@ struct task_struct {
#endif
};
@@ -63210,7 +63160,7 @@ index 7b06169..c92adbe 100644
/* Future-safe accessor for struct task_struct's cpus_allowed. */
#define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed)
-@@ -2146,7 +2238,9 @@ void yield(void);
+@@ -2146,7 +2243,9 @@ void yield(void);
extern struct exec_domain default_exec_domain;
union thread_union {
@@ -63220,7 +63170,7 @@ index 7b06169..c92adbe 100644
unsigned long stack[THREAD_SIZE/sizeof(long)];
};
-@@ -2179,6 +2273,7 @@ extern struct pid_namespace init_pid_ns;
+@@ -2179,6 +2278,7 @@ extern struct pid_namespace init_pid_ns;
*/
extern struct task_struct *find_task_by_vpid(pid_t nr);
@@ -63228,7 +63178,7 @@ index 7b06169..c92adbe 100644
extern struct task_struct *find_task_by_pid_ns(pid_t nr,
struct pid_namespace *ns);
-@@ -2322,7 +2417,7 @@ extern void __cleanup_sighand(struct sighand_struct *);
+@@ -2322,7 +2422,7 @@ extern void __cleanup_sighand(struct sighand_struct *);
extern void exit_itimers(struct signal_struct *);
extern void flush_itimer_signals(void);
@@ -63237,7 +63187,7 @@ index 7b06169..c92adbe 100644
extern void daemonize(const char *, ...);
extern int allow_signal(int);
-@@ -2523,9 +2618,9 @@ static inline unsigned long *end_of_stack(struct task_struct *p)
+@@ -2523,9 +2623,9 @@ static inline unsigned long *end_of_stack(struct task_struct *p)
#endif
@@ -67683,10 +67633,25 @@ index a307cc9..27fd2e9 100644
/* set it to 0 if there are no waiters left: */
diff --git a/kernel/panic.c b/kernel/panic.c
-index 9ed023b..e49543e 100644
+index 9ed023b..4846159 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
-@@ -402,7 +402,7 @@ static void warn_slowpath_common(const char *file, int line, void *caller,
+@@ -75,6 +75,14 @@ void panic(const char *fmt, ...)
+ int state = 0;
+
+ /*
++ * Disable local interrupts. This will prevent panic_smp_self_stop
++ * from deadlocking the first cpu that invokes the panic, since
++ * there is nothing to prevent an interrupt handler (that runs
++ * after the panic_lock is acquired) from invoking panic again.
++ */
++ local_irq_disable();
++
++ /*
+ * It's possible to come here directly from a panic-assertion and
+ * not have preempt disabled. Some functions called from here want
+ * preempt to be disabled. No point enabling it later though...
+@@ -402,7 +410,7 @@ static void warn_slowpath_common(const char *file, int line, void *caller,
const char *board;
printk(KERN_WARNING "------------[ cut here ]------------\n");
@@ -67695,7 +67660,7 @@ index 9ed023b..e49543e 100644
board = dmi_get_system_info(DMI_PRODUCT_NAME);
if (board)
printk(KERN_WARNING "Hardware name: %s\n", board);
-@@ -457,7 +457,8 @@ EXPORT_SYMBOL(warn_slowpath_null);
+@@ -457,7 +465,8 @@ EXPORT_SYMBOL(warn_slowpath_null);
*/
void __stack_chk_fail(void)
{
@@ -69107,7 +69072,7 @@ index e7006eb..8fb7c51 100644
break;
}
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
-index 4ab1187..0b75ced 100644
+index 4ab1187..33f4f2b 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -91,7 +91,6 @@
@@ -69118,7 +69083,7 @@ index 4ab1187..0b75ced 100644
/* External variables not in a header file. */
extern int sysctl_overcommit_memory;
extern int sysctl_overcommit_ratio;
-@@ -169,10 +168,8 @@ static int proc_taint(struct ctl_table *table, int write,
+@@ -169,10 +168,13 @@ static int proc_taint(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos);
#endif
@@ -69126,10 +69091,15 @@ index 4ab1187..0b75ced 100644
static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos);
-#endif
++
++static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write,
++ void __user *buffer, size_t *lenp, loff_t *ppos);
++static int proc_dostring_coredump(struct ctl_table *table, int write,
++ void __user *buffer, size_t *lenp, loff_t *ppos);
#ifdef CONFIG_MAGIC_SYSRQ
/* Note: sysrq code uses it's own private copy */
-@@ -196,6 +193,8 @@ static int sysrq_sysctl_handler(ctl_table *table, int write,
+@@ -196,6 +198,8 @@ static int sysrq_sysctl_handler(ctl_table *table, int write,
#endif
@@ -69138,7 +69108,7 @@ index 4ab1187..0b75ced 100644
static struct ctl_table kern_table[];
static struct ctl_table vm_table[];
static struct ctl_table fs_table[];
-@@ -210,6 +209,20 @@ extern struct ctl_table epoll_table[];
+@@ -210,6 +214,20 @@ extern struct ctl_table epoll_table[];
int sysctl_legacy_va_layout;
#endif
@@ -69159,7 +69129,7 @@ index 4ab1187..0b75ced 100644
/* The default sysctl tables: */
static struct ctl_table sysctl_base_table[] = {
-@@ -256,6 +269,22 @@ static int max_extfrag_threshold = 1000;
+@@ -256,6 +274,22 @@ static int max_extfrag_threshold = 1000;
#endif
static struct ctl_table kern_table[] = {
@@ -69182,7 +69152,16 @@ index 4ab1187..0b75ced 100644
{
.procname = "sched_child_runs_first",
.data = &sysctl_sched_child_runs_first,
-@@ -540,7 +569,7 @@ static struct ctl_table kern_table[] = {
+@@ -410,7 +444,7 @@ static struct ctl_table kern_table[] = {
+ .data = core_pattern,
+ .maxlen = CORENAME_MAX_SIZE,
+ .mode = 0644,
+- .proc_handler = proc_dostring,
++ .proc_handler = proc_dostring_coredump,
+ },
+ {
+ .procname = "core_pipe_limit",
+@@ -540,7 +574,7 @@ static struct ctl_table kern_table[] = {
.data = &modprobe_path,
.maxlen = KMOD_PATH_LEN,
.mode = 0644,
@@ -69191,7 +69170,7 @@ index 4ab1187..0b75ced 100644
},
{
.procname = "modules_disabled",
-@@ -707,16 +736,20 @@ static struct ctl_table kern_table[] = {
+@@ -707,16 +741,20 @@ static struct ctl_table kern_table[] = {
.extra1 = &zero,
.extra2 = &one,
},
@@ -69213,7 +69192,7 @@ index 4ab1187..0b75ced 100644
{
.procname = "ngroups_max",
.data = &ngroups_max,
-@@ -1215,6 +1248,13 @@ static struct ctl_table vm_table[] = {
+@@ -1215,6 +1253,13 @@ static struct ctl_table vm_table[] = {
.proc_handler = proc_dointvec_minmax,
.extra1 = &zero,
},
@@ -69227,7 +69206,16 @@ index 4ab1187..0b75ced 100644
#else
{
.procname = "nr_trim_pages",
-@@ -1645,6 +1685,16 @@ int proc_dostring(struct ctl_table *table, int write,
+@@ -1498,7 +1543,7 @@ static struct ctl_table fs_table[] = {
+ .data = &suid_dumpable,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+- .proc_handler = proc_dointvec_minmax,
++ .proc_handler = proc_dointvec_minmax_coredump,
+ .extra1 = &zero,
+ .extra2 = &two,
+ },
+@@ -1645,6 +1690,16 @@ int proc_dostring(struct ctl_table *table, int write,
buffer, lenp, ppos);
}
@@ -69244,7 +69232,7 @@ index 4ab1187..0b75ced 100644
static size_t proc_skip_spaces(char **buf)
{
size_t ret;
-@@ -1750,6 +1800,8 @@ static int proc_put_long(void __user **buf, size_t *size, unsigned long val,
+@@ -1750,6 +1805,8 @@ static int proc_put_long(void __user **buf, size_t *size, unsigned long val,
len = strlen(tmp);
if (len > *size)
len = *size;
@@ -69253,7 +69241,7 @@ index 4ab1187..0b75ced 100644
if (copy_to_user(*buf, tmp, len))
return -EFAULT;
*size -= len;
-@@ -1942,7 +1994,6 @@ static int proc_taint(struct ctl_table *table, int write,
+@@ -1942,7 +1999,6 @@ static int proc_taint(struct ctl_table *table, int write,
return err;
}
@@ -69261,7 +69249,7 @@ index 4ab1187..0b75ced 100644
static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
-@@ -1951,7 +2002,6 @@ static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
+@@ -1951,7 +2007,6 @@ static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
}
@@ -69269,7 +69257,42 @@ index 4ab1187..0b75ced 100644
struct do_proc_dointvec_minmax_conv_param {
int *min;
-@@ -2066,8 +2116,11 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
+@@ -2009,6 +2064,34 @@ int proc_dointvec_minmax(struct ctl_table *table, int write,
+ do_proc_dointvec_minmax_conv, &param);
+ }
+
++static void validate_coredump_safety(void)
++{
++ if (suid_dumpable == SUID_DUMPABLE_SAFE &&
++ core_pattern[0] != '/' && core_pattern[0] != '|') {
++ printk(KERN_WARNING "Unsafe core_pattern used with "\
++ "suid_dumpable=2. Pipe handler or fully qualified "\
++ "core dump path required.\n");
++ }
++}
++
++static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write,
++ void __user *buffer, size_t *lenp, loff_t *ppos)
++{
++ int error = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
++ if (!error)
++ validate_coredump_safety();
++ return error;
++}
++
++static int proc_dostring_coredump(struct ctl_table *table, int write,
++ void __user *buffer, size_t *lenp, loff_t *ppos)
++{
++ int error = proc_dostring(table, write, buffer, lenp, ppos);
++ if (!error)
++ validate_coredump_safety();
++ return error;
++}
++
+ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write,
+ void __user *buffer,
+ size_t *lenp, loff_t *ppos,
+@@ -2066,8 +2149,11 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
*i = val;
} else {
val = convdiv * (*i) / convmul;
@@ -69282,7 +69305,7 @@ index 4ab1187..0b75ced 100644
err = proc_put_long(&buffer, &left, val, false);
if (err)
break;
-@@ -2459,6 +2512,12 @@ int proc_dostring(struct ctl_table *table, int write,
+@@ -2459,6 +2545,12 @@ int proc_dostring(struct ctl_table *table, int write,
return -ENOSYS;
}
@@ -69295,7 +69318,7 @@ index 4ab1187..0b75ced 100644
int proc_dointvec(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
-@@ -2515,5 +2574,6 @@ EXPORT_SYMBOL(proc_dointvec_minmax);
+@@ -2515,5 +2607,6 @@ EXPORT_SYMBOL(proc_dointvec_minmax);
EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
EXPORT_SYMBOL(proc_dostring);
@@ -70067,7 +70090,7 @@ index 3ac50dc..240bb7e 100644
static inline void *ptr_to_indirect(void *ptr)
{
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
-index abbabec..d5eba6c 100644
+index abbabec..6779788 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -16,6 +16,9 @@
@@ -70110,21 +70133,8 @@ index abbabec..d5eba6c 100644
* - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref]
* - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201]
* - 'M' For a 6-byte MAC address, it prints the address in the
-@@ -866,14 +875,25 @@ static noinline_for_stack
- char *pointer(const char *fmt, char *buf, char *end, void *ptr,
- struct printf_spec spec)
+@@ -868,12 +877,12 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
{
-+#ifdef CONFIG_GRKERNSEC_HIDESYM
-+ /* 'P' = approved pointers to copy to userland,
-+ as in the /proc/kallsyms case, as we make it display nothing
-+ for non-root users, and the real contents for root users
-+ */
-+ if (ptr > TASK_SIZE && *fmt != 'P' && is_usercopy_object(buf)) {
-+ ptr = NULL;
-+ goto simple;
-+ }
-+#endif
-+
if (!ptr && *fmt != 'K') {
/*
- * Print (null) with the same width as a pointer so it makes
@@ -70138,7 +70148,7 @@ index abbabec..d5eba6c 100644
}
switch (*fmt) {
-@@ -883,6 +903,13 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
+@@ -883,6 +892,13 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
/* Fallthrough */
case 'S':
case 's':
@@ -70152,7 +70162,7 @@ index abbabec..d5eba6c 100644
case 'B':
return symbol_string(buf, end, ptr, spec, *fmt);
case 'R':
-@@ -920,6 +947,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
+@@ -920,12 +936,15 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
va_end(va);
return buf;
}
@@ -70161,13 +70171,31 @@ index abbabec..d5eba6c 100644
case 'K':
/*
* %pK cannot be used in IRQ context because its test
-@@ -942,6 +971,9 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
+ * for CAP_SYSLOG would be meaningless.
+ */
+- if (in_irq() || in_serving_softirq() || in_nmi()) {
++ if (kptr_restrict && (in_irq() || in_serving_softirq() ||
++ in_nmi())) {
+ if (spec.field_width == -1)
+ spec.field_width = 2 * sizeof(void *);
+ return string(buf, end, "pK-error", spec);
+@@ -942,6 +961,19 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
}
break;
}
++
+#ifdef CONFIG_GRKERNSEC_HIDESYM
-+simple:
++ /* 'P' = approved pointers to copy to userland,
++ as in the /proc/kallsyms case, as we make it display nothing
++ for non-root users, and the real contents for root users
++ */
++ if (ptr > TASK_SIZE && *fmt != 'P' && is_usercopy_object(buf)) {
++ printk(KERN_ALERT "grsec: kernel infoleak detected! Please report this log to spender@grsecurity.net.\n");
++ dump_stack();
++ ptr = NULL;
++ }
+#endif
++
spec.flags |= SMALL;
if (spec.field_width == -1) {
spec.field_width = 2 * sizeof(void *);
@@ -74470,22 +74498,6 @@ index 1196c77..2e608e8 100644
if (!vas || !vms)
goto err_free2;
-diff --git a/mm/vmscan.c b/mm/vmscan.c
-index 4607cc6..be5bc0a 100644
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -3013,7 +3013,10 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx)
- * them before going back to sleep.
- */
- set_pgdat_percpu_threshold(pgdat, calculate_normal_threshold);
-- schedule();
-+
-+ if (!kthread_should_stop())
-+ schedule();
-+
- set_pgdat_percpu_threshold(pgdat, calculate_pressure_threshold);
- } else {
- if (remaining)
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 7db1b9b..e9f6b07 100644
--- a/mm/vmstat.c
@@ -77207,6 +77219,27 @@ index 4503335..db566b4 100644
}
#endif
+diff --git a/net/rds/recv.c b/net/rds/recv.c
+index 5c6e9f1..9f0f17c 100644
+--- a/net/rds/recv.c
++++ b/net/rds/recv.c
+@@ -410,6 +410,8 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
+
+ rdsdebug("size %zu flags 0x%x timeo %ld\n", size, msg_flags, timeo);
+
++ msg->msg_namelen = 0;
++
+ if (msg_flags & MSG_OOB)
+ goto out;
+
+@@ -485,6 +487,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
+ sin->sin_port = inc->i_hdr.h_sport;
+ sin->sin_addr.s_addr = inc->i_saddr;
+ memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
++ msg->msg_namelen = sizeof(*sin);
+ }
+ break;
+ }
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index edac9ef..16bcb98 100644
--- a/net/rds/tcp.c
@@ -78688,10 +78721,10 @@ index 5c11312..72742b5 100644
write_hex_cnt = 0;
for (i = 0; i < logo_clutsize; i++) {
diff --git a/security/Kconfig b/security/Kconfig
-index ccc61f8..5e68d73 100644
+index ccc61f8..0759500 100644
--- a/security/Kconfig
+++ b/security/Kconfig
-@@ -4,6 +4,875 @@
+@@ -4,6 +4,876 @@
menu "Security options"
@@ -78723,6 +78756,7 @@ index ccc61f8..5e68d73 100644
+ bool "Grsecurity"
+ select CRYPTO
+ select CRYPTO_SHA256
++ select PROC_FS
+ select STOP_MACHINE
+ help
+ If you say Y here, you will be able to configure many features
@@ -79567,7 +79601,7 @@ index ccc61f8..5e68d73 100644
config KEYS
bool "Enable access key retention support"
help
-@@ -169,7 +1038,7 @@ config INTEL_TXT
+@@ -169,7 +1039,7 @@ config INTEL_TXT
config LSM_MMAP_MIN_ADDR
int "Low address space for LSM to protect from user allocation"
depends on SECURITY && SECURITY_SELINUX