mirror of
https://abf.rosa.ru/djam/kernel-5.15.git
synced 2025-02-23 18:42:55 +00:00

- rediffed most of patches, renamed files to easify further rediffs by git format-patch - thanks to abf.io/kernels_stable for some patches for kernel 5.9 - using unofficial patch for AUFS for kernel 5.10, there may be issues with stability, try to avoid using AUFS (I would have dropped it, but MagOS wants it very much) - pulled updates of AltHa from http://git.altlinux.org/gears/k/kernel-image-un-def.git?p=kernel-image-un-def.git;a=history;f=security/altha;hb=HEAD - dropped patch adding sysctl to disable disk-based swap because it has not found any usage - bpf is now in the list of LSM modules (ability to write LSM modules as BPF programs), enable it, it is potentially useful and does not seem to be harmful - keeping kernel libc headers in older kernels for now - dropped building external virtualbox guest modules because they are now included into the mainline kernel - offed building VirtualBox host modules, I do not know how to keep these binary modules in sync with userspace part of VirtualBox, users can continue using dkms - offed building kernel-shredder because it is not buildable on kernel 5.10 - updated rtl8821ce and added a dependency from its "blacklist" subpackage here (see https://github.com/tomaspinho/rtl8821ce/commit/14b536f0) It is not clear if kernel 5.10 will receive an LTS support longer than 5.4 or not. Support until Dec, 2022 is declared right now at https://www.kernel.org/category/releases.html for 5.10 and until Dec, 2025 - for 5.4. TODO: update kernel configs TODO: solve problems with version of virtualbox host modules not matching version of the virtualbox package after virtualbox is updated but kernel is not rebuilt
431 lines
12 KiB
Diff
431 lines
12 KiB
Diff
From e9343095462964e78faadde92bab44a6a13cd4da Mon Sep 17 00:00:00 2001
|
|
From: Kernel Bot <kernelbot@altlinux.org>
|
|
Date: Wed, 21 Aug 2019 16:11:26 +0300
|
|
Subject: [PATCH 1/2] AltHa LSM module
|
|
|
|
* ignore SUID on binaries (with exceptions possible);
|
|
* prevent running selected script interprers in interactive move;
|
|
* disable open file unlinking in selected dirs;
|
|
|
|
Changelog:
|
|
* ported to 5.2 as ordered LSM
|
|
* introduced OLock
|
|
* no more WxorX
|
|
* error handling, path_puts and locking added
|
|
* lists handling rewritten
|
|
* indentation fixed
|
|
|
|
Rediffed for vanilla kernel 5.10.1
|
|
Signed-off-by: Mikhail Novosyolov <m.novosyolov@rosalinux.ru>
|
|
---
|
|
security/Kconfig | 3 +-
|
|
security/Makefile | 2 +
|
|
security/altha/Kconfig | 11 ++
|
|
security/altha/Makefile | 3 +
|
|
security/altha/altha_lsm.c | 325 +++++++++++++++++++++++++++++++++++++
|
|
5 files changed, 343 insertions(+), 1 deletion(-)
|
|
create mode 100644 security/altha/Kconfig
|
|
create mode 100644 security/altha/Makefile
|
|
create mode 100644 security/altha/altha_lsm.c
|
|
|
|
diff --git a/security/Kconfig b/security/Kconfig
|
|
index 7561f6f99f1d..b7551d9001e6 100644
|
|
--- a/security/Kconfig
|
|
+++ b/security/Kconfig
|
|
@@ -238,6 +238,7 @@ source "security/loadpin/Kconfig"
|
|
source "security/yama/Kconfig"
|
|
source "security/safesetid/Kconfig"
|
|
source "security/lockdown/Kconfig"
|
|
+source "security/altha/Kconfig"
|
|
|
|
source "security/integrity/Kconfig"
|
|
|
|
@@ -281,7 +282,7 @@ config LSM
|
|
default "lockdown,yama,loadpin,safesetid,integrity,apparmor,selinux,smack,tomoyo,bpf" if DEFAULT_SECURITY_APPARMOR
|
|
default "lockdown,yama,loadpin,safesetid,integrity,tomoyo,bpf" if DEFAULT_SECURITY_TOMOYO
|
|
default "lockdown,yama,loadpin,safesetid,integrity,bpf" if DEFAULT_SECURITY_DAC
|
|
- default "lockdown,yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor,bpf"
|
|
+ default "lockdown,yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor,bpf,altha"
|
|
help
|
|
A comma-separated list of LSMs, in initialization order.
|
|
Any LSMs left off this list will be ignored. This can be
|
|
diff --git a/security/Makefile b/security/Makefile
|
|
index 3baf435de541..9cc6f5b1b099 100644
|
|
--- a/security/Makefile
|
|
+++ b/security/Makefile
|
|
@@ -13,6 +13,7 @@ subdir-$(CONFIG_SECURITY_LOADPIN) += loadpin
|
|
subdir-$(CONFIG_SECURITY_SAFESETID) += safesetid
|
|
subdir-$(CONFIG_SECURITY_LOCKDOWN_LSM) += lockdown
|
|
subdir-$(CONFIG_BPF_LSM) += bpf
|
|
+subdir-$(CONFIG_SECURITY_ALTHA) += altha
|
|
|
|
# always enable default capabilities
|
|
obj-y += commoncap.o
|
|
@@ -32,6 +33,7 @@ obj-$(CONFIG_SECURITY_SAFESETID) += safesetid/
|
|
obj-$(CONFIG_SECURITY_LOCKDOWN_LSM) += lockdown/
|
|
obj-$(CONFIG_CGROUPS) += device_cgroup.o
|
|
obj-$(CONFIG_BPF_LSM) += bpf/
|
|
+obj-$(CONFIG_SECURITY_ALTHA) += altha/
|
|
|
|
# Object integrity file lists
|
|
subdir-$(CONFIG_INTEGRITY) += integrity
|
|
diff --git a/security/altha/Kconfig b/security/altha/Kconfig
|
|
new file mode 100644
|
|
index 000000000000..4bafdef4e58e
|
|
--- /dev/null
|
|
+++ b/security/altha/Kconfig
|
|
@@ -0,0 +1,11 @@
|
|
+config SECURITY_ALTHA
|
|
+ bool "AltHa security module"
|
|
+ depends on SECURITY
|
|
+ default n
|
|
+ help
|
|
+ Some hardening options:
|
|
+ * ignore SUID on binaries (with exceptions possible);
|
|
+ * prevent running selected script interprers in interactive move;
|
|
+ * WxorX for filesystems (with exceptions possible);
|
|
+
|
|
+ If you are unsure how to answer this question, answer N.
|
|
diff --git a/security/altha/Makefile b/security/altha/Makefile
|
|
new file mode 100644
|
|
index 000000000000..56735b157567
|
|
--- /dev/null
|
|
+++ b/security/altha/Makefile
|
|
@@ -0,0 +1,3 @@
|
|
+obj-$(CONFIG_SECURITY_ALTHA) := altha.o
|
|
+
|
|
+altha-y := altha_lsm.o
|
|
diff --git a/security/altha/altha_lsm.c b/security/altha/altha_lsm.c
|
|
new file mode 100644
|
|
index 000000000000..7d1cc8f8a1a7
|
|
--- /dev/null
|
|
+++ b/security/altha/altha_lsm.c
|
|
@@ -0,0 +1,325 @@
|
|
+/*
|
|
+ * AltHa Linux Security Module
|
|
+ *
|
|
+ * Author: Anton Boyarshinov <boyarsh@altlinux.org>
|
|
+ *
|
|
+ * 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
|
|
+ * published by the Free Software Foundation.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include <linux/lsm_hooks.h>
|
|
+#include <linux/cred.h>
|
|
+#include <linux/sysctl.h>
|
|
+#include <linux/binfmts.h>
|
|
+#include <linux/file.h>
|
|
+#include <linux/ratelimit.h>
|
|
+#include <linux/moduleparam.h>
|
|
+#include <linux/list.h>
|
|
+#include <linux/namei.h>
|
|
+#include <linux/namei.h>
|
|
+#include <linux/printk.h>
|
|
+#include <linux/rwsem.h>
|
|
+#include <asm/uaccess.h>
|
|
+
|
|
+#define ALTHA_PARAMS_SIZE 4096
|
|
+char proc_nosuid_exceptions[ALTHA_PARAMS_SIZE];
|
|
+char proc_interpreters[ALTHA_PARAMS_SIZE];
|
|
+char proc_olock_dirs[ALTHA_PARAMS_SIZE];
|
|
+
|
|
+/* Boot time disable flag */
|
|
+static bool altha_enabled = 0;
|
|
+
|
|
+/* sysctl flags */
|
|
+static int nosuid_enabled;
|
|
+static int rstrscript_enabled;
|
|
+static int olock_enabled;
|
|
+
|
|
+/* Boot parameter handing */
|
|
+module_param_named(enabled, altha_enabled, bool, S_IRUGO);
|
|
+
|
|
+static int __init altha_enabled_setup(char *str)
|
|
+{
|
|
+ unsigned long enabled;
|
|
+ int error = kstrtoul(str, 0, &enabled);
|
|
+ if (!error)
|
|
+ altha_enabled = enabled ? 1 : 0;
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+__setup("altha=", altha_enabled_setup);
|
|
+
|
|
+struct altha_list_struct {
|
|
+ struct path path;
|
|
+ struct list_head list;
|
|
+};
|
|
+
|
|
+/* Lists handling */
|
|
+DECLARE_RWSEM(nosuid_exceptions_sem);
|
|
+DECLARE_RWSEM(interpreters_sem);
|
|
+DECLARE_RWSEM(olock_dirs_sem);
|
|
+LIST_HEAD(nosuid_exceptions_list);
|
|
+LIST_HEAD(interpreters_list);
|
|
+LIST_HEAD(olock_dirs_list);
|
|
+
|
|
+static int altha_list_handler(struct ctl_table *table, int write,
|
|
+ void __user * buffer, size_t * lenp,
|
|
+ loff_t * ppos)
|
|
+{
|
|
+ struct altha_list_struct *item, *tmp;
|
|
+ struct list_head *list_struct;
|
|
+ char *p, *fluid;
|
|
+ char *copy_buffer;
|
|
+ struct rw_semaphore *sem = table->extra2;
|
|
+ unsigned long error = proc_dostring(table, write, buffer, lenp, ppos);
|
|
+ down_write(sem);
|
|
+ if (error)
|
|
+ goto out;
|
|
+
|
|
+ if (write && !error) {
|
|
+ copy_buffer = kmalloc(ALTHA_PARAMS_SIZE, GFP_KERNEL);
|
|
+ if (!copy_buffer) {
|
|
+ pr_err
|
|
+ ("AltHa: can't get memory for copy_buffer processing sysctl\n");
|
|
+ error = -1;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ list_struct = (struct list_head *)(table->extra1);
|
|
+ /*empty list and that fill with new info */
|
|
+ list_for_each_entry_safe(item, tmp, list_struct, list) {
|
|
+ list_del(&item->list);
|
|
+ path_put(&item->path);
|
|
+ kfree(item);
|
|
+ }
|
|
+
|
|
+ strlcpy(copy_buffer, table->data, ALTHA_PARAMS_SIZE);
|
|
+
|
|
+ /* buffer can have a garbage after \n */
|
|
+ p = strchrnul(copy_buffer, '\n');
|
|
+ *p = 0;
|
|
+
|
|
+ /* for strsep usage */
|
|
+ fluid = copy_buffer;
|
|
+
|
|
+ while ((p = strsep(&fluid, ":\n")) != NULL) {
|
|
+ if (strlen(p)) {
|
|
+ item = kmalloc(sizeof(*item), GFP_KERNEL);
|
|
+ if (!item) {
|
|
+ pr_err
|
|
+ ("AltHa: can't get memory processing sysctl\n");
|
|
+ kfree(copy_buffer);
|
|
+ error = -1;
|
|
+ goto out;
|
|
+ }
|
|
+ if (kern_path(p, LOOKUP_FOLLOW, &item->path)) {
|
|
+ pr_info
|
|
+ ("AltHa: error lookup '%s'\n", p);
|
|
+ kfree(item);
|
|
+ } else {
|
|
+ list_add_tail(&item->list, list_struct);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ kfree(copy_buffer);
|
|
+ }
|
|
+out:
|
|
+ up_write(sem);
|
|
+ return error;
|
|
+}
|
|
+
|
|
+struct ctl_path nosuid_sysctl_path[] = {
|
|
+ {.procname = "kernel",},
|
|
+ {.procname = "altha",},
|
|
+ {.procname = "nosuid",},
|
|
+ {}
|
|
+};
|
|
+
|
|
+static struct ctl_table nosuid_sysctl_table[] = {
|
|
+ {
|
|
+ .procname = "enabled",
|
|
+ .data = &nosuid_enabled,
|
|
+ .maxlen = sizeof(int),
|
|
+ .mode = 0644,
|
|
+ .proc_handler = proc_dointvec_minmax,
|
|
+ },
|
|
+ {
|
|
+ .procname = "exceptions",
|
|
+ .data = proc_nosuid_exceptions,
|
|
+ .maxlen = ALTHA_PARAMS_SIZE,
|
|
+ .mode = 0644,
|
|
+ .proc_handler = altha_list_handler,
|
|
+ .extra1 = &nosuid_exceptions_list,
|
|
+ .extra2 = &nosuid_exceptions_sem,
|
|
+ },
|
|
+ {}
|
|
+};
|
|
+
|
|
+struct ctl_path rstrscript_sysctl_path[] = {
|
|
+ {.procname = "kernel",},
|
|
+ {.procname = "altha",},
|
|
+ {.procname = "rstrscript",},
|
|
+ {}
|
|
+};
|
|
+
|
|
+static struct ctl_table rstrscript_sysctl_table[] = {
|
|
+ {
|
|
+ .procname = "enabled",
|
|
+ .data = &rstrscript_enabled,
|
|
+ .maxlen = sizeof(int),
|
|
+ .mode = 0644,
|
|
+ .proc_handler = &proc_dointvec_minmax,
|
|
+ },
|
|
+ {
|
|
+ .procname = "interpreters",
|
|
+ .data = proc_interpreters,
|
|
+ .maxlen = ALTHA_PARAMS_SIZE,
|
|
+ .mode = 0644,
|
|
+ .proc_handler = altha_list_handler,
|
|
+ .extra1 = &interpreters_list,
|
|
+ .extra2 = &interpreters_sem,
|
|
+ },
|
|
+ {}
|
|
+};
|
|
+
|
|
+struct ctl_path olock_sysctl_path[] = {
|
|
+ {.procname = "kernel",},
|
|
+ {.procname = "altha",},
|
|
+ {.procname = "olock",},
|
|
+ {}
|
|
+};
|
|
+
|
|
+static struct ctl_table olock_sysctl_table[] = {
|
|
+ {
|
|
+ .procname = "enabled",
|
|
+ .data = &olock_enabled,
|
|
+ .maxlen = sizeof(int),
|
|
+ .mode = 0644,
|
|
+ .proc_handler = &proc_dointvec_minmax,
|
|
+ },
|
|
+ {
|
|
+ .procname = "dirs",
|
|
+ .data = proc_olock_dirs,
|
|
+ .maxlen = ALTHA_PARAMS_SIZE,
|
|
+ .mode = 0644,
|
|
+ .proc_handler = altha_list_handler,
|
|
+ .extra1 = &olock_dirs_list,
|
|
+ .extra2 = &olock_dirs_sem,
|
|
+ },
|
|
+ {}
|
|
+};
|
|
+
|
|
+struct altha_readdir_callback {
|
|
+ struct dir_context ctx;
|
|
+ u64 inode;
|
|
+ int found;
|
|
+};
|
|
+
|
|
+
|
|
+int is_olock_dir(struct inode *inode)
|
|
+{
|
|
+ struct altha_list_struct *node;
|
|
+ down_read(&olock_dirs_sem);
|
|
+ list_for_each_entry(node, &olock_dirs_list, list) {
|
|
+ struct inode *exc_inode = node->path.dentry->d_inode;
|
|
+ if (exc_inode == inode) {
|
|
+ up_read(&olock_dirs_sem);
|
|
+ return 1;
|
|
+ }
|
|
+ }
|
|
+ up_read(&olock_dirs_sem);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/* Hooks */
|
|
+static int altha_bprm_set_creds(struct linux_binprm *bprm)
|
|
+{
|
|
+ struct altha_list_struct *node;
|
|
+ /* when it's not a shebang issued script interpreter */
|
|
+ if (rstrscript_enabled && !bprm->called_set_creds) {
|
|
+ down_read(&interpreters_sem);
|
|
+ list_for_each_entry(node, &interpreters_list, list) {
|
|
+ if (path_equal(&bprm->file->f_path, &node->path)) {
|
|
+ uid_t cur_uid = from_kuid(bprm->cred->user_ns,
|
|
+ bprm->cred->uid);
|
|
+ pr_notice_ratelimited
|
|
+ ("AltHa/RestrScript: %s is blocked to run directly by %d\n",
|
|
+ bprm->filename, cur_uid);
|
|
+ up_read(&interpreters_sem);
|
|
+ return -EPERM;
|
|
+ }
|
|
+ }
|
|
+ up_read(&interpreters_sem);
|
|
+ }
|
|
+ if (unlikely(nosuid_enabled &&
|
|
+ !uid_eq(bprm->cred->uid, bprm->cred->euid))) {
|
|
+ uid_t cur_uid = from_kuid(bprm->cred->user_ns, bprm->cred->uid);
|
|
+ down_read(&nosuid_exceptions_sem);
|
|
+ list_for_each_entry(node, &nosuid_exceptions_list, list) {
|
|
+ if (path_equal(&bprm->file->f_path, &node->path)) {
|
|
+ pr_notice_ratelimited
|
|
+ ("AltHa/NoSUID: %s permitted to setuid from %d\n",
|
|
+ bprm->filename, cur_uid);
|
|
+ up_read(&nosuid_exceptions_sem);
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+ up_read(&nosuid_exceptions_sem);
|
|
+ pr_notice_ratelimited
|
|
+ ("AltHa/NoSUID: %s prevented to setuid from %d\n",
|
|
+ bprm->filename, cur_uid);
|
|
+ bprm->cred->euid = bprm->cred->uid;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/* For OLock */
|
|
+static int altha_inode_unlink(struct inode *inode, struct dentry *dentry)
|
|
+{
|
|
+ if (olock_enabled && (atomic_read(&dentry->d_inode->i_writecount)
|
|
+#ifdef CONFIG_IMA
|
|
+ || atomic_read(&dentry->d_inode->i_readcount)
|
|
+#endif
|
|
+ )) {
|
|
+ if (is_olock_dir(inode))
|
|
+ return -EPERM;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/* Initialization */
|
|
+
|
|
+static struct security_hook_list altha_hooks[] = {
|
|
+ LSM_HOOK_INIT(bprm_set_creds, altha_bprm_set_creds),
|
|
+ LSM_HOOK_INIT(inode_unlink, altha_inode_unlink),
|
|
+};
|
|
+
|
|
+static int __init altha_init(void)
|
|
+{
|
|
+ if (altha_enabled) {
|
|
+ pr_info("AltHa enabled.\n");
|
|
+ security_add_hooks(altha_hooks, ARRAY_SIZE(altha_hooks),"altha");
|
|
+
|
|
+ if (!register_sysctl_paths
|
|
+ (nosuid_sysctl_path, nosuid_sysctl_table))
|
|
+ panic("AltHa: NoSUID sysctl registration failed.\n");
|
|
+
|
|
+ if (!register_sysctl_paths
|
|
+ (rstrscript_sysctl_path, rstrscript_sysctl_table))
|
|
+ panic
|
|
+ ("AltHa: RestrScript sysctl registration failed.\n");
|
|
+
|
|
+ if (!register_sysctl_paths
|
|
+ (olock_sysctl_path, olock_sysctl_table))
|
|
+ panic("AltHa: OLock sysctl registration failed.\n");
|
|
+ } else
|
|
+ pr_info("AltHa disabled.\n");
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+DEFINE_LSM(altha) = {
|
|
+ .name = "altha",
|
|
+ .init = altha_init,
|
|
+};
|
|
+
|
|
--
|
|
2.25.1
|
|
|