diff options
author | Luke Shumaker <LukeShu@sbcglobal.net> | 2014-01-06 00:36:04 -0500 |
---|---|---|
committer | Luke Shumaker <LukeShu@sbcglobal.net> | 2014-01-06 00:36:04 -0500 |
commit | 462bbf7f306f0c1c3f4da24e15747a088d71be42 (patch) | |
tree | 562fff2ce7123e656e7bad03149156a3ff576363 /kernels/linux-libre-grsec/known-exploit-detection.patch | |
parent | 66c00a074b8c7de57a75dc683b00d29391bdf3a9 (diff) | |
parent | 993cb8ec3fd807471035038106825b4c915a33a8 (diff) |
Merge branch 'master' of https://projects.parabolagnulinux.org/abslibre
Diffstat (limited to 'kernels/linux-libre-grsec/known-exploit-detection.patch')
-rw-r--r-- | kernels/linux-libre-grsec/known-exploit-detection.patch | 350 |
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) { |