mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-12-27 00:19:26 -05:00
Add some more Linux CVE patches
This commit is contained in:
parent
86c2d7a648
commit
ce59045163
78
Patches/Linux_CVEs/CVE-2017-13080/0.patch
Normal file
78
Patches/Linux_CVEs/CVE-2017-13080/0.patch
Normal file
@ -0,0 +1,78 @@
|
||||
From 3adf241382f15b64df74f7c0eeea4583e094eaf9 Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Tue, 5 Sep 2017 14:54:54 +0200
|
||||
Subject: [PATCH] mac80211: accept key reinstall without changing anything
|
||||
|
||||
When a key is reinstalled we can reset the replay counters
|
||||
etc. which can lead to nonce reuse and/or replay detection
|
||||
being impossible, breaking security properties, as described
|
||||
in the "KRACK attacks".
|
||||
|
||||
In particular, CVE-2017-13080 applies to GTK rekeying that
|
||||
happened in firmware while the host is in D3, with the second
|
||||
part of the attack being done after the host wakes up. In
|
||||
this case, the wpa_supplicant mitigation isn't sufficient
|
||||
since wpa_supplicant doesn't know the GTK material.
|
||||
|
||||
In case this happens, simply silently accept the new key
|
||||
coming from userspace but don't take any action on it since
|
||||
it's the same key; this keeps the PN replay counters intact.
|
||||
|
||||
Change-Id: I7576ed8c8df85a767ebf15e74a642063eb34d0f5
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
net/mac80211/key.c | 20 +++++++++++++++++---
|
||||
1 file changed, 17 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
|
||||
index 635d0972b68..417f047f2dc 100644
|
||||
--- a/net/mac80211/key.c
|
||||
+++ b/net/mac80211/key.c
|
||||
@@ -3,6 +3,7 @@
|
||||
* Copyright 2005-2006, Devicescape Software, Inc.
|
||||
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
||||
* Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net>
|
||||
+ * Copyright 2015-2017 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -464,9 +465,6 @@ int ieee80211_key_link(struct ieee80211_key *key,
|
||||
|
||||
pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE;
|
||||
idx = key->conf.keyidx;
|
||||
- key->local = sdata->local;
|
||||
- key->sdata = sdata;
|
||||
- key->sta = sta;
|
||||
|
||||
mutex_lock(&sdata->local->key_mtx);
|
||||
|
||||
@@ -477,6 +475,21 @@ int ieee80211_key_link(struct ieee80211_key *key,
|
||||
else
|
||||
old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
|
||||
|
||||
+ /*
|
||||
+ * Silently accept key re-installation without really installing the
|
||||
+ * new version of the key to avoid nonce reuse or replay issues.
|
||||
+ */
|
||||
+ if (old_key && key->conf.keylen == old_key->conf.keylen &&
|
||||
+ !memcmp(key->conf.key, old_key->conf.key, key->conf.keylen)) {
|
||||
+ ieee80211_key_free_unused(key);
|
||||
+ ret = 0;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ key->local = sdata->local;
|
||||
+ key->sdata = sdata;
|
||||
+ key->sta = sta;
|
||||
+
|
||||
increment_tailroom_need_count(sdata);
|
||||
|
||||
ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
|
||||
@@ -489,6 +502,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
|
||||
if (ret)
|
||||
ieee80211_key_free(key, true);
|
||||
|
||||
+ out:
|
||||
mutex_unlock(&sdata->local->key_mtx);
|
||||
|
||||
return ret;
|
260
Patches/Linux_CVEs/LVT-2017-0001/0.patch
Normal file
260
Patches/Linux_CVEs/LVT-2017-0001/0.patch
Normal file
@ -0,0 +1,260 @@
|
||||
From 9d76d20a000ff47633ece50db4be52bd210db79b Mon Sep 17 00:00:00 2001
|
||||
From: Tom Marshall <tdm.code@gmail.com>
|
||||
Date: Wed, 25 Jan 2017 18:01:03 +0100
|
||||
Subject: [PATCH] kernel: Only expose su when daemon is running
|
||||
|
||||
It has been claimed that the PG implementation of 'su' has security
|
||||
vulnerabilities even when disabled. Unfortunately, the people that
|
||||
find these vulnerabilities often like to keep them private so they
|
||||
can profit from exploits while leaving users exposed to malicious
|
||||
hackers.
|
||||
|
||||
In order to reduce the attack surface for vulnerabilites, it is
|
||||
therefore necessary to make 'su' completely inaccessible when it
|
||||
is not in use (except by the root and system users).
|
||||
|
||||
Change-Id: I79716c72f74d0b7af34ec3a8054896c6559a181d
|
||||
---
|
||||
fs/exec.c | 5 +++++
|
||||
fs/namei.c | 8 ++++++++
|
||||
fs/readdir.c | 15 +++++++++++++++
|
||||
include/linux/dcache.h | 7 +++++++
|
||||
include/linux/fs.h | 1 +
|
||||
include/linux/sched.h | 8 ++++++++
|
||||
include/linux/uidgid.h | 3 +++
|
||||
kernel/exit.c | 5 +++++
|
||||
kernel/fork.c | 2 ++
|
||||
kernel/sched/core.c | 32 ++++++++++++++++++++++++++++++++
|
||||
10 files changed, 86 insertions(+)
|
||||
|
||||
diff --git a/fs/exec.c b/fs/exec.c
|
||||
index 4d5006cff73..0238899eeaa 100644
|
||||
--- a/fs/exec.c
|
||||
+++ b/fs/exec.c
|
||||
@@ -1693,6 +1693,11 @@ static int do_execve_common(const char *filename,
|
||||
if (retval < 0)
|
||||
goto out;
|
||||
|
||||
+ if (d_is_su(file->f_dentry) && capable(CAP_SYS_ADMIN)) {
|
||||
+ current->flags |= PF_SU;
|
||||
+ su_exec();
|
||||
+ }
|
||||
+
|
||||
/* execve succeeded */
|
||||
current->fs->in_exec = 0;
|
||||
current->in_execve = 0;
|
||||
diff --git a/fs/namei.c b/fs/namei.c
|
||||
index de342fb9ed0..b3cbf53dda2 100644
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -2025,6 +2025,14 @@ static int path_lookupat(int dfd, const char *name,
|
||||
}
|
||||
}
|
||||
|
||||
+ if (!err) {
|
||||
+ struct super_block *sb = nd->inode->i_sb;
|
||||
+ if (sb->s_flags & MS_RDONLY) {
|
||||
+ if (d_is_su(nd->path.dentry) && !su_visible())
|
||||
+ err = -ENOENT;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (base)
|
||||
fput(base);
|
||||
|
||||
diff --git a/fs/readdir.c b/fs/readdir.c
|
||||
index 5d6578affbb..516fc904513 100644
|
||||
--- a/fs/readdir.c
|
||||
+++ b/fs/readdir.c
|
||||
@@ -39,6 +39,7 @@ int iterate_dir(struct file *file, struct dir_context *ctx)
|
||||
if (!IS_DEADDIR(inode)) {
|
||||
if (file->f_op->iterate) {
|
||||
ctx->pos = file->f_pos;
|
||||
+ ctx->romnt = (inode->i_sb->s_flags & MS_RDONLY);
|
||||
res = file->f_op->iterate(file, ctx);
|
||||
file->f_pos = ctx->pos;
|
||||
} else {
|
||||
@@ -53,6 +54,14 @@ int iterate_dir(struct file *file, struct dir_context *ctx)
|
||||
}
|
||||
EXPORT_SYMBOL(iterate_dir);
|
||||
|
||||
+static bool hide_name(const char *name, int namlen)
|
||||
+{
|
||||
+ if (namlen == 2 && !memcmp(name, "su", 2))
|
||||
+ if (!su_visible())
|
||||
+ return true;
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Traditional linux readdir() handling..
|
||||
*
|
||||
@@ -91,6 +100,8 @@ static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset
|
||||
buf->result = -EOVERFLOW;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
+ if (hide_name(name, namlen) && buf->ctx.romnt)
|
||||
+ return 0;
|
||||
buf->result++;
|
||||
dirent = buf->dirent;
|
||||
if (!access_ok(VERIFY_WRITE, dirent,
|
||||
@@ -169,6 +180,8 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
|
||||
buf->error = -EOVERFLOW;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
+ if (hide_name(name, namlen) && buf->ctx.romnt)
|
||||
+ return 0;
|
||||
dirent = buf->previous;
|
||||
if (dirent) {
|
||||
if (__put_user(offset, &dirent->d_off))
|
||||
@@ -249,6 +262,8 @@ static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
|
||||
buf->error = -EINVAL; /* only used if we fail.. */
|
||||
if (reclen > buf->count)
|
||||
return -EINVAL;
|
||||
+ if (hide_name(name, namlen) && buf->ctx.romnt)
|
||||
+ return 0;
|
||||
dirent = buf->previous;
|
||||
if (dirent) {
|
||||
if (__put_user(offset, &dirent->d_off))
|
||||
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
|
||||
index 7bd16b926d5..a660e2b1a28 100644
|
||||
--- a/include/linux/dcache.h
|
||||
+++ b/include/linux/dcache.h
|
||||
@@ -411,6 +411,13 @@ static inline bool d_mountpoint(struct dentry *dentry)
|
||||
return dentry->d_flags & DCACHE_MOUNTED;
|
||||
}
|
||||
|
||||
+static inline bool d_is_su(const struct dentry *dentry)
|
||||
+{
|
||||
+ return dentry &&
|
||||
+ dentry->d_name.len == 2 &&
|
||||
+ !memcmp(dentry->d_name.name, "su", 2);
|
||||
+}
|
||||
+
|
||||
extern int sysctl_vfs_cache_pressure;
|
||||
|
||||
#endif /* __LINUX_DCACHE_H */
|
||||
diff --git a/include/linux/fs.h b/include/linux/fs.h
|
||||
index fe4a8fe4630..e686a31375d 100644
|
||||
--- a/include/linux/fs.h
|
||||
+++ b/include/linux/fs.h
|
||||
@@ -1538,6 +1538,7 @@ typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned);
|
||||
struct dir_context {
|
||||
filldir_t actor;
|
||||
loff_t pos;
|
||||
+ bool romnt;
|
||||
};
|
||||
|
||||
static inline bool dir_emit(struct dir_context *ctx,
|
||||
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
||||
index 6dbecacfe05..96cd3c15967 100644
|
||||
--- a/include/linux/sched.h
|
||||
+++ b/include/linux/sched.h
|
||||
@@ -55,6 +55,12 @@ struct sched_param {
|
||||
|
||||
#include <asm/processor.h>
|
||||
|
||||
+int su_instances(void);
|
||||
+bool su_running(void);
|
||||
+bool su_visible(void);
|
||||
+void su_exec(void);
|
||||
+void su_exit(void);
|
||||
+
|
||||
struct exec_domain;
|
||||
struct futex_pi_state;
|
||||
struct robust_list_head;
|
||||
@@ -1678,6 +1684,8 @@ extern int task_free_unregister(struct notifier_block *n);
|
||||
#define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezable */
|
||||
#define PF_WAKE_UP_IDLE 0x80000000 /* try to wake up on an idle CPU */
|
||||
|
||||
+#define PF_SU 0x00000002 /* task is su */
|
||||
+
|
||||
/*
|
||||
* Only the _current_ task can read/write to tsk->flags, but other
|
||||
* tasks can access tsk->flags in readonly mode for example
|
||||
diff --git a/include/linux/uidgid.h b/include/linux/uidgid.h
|
||||
index 8e522cbcef2..cb4c867a523 100644
|
||||
--- a/include/linux/uidgid.h
|
||||
+++ b/include/linux/uidgid.h
|
||||
@@ -64,6 +64,9 @@ static inline gid_t __kgid_val(kgid_t gid)
|
||||
#define GLOBAL_ROOT_UID KUIDT_INIT(0)
|
||||
#define GLOBAL_ROOT_GID KGIDT_INIT(0)
|
||||
|
||||
+#define GLOBAL_SYSTEM_UID KUIDT_INIT(1000)
|
||||
+#define GLOBAL_SYSTEM_GID KGIDT_INIT(1000)
|
||||
+
|
||||
#define INVALID_UID KUIDT_INIT(-1)
|
||||
#define INVALID_GID KGIDT_INIT(-1)
|
||||
|
||||
diff --git a/kernel/exit.c b/kernel/exit.c
|
||||
index 8e2166363b4..89b8cd8499d 100644
|
||||
--- a/kernel/exit.c
|
||||
+++ b/kernel/exit.c
|
||||
@@ -754,6 +754,11 @@ void do_exit(long code)
|
||||
}
|
||||
|
||||
exit_signals(tsk); /* sets PF_EXITING */
|
||||
+
|
||||
+ if (tsk->flags & PF_SU) {
|
||||
+ su_exit();
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* tsk->flags are checked in the futex code to protect against
|
||||
* an exiting task cleaning up the robust pi futexes.
|
||||
diff --git a/kernel/fork.c b/kernel/fork.c
|
||||
index 5bb57843fa4..bce1c62fc6c 100644
|
||||
--- a/kernel/fork.c
|
||||
+++ b/kernel/fork.c
|
||||
@@ -326,6 +326,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
|
||||
if (err)
|
||||
goto free_ti;
|
||||
|
||||
+ tsk->flags &= ~PF_SU;
|
||||
+
|
||||
tsk->stack = ti;
|
||||
#ifdef CONFIG_SECCOMP
|
||||
/*
|
||||
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
|
||||
index d80cef29661..b8fdeb468b3 100644
|
||||
--- a/kernel/sched/core.c
|
||||
+++ b/kernel/sched/core.c
|
||||
@@ -92,6 +92,38 @@
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/sched.h>
|
||||
|
||||
+static atomic_t __su_instances;
|
||||
+
|
||||
+int su_instances(void)
|
||||
+{
|
||||
+ return atomic_read(&__su_instances);
|
||||
+}
|
||||
+
|
||||
+bool su_running(void)
|
||||
+{
|
||||
+ return su_instances() > 0;
|
||||
+}
|
||||
+
|
||||
+bool su_visible(void)
|
||||
+{
|
||||
+ kuid_t uid = current_uid();
|
||||
+ if (su_running())
|
||||
+ return true;
|
||||
+ if (uid_eq(uid, GLOBAL_ROOT_UID) || uid_eq(uid, GLOBAL_SYSTEM_UID))
|
||||
+ return true;
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+void su_exec(void)
|
||||
+{
|
||||
+ atomic_inc(&__su_instances);
|
||||
+}
|
||||
+
|
||||
+void su_exit(void)
|
||||
+{
|
||||
+ atomic_dec(&__su_instances);
|
||||
+}
|
||||
+
|
||||
void start_bandwidth_timer(struct hrtimer *period_timer, ktime_t period)
|
||||
{
|
||||
unsigned long delta;
|
26
Patches/Linux_CVEs/LVT-2017-0002/0.patch
Normal file
26
Patches/Linux_CVEs/LVT-2017-0002/0.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From 20ad8a951b24ec89e887070364b386169b3ad89a Mon Sep 17 00:00:00 2001
|
||||
From: Tom Marshall <tdm.code@gmail.com>
|
||||
Date: Thu, 18 May 2017 23:50:22 +0000
|
||||
Subject: [PATCH] kernel: Fix potential refcount leak in su check
|
||||
|
||||
Change-Id: I8d2c8bed65a01eb0928308df638a04449a5bd881
|
||||
---
|
||||
fs/namei.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/namei.c b/fs/namei.c
|
||||
index 40d9a30eaf3a..bdfbb34dd137 100644
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -2029,8 +2029,10 @@ static int path_lookupat(int dfd, const char *name,
|
||||
if (!err) {
|
||||
struct super_block *sb = nd->inode->i_sb;
|
||||
if (sb->s_flags & MS_RDONLY) {
|
||||
- if (d_is_su(nd->path.dentry) && !su_visible())
|
||||
+ if (d_is_su(nd->path.dentry) && !su_visible()) {
|
||||
+ path_put(&nd->path);
|
||||
err = -ENOENT;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
33
Patches/Linux_CVEs/LVT-2017-0003/0.patch
Normal file
33
Patches/Linux_CVEs/LVT-2017-0003/0.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From 29bcc180806c11559706af51f284b7217825c372 Mon Sep 17 00:00:00 2001
|
||||
From: Alberto97 <albertop2197@gmail.com>
|
||||
Date: Tue, 23 May 2017 21:47:00 +0200
|
||||
Subject: [PATCH] fs: readdir: Fix su hide patch for non-iterate filesystems
|
||||
|
||||
* 3.10 doesn't normally use iterate for filesystems,
|
||||
but it was backported in hopes of removing vfs_readdir()
|
||||
* Because the romnt variable was only set for filesystems
|
||||
using iterate, the su hide patches were broken for many
|
||||
filesytems like ext4, which still use vfs_readdir()
|
||||
instead of iterate_dir() like their mainline counterparts
|
||||
* Remove the iterate check around setting romnt to fix this
|
||||
|
||||
Change-Id: I26426683df0fd199a80f053294f352e31754bec5
|
||||
---
|
||||
fs/readdir.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/readdir.c b/fs/readdir.c
|
||||
index d52d18d9887..b22bbbfabee 100644
|
||||
--- a/fs/readdir.c
|
||||
+++ b/fs/readdir.c
|
||||
@@ -37,9 +37,9 @@ int iterate_dir(struct file *file, struct dir_context *ctx)
|
||||
|
||||
res = -ENOENT;
|
||||
if (!IS_DEADDIR(inode)) {
|
||||
+ ctx->romnt = (inode->i_sb->s_flags & MS_RDONLY);
|
||||
if (file->f_op->iterate) {
|
||||
ctx->pos = file->f_pos;
|
||||
- ctx->romnt = (inode->i_sb->s_flags & MS_RDONLY);
|
||||
res = file->f_op->iterate(file, ctx);
|
||||
file->f_pos = ctx->pos;
|
||||
} else {
|
52
Patches/Linux_CVEs/LVT-2017-0004/0.patch
Normal file
52
Patches/Linux_CVEs/LVT-2017-0004/0.patch
Normal file
@ -0,0 +1,52 @@
|
||||
From d710842e8f38921571a19b6df18a078d6622f842 Mon Sep 17 00:00:00 2001
|
||||
From: Andrea Arcangeli <andrea@cpushare.com>
|
||||
Date: Tue, 25 Jul 2017 22:22:45 +0200
|
||||
Subject: [PATCH] fs/exec: fix use after free in execve
|
||||
|
||||
"file" can be already freed if bprm->file is NULL after
|
||||
search_binary_handler() return. binfmt_script will do exactly that for
|
||||
example. If the VM reuses the file after fput run(), this will result in
|
||||
a use ater free.
|
||||
|
||||
So obtain d_is_su before search_binary_handler() runs.
|
||||
|
||||
This should explain this crash:
|
||||
|
||||
[25333.009554] Unable to handle kernel NULL pointer dereference at virtual address 00000185
|
||||
[..]
|
||||
[25333.009918] [2: am:21861] PC is at do_execve+0x354/0x474
|
||||
|
||||
Change-Id: I2a8a814d1c0aa75625be83cb30432cf13f1a0681
|
||||
Signed-off-by: Kevin F. Haggerty <haggertk@lineageos.org>
|
||||
---
|
||||
fs/exec.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/exec.c b/fs/exec.c
|
||||
index 09f2a8ccde6..b48461148cb 100644
|
||||
--- a/fs/exec.c
|
||||
+++ b/fs/exec.c
|
||||
@@ -1531,6 +1531,7 @@ static int do_execve_common(const char *filename,
|
||||
bool clear_in_exec;
|
||||
int retval;
|
||||
const struct cred *cred = current_cred();
|
||||
+ bool is_su;
|
||||
|
||||
/*
|
||||
* We move the actual failure in case of RLIMIT_NPROC excess from
|
||||
@@ -1607,11 +1608,14 @@ static int do_execve_common(const char *filename,
|
||||
if (retval < 0)
|
||||
goto out;
|
||||
|
||||
+ /* search_binary_handler can release file and it may be freed */
|
||||
+ is_su = d_is_su(file->f_dentry);
|
||||
+
|
||||
retval = search_binary_handler(bprm,regs);
|
||||
if (retval < 0)
|
||||
goto out;
|
||||
|
||||
- if (d_is_su(file->f_dentry) && capable(CAP_SYS_ADMIN)) {
|
||||
+ if (is_su && capable(CAP_SYS_ADMIN)) {
|
||||
current->flags |= PF_SU;
|
||||
su_exec();
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
cd $base"kernel/lge/mako"
|
||||
git apply $cvePatches/CVE-2012-6703/0.patch
|
||||
#git apply $cvePatches/CVE-2012-6703/0.patch
|
||||
git apply $cvePatches/CVE-2016-3134/0.patch
|
||||
git apply $cvePatches/CVE-2016-8404/0.patch
|
||||
git apply $cvePatches/CVE-2016-9793/0.patch
|
||||
|
Loading…
Reference in New Issue
Block a user