@@ -1535,6 +1535,15 @@
Permit 'security.evm' to be updated regardless of
current integrity status.
+ exec.seal_system_mappings = [KNL]
+ Format: { never | always }
+ Seal system mappings: vdso, vvar, sigpage, uprobes,
+ vsyscall.
+ This overwrites KCONFIG CONFIG_SEAL_SYSTEM_MAPPINGS_*
+ - 'never': never seal system mappings.
+ - 'always': always seal system mappings.
+ If not specified or invalid, default is the KCONFIG value.
+
early_page_ext [KNL,EARLY] Enforces page_ext initialization to earlier
stages so cover more early boot allocations.
Please note that as side effect some optimizations
@@ -32,6 +32,7 @@
#include <linux/mm_types.h>
#include <linux/syscalls.h>
#include <linux/ratelimit.h>
+#include <linux/fs.h>
#include <asm/vsyscall.h>
#include <asm/unistd.h>
@@ -366,8 +367,12 @@ void __init map_vsyscall(void)
set_vsyscall_pgtable_user_bits(swapper_pg_dir);
}
- if (vsyscall_mode == XONLY)
- vm_flags_init(&gate_vma, VM_EXEC);
+ if (vsyscall_mode == XONLY) {
+ unsigned long vm_flags = VM_EXEC;
+
+ update_seal_exec_system_mappings(&vm_flags);
+ vm_flags_init(&gate_vma, vm_flags);
+ }
BUILD_BUG_ON((unsigned long)__fix_to_virt(VSYSCALL_PAGE) !=
(unsigned long)VSYSCALL_ADDR);
@@ -68,6 +68,7 @@
#include <linux/user_events.h>
#include <linux/rseq.h>
#include <linux/ksm.h>
+#include <linux/fs_parser.h>
#include <linux/uaccess.h>
#include <asm/mmu_context.h>
@@ -2169,3 +2170,55 @@ fs_initcall(init_fs_exec_sysctls);
#ifdef CONFIG_EXEC_KUNIT_TEST
#include "tests/exec_kunit.c"
#endif
+
+#ifdef CONFIG_64BIT
+/*
+ * Kernel cmdline overwrite for CONFIG_SEAL_SYSTEM_MAPPINGS_X
+ */
+enum seal_system_mappings_type {
+ SEAL_SYSTEM_MAPPINGS_NEVER,
+ SEAL_SYSTEM_MAPPINGS_ALWAYS
+};
+
+static enum seal_system_mappings_type seal_system_mappings __ro_after_init =
+ IS_ENABLED(CONFIG_SEAL_SYSTEM_MAPPINGS_ALWAYS) ? SEAL_SYSTEM_MAPPINGS_ALWAYS :
+ SEAL_SYSTEM_MAPPINGS_NEVER;
+
+static const struct constant_table value_table_sys_mapping[] __initconst = {
+ { "never", SEAL_SYSTEM_MAPPINGS_NEVER},
+ { "always", SEAL_SYSTEM_MAPPINGS_ALWAYS},
+ { }
+};
+
+static int __init early_seal_system_mappings_override(char *buf)
+{
+ if (!buf)
+ return -EINVAL;
+
+ seal_system_mappings = lookup_constant(value_table_sys_mapping,
+ buf, seal_system_mappings);
+
+ return 0;
+}
+
+early_param("exec.seal_system_mappings", early_seal_system_mappings_override);
+
+static bool seal_system_mappings_enabled(void)
+{
+ if (seal_system_mappings == SEAL_SYSTEM_MAPPINGS_ALWAYS)
+ return true;
+
+ return false;
+}
+
+void update_seal_exec_system_mappings(unsigned long *vm_flags)
+{
+ if (seal_system_mappings_enabled())
+ *vm_flags |= VM_SEALED;
+
+}
+#else
+void update_seal_exec_system_mappings(unsigned long *vm_flags)
+{
+}
+#endif /* CONFIG_64BIT */
@@ -3075,6 +3075,7 @@ ssize_t __kernel_read(struct file *file, void *buf, size_t count, loff_t *pos);
extern ssize_t kernel_write(struct file *, const void *, size_t, loff_t *);
extern ssize_t __kernel_write(struct file *, const void *, size_t, loff_t *);
extern struct file * open_exec(const char *);
+extern void update_seal_exec_system_mappings(unsigned long *vm_flags);
/* fs/dcache.c -- generic fs support functions */
extern bool is_subdir(struct dentry *, struct dentry *);
@@ -2115,6 +2115,7 @@ struct vm_area_struct *_install_special_mapping(
unsigned long addr, unsigned long len,
unsigned long vm_flags, const struct vm_special_mapping *spec)
{
+ update_seal_exec_system_mappings(&vm_flags);
return __install_special_mapping(mm, addr, len, vm_flags, (void *)spec,
&special_mapping_vmops);
}
@@ -51,6 +51,32 @@ config PROC_MEM_NO_FORCE
endchoice
+choice
+ prompt "Seal system mappings"
+ default SEAL_SYSTEM_MAPPINGS_NEVER
+ help
+ Seal system mappings such as vdso, vvar, sigpage, uprobes and
+ vsyscall.
+ Note: kernel command line exec.seal_system_mappings overwrite this.
+
+config SEAL_SYSTEM_MAPPINGS_NEVER
+ bool "Traditional behavior - not sealed"
+ help
+ Do not seal system mappings.
+ This is default.
+
+config SEAL_SYSTEM_MAPPINGS_ALWAYS
+ bool "Always seal system mappings"
+ depends on 64BIT
+ depends on !CHECKPOINT_RESTORE
+ help
+ Seal system mappings such as vdso, vvar, sigpage, uprobes and
+ vsyscall.
+ Note: CHECKPOINT_RESTORE might relocate vdso mapping during restore,
+ and remap will fail if the mapping is sealed, therefore
+ !CHECKPOINT_RESTORE is added as dependency.
+endchoice
+
config SECURITY
bool "Enable different security models"
depends on SYSFS