summaryrefslogtreecommitdiff
path: root/kernels/linux-libre-grsec/known-exploit-detection.patch
diff options
context:
space:
mode:
Diffstat (limited to 'kernels/linux-libre-grsec/known-exploit-detection.patch')
-rw-r--r--kernels/linux-libre-grsec/known-exploit-detection.patch350
1 files changed, 350 insertions, 0 deletions
diff --git a/kernels/linux-libre-grsec/known-exploit-detection.patch b/kernels/linux-libre-grsec/known-exploit-detection.patch
new file mode 100644
index 000000000..4837a9ce5
--- /dev/null
+++ b/kernels/linux-libre-grsec/known-exploit-detection.patch
@@ -0,0 +1,350 @@
+diff --git a/include/linux/exploit.h b/include/linux/exploit.h
+new file mode 100644
+index 0000000..a8df72a
+--- /dev/null
++++ b/include/linux/exploit.h
+@@ -0,0 +1,23 @@
++#ifndef _LINUX_EXPLOIT_H
++#define _LINUX_EXPLOIT_H
++
++#ifdef CONFIG_EXPLOIT_DETECTION
++extern void _exploit(const char *id);
++
++#define exploit_on(cond, id) \
++ do { \
++ if (unlikely(cond)) \
++ _exploit(id); \
++ } while (0)
++
++#else
++
++#define exploit_on(cond, id) \
++ do { \
++ } while (0)
++
++#endif
++
++#define exploit(id) exploit_on(true, id)
++
++#endif
+diff --git a/security/Kconfig b/security/Kconfig
+index e9c6ac7..a828dfb 100644
+--- a/security/Kconfig
++++ b/security/Kconfig
+@@ -167,5 +167,17 @@ config DEFAULT_SECURITY
+ default "yama" if DEFAULT_SECURITY_YAMA
+ default "" if DEFAULT_SECURITY_DAC
+
+-endmenu
++config EXPLOIT_DETECTION
++ bool "Known exploit detection"
++ depends on PRINTK
++ default y
++ help
++ This option enables the detection of users/programs who attempt to
++ break into the kernel using publicly known (past) exploits.
++
++ Upon detection, a message will be printed in the kernel log.
+
++ The runtime overhead of enabling this option is extremely small, so
++ you are recommended to say Y.
++
++endmenu
+diff --git a/security/Makefile b/security/Makefile
+index c26c81e..d152a1d 100644
+--- a/security/Makefile
++++ b/security/Makefile
+@@ -28,3 +28,5 @@ obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
+ # Object integrity file lists
+ subdir-$(CONFIG_INTEGRITY) += integrity
+ obj-$(CONFIG_INTEGRITY) += integrity/built-in.o
++
++obj-$(CONFIG_EXPLOIT_DETECTION) += exploit.o
+diff --git a/security/exploit.c b/security/exploit.c
+new file mode 100644
+index 0000000..a732613
+--- /dev/null
++++ b/security/exploit.c
+@@ -0,0 +1,28 @@
++#include <linux/cred.h>
++#include <linux/exploit.h>
++#include <linux/printk.h>
++#include <linux/ratelimit.h>
++#include <linux/sched.h>
++
++void _exploit(const char *id)
++{
++ /*
++ * This function needs to be super defensive/conservative, since
++ * userspace can easily get to it from several different contexts.
++ * We don't want it to become an attack vector in itself!
++ *
++ * We can assume that we're in process context, but spinlocks may
++ * be held, etc.
++ */
++
++ struct task_struct *task = current;
++ pid_t pid = task_pid_nr(task);
++ uid_t uid = from_kuid(&init_user_ns, current_uid());
++ char comm[sizeof(task->comm)];
++
++ get_task_comm(comm, task);
++
++ pr_warn_ratelimited("warning: possible %s exploit attempt by pid=%u uid=%u comm=%s\n",
++ id, pid, uid, comm);
++}
++EXPORT_SYMBOL(_exploit);
+diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
+index 75cef3f..65811d4 100644
+--- a/include/uapi/linux/audit.h
++++ b/include/uapi/linux/audit.h
+@@ -131,6 +131,7 @@
+ #define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */
+ #define AUDIT_ANOM_ABEND 1701 /* Process ended abnormally */
+ #define AUDIT_ANOM_LINK 1702 /* Suspicious use of file links */
++#define AUDIT_ANOM_EXPLOIT 1703 /* Known exploit attempt */
+ #define AUDIT_INTEGRITY_DATA 1800 /* Data integrity verification */
+ #define AUDIT_INTEGRITY_METADATA 1801 /* Metadata integrity verification */
+ #define AUDIT_INTEGRITY_STATUS 1802 /* Integrity enable status */
+diff --git a/security/exploit.c b/security/exploit.c
+index a732613..3d8ee5b 100644
+--- a/security/exploit.c
++++ b/security/exploit.c
+@@ -1,3 +1,4 @@
++#include <linux/audit.h>
+ #include <linux/cred.h>
+ #include <linux/exploit.h>
+ #include <linux/printk.h>
+@@ -19,9 +20,24 @@ void _exploit(const char *id)
+ pid_t pid = task_pid_nr(task);
+ uid_t uid = from_kuid(&init_user_ns, current_uid());
+ char comm[sizeof(task->comm)];
++#ifdef CONFIG_AUDIT
++ struct audit_buffer *ab;
++#endif
+
+ get_task_comm(comm, task);
+
++#ifdef CONFIG_AUDIT
++ ab = audit_log_start(NULL, GFP_ATOMIC, AUDIT_ANOM_EXPLOIT);
++ if (ab) {
++ audit_log_format(ab, "exploit id=%s pid=%u uid=%u auid=%u ses=%u comm=",
++ id, pid, uid,
++ from_kuid(&init_user_ns, audit_get_loginuid(task)),
++ audit_get_sessionid(task));
++ audit_log_untrustedstring(ab, comm);
++ audit_log_end(ab);
++ }
++#endif
++
+ pr_warn_ratelimited("warning: possible %s exploit attempt by pid=%u uid=%u comm=%s\n",
+ id, pid, uid, comm);
+ }
+diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+index bf34577..48490c1 100644
+--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
++++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+@@ -32,6 +32,7 @@
+ #include "i915_trace.h"
+ #include "intel_drv.h"
+ #include <linux/dma_remapping.h>
++#include <linux/exploit.h>
+
+ struct eb_objects {
+ struct list_head objects;
+@@ -785,8 +786,10 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
+ * the worst case where we need to allocate the entire
+ * relocation tree as a single array.
+ */
+- if (exec[i].relocation_count > relocs_max - relocs_total)
++ if (exec[i].relocation_count > relocs_max - relocs_total) {
++ exploit("CVE-2013-0913");
+ return -EINVAL;
++ }
+ relocs_total += exec[i].relocation_count;
+
+ length = exec[i].relocation_count *
+diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
+index 88458fa..fad04f1 100644
+--- a/arch/x86/kernel/msr.c
++++ b/arch/x86/kernel/msr.c
+@@ -37,6 +37,7 @@
+ #include <linux/notifier.h>
+ #include <linux/uaccess.h>
+ #include <linux/gfp.h>
++#include <linux/exploit.h>
+
+ #include <asm/processor.h>
+ #include <asm/msr.h>
+@@ -174,8 +175,10 @@ static int msr_open(struct inode *inode, struct file *file)
+ unsigned int cpu = iminor(file_inode(file));
+ struct cpuinfo_x86 *c;
+
+- if (!capable(CAP_SYS_RAWIO))
++ if (!capable(CAP_SYS_RAWIO)) {
++ exploit("CVE-2013-0268");
+ return -EPERM;
++ }
+
+ if (cpu >= nr_cpu_ids || !cpu_online(cpu))
+ return -ENXIO; /* No such CPU */
+diff --git a/fs/hfs/trans.c b/fs/hfs/trans.c
+index b1ce4c7..2fe83f0 100644
+--- a/fs/hfs/trans.c
++++ b/fs/hfs/trans.c
+@@ -11,6 +11,7 @@
+
+ #include <linux/types.h>
+ #include <linux/nls.h>
++#include <linux/exploit.h>
+
+ #include "hfs_fs.h"
+
+@@ -40,8 +41,10 @@ int hfs_mac2asc(struct super_block *sb, char *out, const struct hfs_name *in)
+
+ src = in->name;
+ srclen = in->len;
+- if (srclen > HFS_NAMELEN)
++ if (srclen > HFS_NAMELEN) {
++ exploit("CVE-2011-4330");
+ srclen = HFS_NAMELEN;
++ }
+ dst = out;
+ dstlen = HFS_MAX_NAMELEN;
+ if (nls_io) {
+diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
+index 13fb113..df7a51a 100644
+--- a/kernel/user_namespace.c
++++ b/kernel/user_namespace.c
+@@ -22,6 +22,7 @@
+ #include <linux/ctype.h>
+ #include <linux/projid.h>
+ #include <linux/fs_struct.h>
++#include <linux/exploit.h>
+
+ static struct kmem_cache *user_ns_cachep __read_mostly;
+
+@@ -806,11 +807,15 @@ static bool new_idmap_permitted(const struct file *file,
+ kuid_t uid = make_kuid(ns->parent, id);
+ if (uid_eq(uid, file->f_cred->fsuid))
+ return true;
++
++ exploit_on(uid_eq(uid, current_fsuid()), "CVE-2013-1959");
+ }
+ else if (cap_setid == CAP_SETGID) {
+ kgid_t gid = make_kgid(ns->parent, id);
+ if (gid_eq(gid, file->f_cred->fsgid))
+ return true;
++
++ exploit_on(gid_eq(gid, current_fsgid()), "CVE-2013-1959");
+ }
+ }
+
+@@ -822,9 +827,12 @@ static bool new_idmap_permitted(const struct file *file,
+ * (CAP_SETUID or CAP_SETGID) over the parent user namespace.
+ * And the opener of the id file also had the approprpiate capability.
+ */
+- if (ns_capable(ns->parent, cap_setid) &&
+- file_ns_capable(file, ns->parent, cap_setid))
+- return true;
++ if (ns_capable(ns->parent, cap_setid)) {
++ if (file_ns_capable(file, ns->parent, cap_setid))
++ return true;
++
++ exploit("CVE-2013-1959");
++ }
+
+ return false;
+ }
+diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c
+index 968ce41..5f47a1a 100644
+--- a/fs/hfsplus/catalog.c
++++ b/fs/hfsplus/catalog.c
+@@ -8,6 +8,7 @@
+ * Handling of catalog records
+ */
+
++#include <linux/exploit.h>
+
+ #include "hfsplus_fs.h"
+ #include "hfsplus_raw.h"
+@@ -374,6 +375,7 @@ int hfsplus_rename_cat(u32 cnid,
+ if (err)
+ goto out;
+ if (src_fd.entrylength > sizeof(entry) || src_fd.entrylength < 0) {
++ exploit("CVE-2012-2319");
+ err = -EIO;
+ goto out;
+ }
+diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
+index 4a4fea0..2d5e283 100644
+--- a/fs/hfsplus/dir.c
++++ b/fs/hfsplus/dir.c
+@@ -9,6 +9,7 @@
+ */
+
+ #include <linux/errno.h>
++#include <linux/exploit.h>
+ #include <linux/fs.h>
+ #include <linux/slab.h>
+ #include <linux/random.h>
+@@ -152,6 +153,7 @@ static int hfsplus_readdir(struct file *file, struct dir_context *ctx)
+ }
+ if (ctx->pos == 1) {
+ if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) {
++ exploit("CVE-2012-2319");
+ err = -EIO;
+ goto out;
+ }
+@@ -186,6 +188,7 @@ static int hfsplus_readdir(struct file *file, struct dir_context *ctx)
+ }
+
+ if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) {
++ exploit("CVE-2012-2319");
+ err = -EIO;
+ goto out;
+ }
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index 953c143..32b9383 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -39,6 +39,7 @@
+ #include <linux/hw_breakpoint.h>
+ #include <linux/mm_types.h>
+ #include <linux/cgroup.h>
++#include <linux/exploit.h>
+
+ #include "internal.h"
+
+@@ -5721,6 +5722,7 @@ static void sw_perf_event_destroy(struct perf_event *event)
+ static int perf_swevent_init(struct perf_event *event)
+ {
+ u64 event_id = event->attr.config;
++ exploit_on((int) event_id < 0, "CVE-2013-2094");
+
+ if (event->attr.type != PERF_TYPE_SOFTWARE)
+ return -ENOENT;
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 0b39e7a..c16246f 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -117,6 +117,7 @@
+ #include <linux/static_key.h>
+ #include <linux/memcontrol.h>
+ #include <linux/prefetch.h>
++#include <linux/exploit.h>
+
+ #include <asm/uaccess.h>
+
+@@ -1753,8 +1754,10 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len,
+ int i;
+
+ err = -EMSGSIZE;
+- if (npages > MAX_SKB_FRAGS)
++ if (npages > MAX_SKB_FRAGS) {
++ exploit("CVE-2012-2136");
+ goto failure;
++ }
+
+ timeo = sock_sndtimeo(sk, noblock);
+ while (!skb) {