summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2015-11-15 11:32:15 -0500
committerAnthony G. Basile <blueness@gentoo.org>2015-11-15 11:32:15 -0500
commitabddbbc666308272b2792e65f7c9e208e9bfddbb (patch)
treeebdd34679d8f76e539b16e9dddc78d8f5b63e574
parentgrsecurity-3.1-4.2.6-201511122040 (diff)
downloadhardened-patchset-abddbbc666308272b2792e65f7c9e208e9bfddbb.tar.gz
hardened-patchset-abddbbc666308272b2792e65f7c9e208e9bfddbb.tar.bz2
hardened-patchset-abddbbc666308272b2792e65f7c9e208e9bfddbb.zip
grsecurity-3.1-4.2.6-20151114154320151114
-rw-r--r--4.2.6/0000_README2
-rw-r--r--4.2.6/4420_grsecurity-3.1-4.2.6-201511141543.patch (renamed from 4.2.6/4420_grsecurity-3.1-4.2.6-201511122040.patch)356
2 files changed, 268 insertions, 90 deletions
diff --git a/4.2.6/0000_README b/4.2.6/0000_README
index 9993992..7ec57e5 100644
--- a/4.2.6/0000_README
+++ b/4.2.6/0000_README
@@ -6,7 +6,7 @@ Patch: 1005_linux-4.2.6.patch
From: http://www.kernel.org
Desc: Linux 4.2.6
-Patch: 4420_grsecurity-3.1-4.2.6-201511122040.patch
+Patch: 4420_grsecurity-3.1-4.2.6-201511141543.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/4.2.6/4420_grsecurity-3.1-4.2.6-201511122040.patch b/4.2.6/4420_grsecurity-3.1-4.2.6-201511141543.patch
index 2f80639..27bda59 100644
--- a/4.2.6/4420_grsecurity-3.1-4.2.6-201511122040.patch
+++ b/4.2.6/4420_grsecurity-3.1-4.2.6-201511141543.patch
@@ -75612,7 +75612,7 @@ index 54114b4..580cfc9 100644
WARN_ON(trans->transid != btrfs_header_generation(parent));
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
-index a2ae427..53c2e98 100644
+index a2ae427..d028233 100644
--- a/fs/btrfs/delayed-inode.c
+++ b/fs/btrfs/delayed-inode.c
@@ -462,7 +462,7 @@ static int __btrfs_add_delayed_deletion_item(struct btrfs_delayed_node *node,
@@ -75642,8 +75642,25 @@ index a2ae427..53c2e98 100644
ret = btrfs_wq_run_delayed_node(delayed_root, fs_info, 0);
if (ret)
+@@ -1690,7 +1690,7 @@ int btrfs_should_delete_dir_index(struct list_head *del_list,
+ *
+ */
+ int btrfs_readdir_delayed_dir_index(struct dir_context *ctx,
+- struct list_head *ins_list)
++ struct list_head *ins_list, bool *emitted)
+ {
+ struct btrfs_dir_item *di;
+ struct btrfs_delayed_item *curr, *next;
+@@ -1734,6 +1734,7 @@ int btrfs_readdir_delayed_dir_index(struct dir_context *ctx,
+
+ if (over)
+ return 1;
++ *emitted = true;
+ }
+ return 0;
+ }
diff --git a/fs/btrfs/delayed-inode.h b/fs/btrfs/delayed-inode.h
-index f70119f..ab5894d 100644
+index f70119f..b7d2bb4 100644
--- a/fs/btrfs/delayed-inode.h
+++ b/fs/btrfs/delayed-inode.h
@@ -43,7 +43,7 @@ struct btrfs_delayed_root {
@@ -75664,6 +75681,15 @@ index f70119f..ab5894d 100644
delayed_root->nodes = 0;
spin_lock_init(&delayed_root->lock);
init_waitqueue_head(&delayed_root->wait);
+@@ -144,7 +144,7 @@ void btrfs_put_delayed_items(struct list_head *ins_list,
+ int btrfs_should_delete_dir_index(struct list_head *del_list,
+ u64 index);
+ int btrfs_readdir_delayed_dir_index(struct dir_context *ctx,
+- struct list_head *ins_list);
++ struct list_head *ins_list, bool *emitted);
+
+ /* for init */
+ int __init btrfs_delayed_inode_init(void);
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index b823fac..c5155de 100644
--- a/fs/btrfs/file.c
@@ -75693,6 +75719,56 @@ index b823fac..c5155de 100644
if (ret) {
btrfs_end_transaction(trans, root);
goto out;
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index b54e630..6ecf999 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -5632,6 +5632,7 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx)
+ char *name_ptr;
+ int name_len;
+ int is_curr = 0; /* ctx->pos points to the current index? */
++ bool emitted;
+
+ /* FIXME, use a real flag for deciding about the key type */
+ if (root->fs_info->tree_root == root)
+@@ -5660,6 +5661,7 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx)
+ if (ret < 0)
+ goto err;
+
++ emitted = false;
+ while (1) {
+ leaf = path->nodes[0];
+ slot = path->slots[0];
+@@ -5739,6 +5741,7 @@ skip:
+
+ if (over)
+ goto nopos;
++ emitted = true;
+ di_len = btrfs_dir_name_len(leaf, di) +
+ btrfs_dir_data_len(leaf, di) + sizeof(*di);
+ di_cur += di_len;
+@@ -5751,11 +5754,20 @@ next:
+ if (key_type == BTRFS_DIR_INDEX_KEY) {
+ if (is_curr)
+ ctx->pos++;
+- ret = btrfs_readdir_delayed_dir_index(ctx, &ins_list);
++ ret = btrfs_readdir_delayed_dir_index(ctx, &ins_list, &emitted);
+ if (ret)
+ goto nopos;
+ }
+
++ /*
++ * If we haven't emitted any dir entry, we must not touch ctx->pos as
++ * it was was set to the termination value in previous call. We assume
++ * that "." and ".." were emitted if we reach this point and set the
++ * termination value as well for an empty directory.
++ */
++ if (ctx->pos > 2 && !emitted)
++ goto nopos;
++
+ /* Reached end of directory/root. Bump pos past the last item. */
+ ctx->pos++;
+
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index cd7ef34..1e31ae3 100644
--- a/fs/btrfs/super.c
@@ -125501,14 +125577,14 @@ index 99ca6e7..3a1a1a1 100644
rm -f $(objtree)/.scmversion
$(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
-index 88dbf23..d1b4291 100755
+index 88dbf23..c8c6e81 100755
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -304,6 +304,7 @@ fi
(cd $srctree; find arch/$SRCARCH -name module.lds -o -name Kbuild.platforms -o -name Platform) >> "$objtree/debian/hdrsrcfiles"
(cd $srctree; find $(find arch/$SRCARCH -name include -o -name scripts -type d) -type f) >> "$objtree/debian/hdrsrcfiles"
(cd $objtree; find arch/$SRCARCH/include Module.symvers include scripts -type f) >> "$objtree/debian/hdrobjfiles"
-+(cd $objtree; find tools/gcc -name \*.so >> "$objtree/debian/hdrobjfiles")
++(cd $objtree; find tools/gcc -name \*.so -o -name gcc-common.h >> "$objtree/debian/hdrobjfiles")
destdir=$kernel_headers_dir/usr/src/linux-headers-$version
mkdir -p "$destdir"
(cd $srctree; tar -c -f - -T -) < "$objtree/debian/hdrsrcfiles" | (cd $destdir; tar -xf -)
@@ -125645,7 +125721,7 @@ index c0a932d..817c587 100755
# Find all available archs
find_all_archs()
diff --git a/security/Kconfig b/security/Kconfig
-index bf4ec46..d32a3b8 100644
+index bf4ec46..faa8418 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -4,6 +4,985 @@
@@ -126596,7 +126672,7 @@ index bf4ec46..d32a3b8 100644
+
+config PAX_SIZE_OVERFLOW_DISABLE_KILL
+ bool "Do not kill process on overflow detection"
-+ default y
++ default n
+ depends on PAX_SIZE_OVERFLOW
+
+config PAX_LATENT_ENTROPY
@@ -129633,10 +129709,10 @@ index 0000000..7514850
+fi
diff --git a/tools/gcc/initify_plugin.c b/tools/gcc/initify_plugin.c
new file mode 100644
-index 0000000..294ac43
+index 0000000..2abfe4b
--- /dev/null
+++ b/tools/gcc/initify_plugin.c
-@@ -0,0 +1,450 @@
+@@ -0,0 +1,552 @@
+/*
+ * Copyright 2011-2015 by Emese Revfy <re.emese@gmail.com>
+ * Licensed under the GPL v2, or (at your option) v3
@@ -129656,13 +129732,16 @@ index 0000000..294ac43
+
+int plugin_is_GPL_compatible;
+
-+static bool verbose = false;
-+
+static struct plugin_info initify_plugin_info = {
-+ .version = "20150524a",
++ .version = "20151113",
+ .help = "initify_plugin\n",
+};
+
++/* nocapture attribute:
++ * * to mark nocapture function arguments. If used on a vararg argument it applies to all of them
++ * that have no other uses.
++ * * attribute value 0 is ignored to allow reusing print attribute arguments
++ */
+static tree handle_nocapture_attribute(tree *node, tree __unused name, tree args, int __unused flags, bool *no_add_attrs)
+{
+ tree orig_attr, arg;
@@ -129673,7 +129752,6 @@ index 0000000..294ac43
+ case FUNCTION_TYPE:
+ case METHOD_TYPE:
+ break;
-+
+ case TYPE_DECL: {
+ const_tree fntype = TREE_TYPE(*node);
+
@@ -129683,10 +129761,9 @@ index 0000000..294ac43
+ break;
+ // FALLTHROUGH
+ }
-+
+ default:
-+ error("%s: %qE attribute only applies to functions", __func__, name);
+ debug_tree(*node);
++ error("%s: %qE attribute only applies to functions", __func__, name);
+ return NULL_TREE;
+ }
+
@@ -129694,8 +129771,12 @@ index 0000000..294ac43
+ tree position = TREE_VALUE(arg);
+
+ if (TREE_CODE(position) != INTEGER_CST) {
-+ error("%s: parameter isn't an integer", __func__);
-+ debug_tree(arg);
++ error("%qE parameter of the %qE attribute isn't an integer (fn: %qE)", position, name, *node);
++ return NULL_TREE;
++ }
++
++ if (tree_int_cst_lt(position, integer_minus_one_node)) {
++ error("%qE parameter of the %qE attribute less than 0 (fn: %qE)", position, name, *node);
+ return NULL_TREE;
+ }
+ }
@@ -129742,7 +129823,6 @@ index 0000000..294ac43
+
+ if (!strncmp(str, ".init.", 6))
+ return str;
-+
+ if (!strncmp(str, ".exit.", 6))
+ return str;
+ }
@@ -129770,11 +129850,9 @@ index 0000000..294ac43
+ }
+ break;
+ }
-+
+ default:
+ break;
+ }
-+
+ return NULL_TREE;
+}
+
@@ -129795,6 +129873,164 @@ index 0000000..294ac43
+ return true;
+}
+
++static bool is_syscall(const_tree fn)
++{
++ if (!strncmp(DECL_NAME_POINTER(fn), "sys_", 4))
++ return true;
++
++ if (!strncmp(DECL_NAME_POINTER(fn), "sys32_", 6))
++ return true;
++
++ if (!strncmp(DECL_NAME_POINTER(fn), "compat_sys_", 11))
++ return true;
++
++ return false;
++}
++
++static bool is_nocapture_param(const gcall *stmt, int fn_arg_count)
++{
++ const_tree attr, attr_val;
++ int fntype_arg_len;
++ const_tree fndecl = gimple_call_fndecl(stmt);
++
++ gcc_assert(DECL_ABSTRACT_ORIGIN(fndecl) == NULL_TREE);
++
++ if (is_syscall(fndecl))
++ return true;
++
++ fntype_arg_len = type_num_arguments(TREE_TYPE(fndecl));
++ attr = lookup_attribute("nocapture", DECL_ATTRIBUTES(fndecl));
++ if (attr == NULL_TREE)
++ return false;
++
++ for (attr_val = TREE_VALUE(attr); attr_val; attr_val = TREE_CHAIN(attr_val)) {
++ int attr_arg_val = (int)tree_to_shwi(TREE_VALUE(attr_val));
++
++ if (attr_arg_val == -1)
++ return true;
++ if (attr_arg_val == fn_arg_count)
++ return true;
++ if (attr_arg_val > fntype_arg_len && fn_arg_count >= attr_arg_val)
++ return true;
++ }
++
++ return false;
++}
++
++static bool compare_vardecls(const_tree vardecl, tree op)
++{
++ tree decl, offset;
++ HOST_WIDE_INT bitsize, bitpos;
++ enum machine_mode mode;
++ int unsignedp, volatilep;
++ enum tree_code code = TREE_CODE(op);
++
++ if (TREE_CODE_CLASS(code) == tcc_exceptional && code != SSA_NAME)
++ return false;
++
++ if (code == ADDR_EXPR)
++ op = TREE_OPERAND(op, 0);
++
++ if (TREE_CODE(op) == COMPONENT_REF)
++ return false;
++
++ decl = get_inner_reference(op, &bitsize, &bitpos, &offset, &mode, &unsignedp, &volatilep, true);
++
++ switch (TREE_CODE_CLASS(TREE_CODE(decl))) {
++ case tcc_constant:
++ case tcc_statement:
++ return false;
++ default:
++ break;
++ }
++
++ switch (TREE_CODE(decl)) {
++#if BUILDING_GCC_VERSION >= 4006
++ case MEM_REF:
++#endif
++ case TARGET_MEM_REF:
++ decl = TREE_OPERAND(decl, 0);
++ break;
++ default:
++ break;
++ }
++
++ if (TREE_CODE(decl) == ADDR_EXPR)
++ decl = TREE_OPERAND(decl, 0);
++ if (TREE_CODE(decl) == SSA_NAME)
++ decl = SSA_NAME_VAR(decl);
++ if (decl == NULL_TREE)
++ return false;
++
++ if (!DECL_P(decl)) {
++ debug_tree(op);
++ debug_tree(decl);
++ gcc_unreachable();
++ }
++
++ if (!VAR_P(decl))
++ return false;
++ if (!DECL_NAME(decl))
++ return false;
++
++ if (decl != vardecl && strcmp(DECL_NAME_POINTER(decl), DECL_NAME_POINTER(vardecl)))
++ return false;
++
++ gcc_assert(TREE_CODE(op) != SSA_NAME);
++ return true;
++}
++
++static bool search_capture_use(const_tree vardecl, gimple stmt)
++{
++ unsigned int i;
++
++ for (i = 0; i < gimple_num_ops(stmt); i++) {
++ unsigned int arg_count;
++ const_tree fndecl;
++ tree op = *(gimple_op_ptr(stmt, i));
++
++ if (op == NULL_TREE)
++ continue;
++ if (is_gimple_constant(op))
++ continue;
++
++ if (!compare_vardecls(vardecl, op))
++ continue;
++
++ if (!is_gimple_call(stmt))
++ return true;
++
++ // return, fndecl
++ gcc_assert(i >= 3);
++ arg_count = i - 2;
++ if (is_nocapture_param(as_a_const_gcall(stmt), (int)arg_count))
++ continue;
++
++ fndecl = gimple_call_fndecl(stmt);
++ gcc_assert(fndecl != NULL_TREE);
++// inform(gimple_location(stmt), "nocapture attribute is missing (fn: %E, arg: %u)\n", fndecl, arg_count);
++ return true;
++
++ }
++ return false;
++}
++
++static bool has_capture_use_local_var(const_tree vardecl)
++{
++ basic_block bb;
++
++ FOR_ALL_BB_FN(bb, cfun) {
++ gimple_stmt_iterator gsi;
++
++ for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
++ if (search_capture_use(vardecl, gsi_stmt(gsi)))
++ return true;
++ }
++ }
++
++ return false;
++}
++
+static void search_local_strs(bool initexit)
+{
+ unsigned int i;
@@ -129803,16 +130039,21 @@ index 0000000..294ac43
+ FOR_EACH_LOCAL_DECL(cfun, i, var) {
+ tree str, init_val = DECL_INITIAL(var);
+
-+ if (init_val == NULL_TREE)
++ if (init_val == NULL_TREE || init_val == error_mark_node)
+ continue;
++ // !!! str local vars
+ if (strcmp(DECL_NAME_POINTER(var), "__func__"))
+ continue;
+
++ if (has_capture_use_local_var(var))
++ continue;
++
+ str = get_string_cst(init_val);
+ gcc_assert(str);
+
-+ if (set_init_exit_section(var, initexit) && verbose)
-+ inform(DECL_SOURCE_LOCATION(var), "initified local var: %s: %s", DECL_NAME_POINTER(current_function_decl), TREE_STRING_POINTER(str));
++ if (set_init_exit_section(var, initexit)) {
++// inform(DECL_SOURCE_LOCATION(var), "initified local var: %s: %s", DECL_NAME_POINTER(current_function_decl), TREE_STRING_POINTER(str));
++ }
+ }
+}
+
@@ -129853,70 +130094,6 @@ index 0000000..294ac43
+ return TREE_OPERAND(decl, 0);
+}
+
-+static bool is_syscall(const_tree fn)
-+{
-+ if (!strncmp(DECL_NAME_POINTER(fn), "sys_", 4))
-+ return true;
-+
-+ if (!strncmp(DECL_NAME_POINTER(fn), "sys32_", 6))
-+ return true;
-+
-+ if (!strncmp(DECL_NAME_POINTER(fn), "compat_sys_", 11))
-+ return true;
-+
-+ return false;
-+}
-+
-+static bool is_vararg(const_tree fn)
-+{
-+ tree arg_list;
-+
-+ arg_list = TYPE_ARG_TYPES(TREE_TYPE(fn));
-+ if (arg_list == NULL_TREE)
-+ return false;
-+
-+ return tree_last(arg_list) != void_list_node;
-+}
-+
-+// __printf(1, 0), 0: turn off the varargs checking
-+static bool check_varargs(const_tree attr)
-+{
-+ const_tree attr_val;
-+
-+ for (attr_val = TREE_VALUE(attr); attr_val; attr_val = TREE_CHAIN(attr_val)) {
-+ if (TREE_VALUE(attr_val) == integer_zero_node)
-+ return false;
-+ }
-+ return true;
-+}
-+
-+static bool is_nocapture_param(const_gimple stmt, unsigned int num)
-+{
-+ unsigned int attr_arg_val = 0;
-+ tree attr_val;
-+ const_tree attr;
-+ const_tree fndecl = gimple_call_fndecl(stmt);
-+
-+ gcc_assert(DECL_ABSTRACT_ORIGIN(fndecl) == NULL_TREE);
-+
-+ if (is_syscall(fndecl))
-+ return true;
-+
-+ attr = lookup_attribute("nocapture", DECL_ATTRIBUTES(fndecl));
-+ for (attr_val = TREE_VALUE(attr); attr_val; attr_val = TREE_CHAIN(attr_val)) {
-+ attr_arg_val = (unsigned int)tree_to_uhwi(TREE_VALUE(attr_val));
-+
-+ if (attr_arg_val == num + 1)
-+ return true;
-+ }
-+
-+ if (!is_vararg(fndecl))
-+ return false;
-+ if (!check_varargs(attr))
-+ return false;
-+ return attr_arg_val < num + 1;
-+}
-+
+static void search_str_param(gcall *stmt, bool initexit)
+{
+ unsigned int num;
@@ -129928,12 +130105,13 @@ index 0000000..294ac43
+ if (str == NULL_TREE)
+ continue;
+
-+ if (!is_nocapture_param(stmt, num))
++ if (!is_nocapture_param(stmt, num + 1))
+ continue;
+
+ var = create_tmp_assign(stmt, num);
-+ if (set_init_exit_section(var, initexit) && verbose)
-+ inform(gimple_location(stmt), "initified function arg: %s: [%s]", DECL_NAME_POINTER(current_function_decl), TREE_STRING_POINTER(str));
++ if (set_init_exit_section(var, initexit)) {
++// inform(gimple_location(stmt), "initified function arg: %E: [%E]", current_function_decl, str);
++ }
+ }
+}
+