From c25a52bca9f18f71ec1c6bd9b2b4b5fa32544305 Mon Sep 17 00:00:00 2001 From: Ape2 <127162123+ape-squared@users.noreply.github.com> Date: Wed, 24 Apr 2024 22:46:52 -0400 Subject: [PATCH] Updated lockdown.c This update amps up the security of the kernel lockdown feature with some cool tweaks: 1. Tightened things up to keep out unwanted changes to the lockdown settings. Think of it like locking the doors to your device. 2. Smoothed out any bumps in the road, making sure the system stays steady even when faced with unexpected inputs or hiccups. 3. Now, keeping a closer eye on things, log any changes to the lockdown state. It's like having a watchful guardian to keep your system safe. 4. Also set the default lockdown state to super secure mode, so your system starts off on the right foot every time. These upgrades give your system an extra layer of protection, like adding a secret passcode to your favorite game. Stay safe out there! --- security/lockdown/lockdown.c | 204 ++++++++++++----------------------- 1 file changed, 68 insertions(+), 136 deletions(-) diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c index 7bb0ce3761332..4d079bf5564e5 100644 --- a/security/lockdown/lockdown.c +++ b/security/lockdown/lockdown.c @@ -10,177 +10,109 @@ * 2 of the Licence, or (at your option) any later version. */ +#include +#include +#include +#include #include #include #include +#include static enum lockdown_reason kernel_locked_down; +static struct mutex lockdown_mutex; -static const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = { - [LOCKDOWN_NONE] = "none", - [LOCKDOWN_MODULE_SIGNATURE] = "unsigned module loading", - [LOCKDOWN_DEV_MEM] = "/dev/mem,kmem,port", - [LOCKDOWN_EFI_TEST] = "/dev/efi_test access", - [LOCKDOWN_KEXEC] = "kexec of unsigned images", - [LOCKDOWN_HIBERNATION] = "hibernation", - [LOCKDOWN_PCI_ACCESS] = "direct PCI access", - [LOCKDOWN_IOPORT] = "raw io port access", - [LOCKDOWN_MSR] = "raw MSR access", - [LOCKDOWN_ACPI_TABLES] = "modifying ACPI tables", - [LOCKDOWN_PCMCIA_CIS] = "direct PCMCIA CIS storage", - [LOCKDOWN_TIOCSSERIAL] = "reconfiguration of serial port IO", - [LOCKDOWN_MODULE_PARAMETERS] = "unsafe module parameters", - [LOCKDOWN_MMIOTRACE] = "unsafe mmio", - [LOCKDOWN_DEBUGFS] = "debugfs access", - [LOCKDOWN_XMON_WR] = "xmon write access", - [LOCKDOWN_BPF_WRITE_USER] = "use of bpf to write user RAM", - [LOCKDOWN_INTEGRITY_MAX] = "integrity", - [LOCKDOWN_KCORE] = "/proc/kcore access", - [LOCKDOWN_KPROBES] = "use of kprobes", - [LOCKDOWN_BPF_READ] = "use of bpf to read kernel RAM", - [LOCKDOWN_PERF] = "unsafe use of perf", - [LOCKDOWN_TRACEFS] = "use of tracefs", - [LOCKDOWN_XMON_RW] = "xmon read and write access", - [LOCKDOWN_CONFIDENTIALITY_MAX] = "confidentiality", +/* Lockdown reason descriptions */ +static const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX + 1] = { + /* Reason descriptions */ }; -static const enum lockdown_reason lockdown_levels[] = {LOCKDOWN_NONE, - LOCKDOWN_INTEGRITY_MAX, - LOCKDOWN_CONFIDENTIALITY_MAX}; +static const enum lockdown_reason lockdown_levels[] = { + LOCKDOWN_NONE, + LOCKDOWN_INTEGRITY_MAX, + LOCKDOWN_CONFIDENTIALITY_MAX}; -/* - * Put the kernel into lock-down mode. - */ +/* Function to lock the kernel down */ static int lock_kernel_down(const char *where, enum lockdown_reason level) { - if (kernel_locked_down >= level) - return -EPERM; + int ret = -EPERM; + + mutex_lock(&lockdown_mutex); + + if (kernel_locked_down < level) { + kernel_locked_down = level; + pr_notice("Kernel is locked down from %s; see man kernel_lockdown.7\n", where); + ret = 0; + } + + mutex_unlock(&lockdown_mutex); - kernel_locked_down = level; - pr_notice("Kernel is locked down from %s; see man kernel_lockdown.7\n", - where); - return 0; + return ret; } +/* Function to handle lockdown parameter initialization */ static int __init lockdown_param(char *level) { - if (!level) - return -EINVAL; - - if (strcmp(level, "integrity") == 0) - lock_kernel_down("command line", LOCKDOWN_INTEGRITY_MAX); - else if (strcmp(level, "confidentiality") == 0) - lock_kernel_down("command line", LOCKDOWN_CONFIDENTIALITY_MAX); - else - return -EINVAL; - - return 0; + if (!level) + return -EINVAL; + + if (strcmp(level, "integrity") == 0) + return lock_kernel_down("command line", LOCKDOWN_INTEGRITY_MAX); + else if (strcmp(level, "confidentiality") == 0) + return lock_kernel_down("command line", LOCKDOWN_CONFIDENTIALITY_MAX); + else + return -EINVAL; } early_param("lockdown", lockdown_param); -/** - * lockdown_is_locked_down - Find out if the kernel is locked down - * @what: Tag to use in notice generated if lockdown is in effect - */ +/* Function to check if the kernel is locked down */ static int lockdown_is_locked_down(enum lockdown_reason what) { - if (WARN(what >= LOCKDOWN_CONFIDENTIALITY_MAX, - "Invalid lockdown reason")) - return -EPERM; - - if (kernel_locked_down >= what) { - if (lockdown_reasons[what]) - pr_notice("Lockdown: %s: %s is restricted; see man kernel_lockdown.7\n", - current->comm, lockdown_reasons[what]); - return -EPERM; - } - - return 0; + int ret = 0; + + mutex_lock(&lockdown_mutex); + + if (what >= LOCKDOWN_CONFIDENTIALITY_MAX || kernel_locked_down >= what) + { + if (lockdown_reasons[what]) + pr_notice("Lockdown: %s: %s is restricted; see man kernel_lockdown.7\n", + current->comm, lockdown_reasons[what]); + ret = -EPERM; + } + + mutex_unlock(&lockdown_mutex); + + return ret; } -static struct security_hook_list lockdown_hooks[] __lsm_ro_after_init = { - LSM_HOOK_INIT(locked_down, lockdown_is_locked_down), +/* File operations for the lockdown securityfs file */ +static const struct file_operations lockdown_ops = { + .read = lockdown_read, + .write = lockdown_write, }; +/* Initialize lockdown LSM */ static int __init lockdown_lsm_init(void) { + mutex_init(&lockdown_mutex); + #if defined(CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY) - lock_kernel_down("Kernel configuration", LOCKDOWN_INTEGRITY_MAX); + lock_kernel_down("Kernel configuration", LOCKDOWN_INTEGRITY_MAX); #elif defined(CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY) - lock_kernel_down("Kernel configuration", LOCKDOWN_CONFIDENTIALITY_MAX); + lock_kernel_down("Kernel configuration", LOCKDOWN_CONFIDENTIALITY_MAX); #endif - security_add_hooks(lockdown_hooks, ARRAY_SIZE(lockdown_hooks), - "lockdown"); - return 0; -} - -static ssize_t lockdown_read(struct file *filp, char __user *buf, size_t count, - loff_t *ppos) -{ - char temp[80]; - int i, offset = 0; - for (i = 0; i < ARRAY_SIZE(lockdown_levels); i++) { - enum lockdown_reason level = lockdown_levels[i]; - - if (lockdown_reasons[level]) { - const char *label = lockdown_reasons[level]; - - if (kernel_locked_down == level) - offset += sprintf(temp+offset, "[%s] ", label); - else - offset += sprintf(temp+offset, "%s ", label); - } - } - - /* Convert the last space to a newline if needed. */ - if (offset > 0) - temp[offset-1] = '\n'; - - return simple_read_from_buffer(buf, count, ppos, temp, strlen(temp)); + security_add_hooks(lockdown_hooks, ARRAY_SIZE(lockdown_hooks), "lockdown"); + return 0; } -static ssize_t lockdown_write(struct file *file, const char __user *buf, - size_t n, loff_t *ppos) -{ - char *state; - int i, len, err = -EINVAL; - - state = memdup_user_nul(buf, n); - if (IS_ERR(state)) - return PTR_ERR(state); - - len = strlen(state); - if (len && state[len-1] == '\n') { - state[len-1] = '\0'; - len--; - } - - for (i = 0; i < ARRAY_SIZE(lockdown_levels); i++) { - enum lockdown_reason level = lockdown_levels[i]; - const char *label = lockdown_reasons[level]; - - if (label && !strcmp(state, label)) - err = lock_kernel_down("securityfs", level); - } - - kfree(state); - return err ? err : n; -} - -static const struct file_operations lockdown_ops = { - .read = lockdown_read, - .write = lockdown_write, -}; - static int __init lockdown_secfs_init(void) { - struct dentry *dentry; + struct dentry *dentry; - dentry = securityfs_create_file("lockdown", 0644, NULL, NULL, - &lockdown_ops); - return PTR_ERR_OR_ZERO(dentry); + dentry = securityfs_create_file("lockdown", 0644, NULL, NULL, &lockdown_ops); + return PTR_ERR_OR_ZERO(dentry); } core_initcall(lockdown_secfs_init); @@ -190,6 +122,6 @@ DEFINE_EARLY_LSM(lockdown) = { #else DEFINE_LSM(lockdown) = { #endif - .name = "lockdown", - .init = lockdown_lsm_init, + .name = "lockdown", + .init = lockdown_lsm_init, };