aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2017-05-30 12:23:29 +1000
committerStephen Rothwell <sfr@canb.auug.org.au>2017-05-30 12:23:29 +1000
commit644406fd7dd7fa0b7c894b0fd5093b85de7bc0e3 (patch)
tree3fddf34dd8368adf971c3cbbec425562225bc8f5
parent124e5e25299bc85c4891a3f460e0c1642dd709b5 (diff)
parentd68c51e0b377838dd31b37707813bb62089f399c (diff)
Merge remote-tracking branch 'security/next'
-rw-r--r--security/Kconfig2
-rw-r--r--security/security.c19
2 files changed, 20 insertions, 1 deletions
diff --git a/security/Kconfig b/security/Kconfig
index 93027fdf47d1..bdcbb92927ab 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -139,7 +139,7 @@ config HARDENED_USERCOPY
copying memory to/from the kernel (via copy_to_user() and
copy_from_user() functions) by rejecting memory ranges that
are larger than the specified heap object, span multiple
- separately allocates pages, are not on the process stack,
+ separately allocated pages, are not on the process stack,
or are part of the kernel text. This kills entire classes
of heap overflow exploits and similar kernel memory exposures.
diff --git a/security/security.c b/security/security.c
index b9fea3999cf8..38316bb28b16 100644
--- a/security/security.c
+++ b/security/security.c
@@ -25,6 +25,7 @@
#include <linux/mount.h>
#include <linux/personality.h>
#include <linux/backing-dev.h>
+#include <linux/string.h>
#include <net/flow.h>
#define MAX_LSM_EVM_XATTR 2
@@ -86,6 +87,21 @@ static int __init choose_lsm(char *str)
}
__setup("security=", choose_lsm);
+static bool match_last_lsm(const char *list, const char *lsm)
+{
+ const char *last;
+
+ if (WARN_ON(!list || !lsm))
+ return false;
+ last = strrchr(list, ',');
+ if (last)
+ /* Pass the comma, strcmp() will check for '\0' */
+ last++;
+ else
+ last = list;
+ return !strcmp(last, lsm);
+}
+
static int lsm_append(char *new, char **result)
{
char *cp;
@@ -93,6 +109,9 @@ static int lsm_append(char *new, char **result)
if (*result == NULL) {
*result = kstrdup(new, GFP_KERNEL);
} else {
+ /* Check if it is the last registered name */
+ if (match_last_lsm(*result, new))
+ return 0;
cp = kasprintf(GFP_KERNEL, "%s,%s", *result, new);
if (cp == NULL)
return -ENOMEM;