montana/_internal-private/MontanaOS-archived-20260521/kernel/patches/0001-user-mlock-unrestricted.patch

75 lines
2.3 KiB
Diff
Raw Normal View History

2026-05-26 21:14:51 +03:00
From: MontanaOS Kernel Team <kernel@montana.quest>
Date: Wed, 6 May 2026 00:00:00 +0000
Subject: [PATCH] mm: kernel.user_mlock_unrestricted sysctl
Adds a sysctl that allows unprivileged processes to mlock pages
beyond their RLIMIT_MEMLOCK when set to 1.
This is required for Montana node daemons running in a non-root
namespace (Termux or system service running as a dedicated UID
without CAP_IPC_LOCK), where the default RLIMIT_MEMLOCK of 64 KB
is insufficient to lock the working set of cryptographic secrets.
Default value is 0, which preserves vanilla kernel behavior. The
sysctl is set to 1 by MontanaOS init.rc only after the system
finishes early boot and montana_main service class is started.
Security model: enabling this sysctl allows any unprivileged process
to lock arbitrary amounts of memory, which could be used for a
denial-of-service attack against other processes on the same system.
On a single-purpose appliance device (MontanaOS phone running as a
dedicated validator), this is an acceptable trade-off. The sysctl
must NOT be enabled on multi-tenant systems.
Signed-off-by: MontanaOS Kernel Team <kernel@montana.quest>
---
kernel/sysctl.c | 12 ++++++++++++
mm/mlock.c | 6 ++++++
2 files changed, 18 insertions(+)
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -100,6 +100,9 @@ static const int six_hundred_forty_kb = 640 * 1024;
#endif
#endif
+int sysctl_user_mlock_unrestricted;
+EXPORT_SYMBOL(sysctl_user_mlock_unrestricted);
+
#ifdef CONFIG_PERF_EVENTS
static const int six_hundred_forty_kb = 640 * 1024;
#endif
@@ -1850,6 +1853,15 @@ static struct ctl_table kern_table[] = {
.proc_handler = proc_dointvec,
},
#endif
+ {
+ .procname = "user_mlock_unrestricted",
+ .data = &sysctl_user_mlock_unrestricted,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = SYSCTL_ZERO,
+ .extra2 = SYSCTL_ONE,
+ },
{}
};
diff --git a/mm/mlock.c b/mm/mlock.c
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -589,8 +589,14 @@ static __must_check int do_mlock(unsigned long start, size_t len, vm_flags_t fla
return error;
}
+extern int sysctl_user_mlock_unrestricted;
+
static int can_do_mlock(void)
{
+ if (sysctl_user_mlock_unrestricted)
+ return 1;
if (rlimit(RLIMIT_MEMLOCK) != 0)
return 1;
if (capable(CAP_IPC_LOCK))