mirror of
https://abf.rosa.ru/djam/kernel-6.6.git
synced 2025-02-25 03:42:46 +00:00

https://git.altlinux.org/gears/k/kernel-image-un-def.git?p=kernel-image-un-def.git;a=history;f=security/altha;h=90d1618c238171cff6517d93fd1f2e000c72d977;hb=HEAD
150 lines
6.6 KiB
Diff
150 lines
6.6 KiB
Diff
From c71405f7352fd1929313360a34c1431613e92fb6 Mon Sep 17 00:00:00 2001
|
|
From: "Vladimir D. Seleznev" <vseleznv@altlinux.org>
|
|
Date: Fri, 3 Jun 2022 16:44:41 +0000
|
|
Subject: [PATCH] AltHa: handle setcap binaries in the same way as setuid ones
|
|
|
|
altha.nosuid facility controls what binaries can raise user privilleges.
|
|
Prior to this commit it only handled setuid binaries, but it was still
|
|
possible to raise privilleges via setcaps. Now it handles both setuid
|
|
and setcap binaries.
|
|
|
|
Signed-off-by: Vladimir D. Seleznev <vseleznv@altlinux.org>
|
|
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
|
|
---
|
|
Documentation/admin-guide/LSM/AltHa.rst | 6 ++--
|
|
security/altha/Kconfig | 2 +-
|
|
security/altha/altha_lsm.c | 47 ++++++++++++++++++++-----
|
|
3 files changed, 43 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/Documentation/admin-guide/LSM/AltHa.rst b/Documentation/admin-guide/LSM/AltHa.rst
|
|
index 34d010740bda..fc3ba1486194 100644
|
|
--- a/Documentation/admin-guide/LSM/AltHa.rst
|
|
+++ b/Documentation/admin-guide/LSM/AltHa.rst
|
|
@@ -3,7 +3,7 @@ AltHa
|
|
====
|
|
|
|
AltHa is a Linux Security Module currently has three userspace hardening options:
|
|
- * ignore SUID on binaries (with exceptions possible);
|
|
+ * ignore SUID and setcaps on binaries (with exceptions possible);
|
|
* prevent running selected script interpreters in interactive mode;
|
|
* disable open file unlinking in selected dirs.
|
|
|
|
@@ -14,12 +14,12 @@ through sysctls in ``/proc/sys/kernel/altha``.
|
|
|
|
NoSUID
|
|
============
|
|
-Modern Linux systems can be used with minimal (or even zero at least for OWL and ALT) usage of SUID programms, but in many cases in full-featured desktop or server systems there are plenty of them: uncounted and sometimes unnecessary. Privileged programms are always an attack surface, but mounting filesystems with ``nosuid`` flag doesn't provide enough granularity in SUID binaries management. This LSM module provides a single control point for all SUID binaries. When this submodule is enabled, SUID bits on all binaries except explicitly listed are system-wide ignored.
|
|
+Modern Linux systems can be used with minimal (or even zero at least for OWL and ALT) usage of SUID programms, but in many cases in full-featured desktop or server systems there are plenty of them: uncounted and sometimes unnecessary. Privileged programms are always an attack surface, but mounting filesystems with ``nosuid`` flag doesn't provide enough granularity in SUID binaries management. This LSM module provides a single control point for all SUID and setcap binaries. When this submodule is enabled, SUID and setcap bits on all binaries except explicitly listed are system-wide ignored.
|
|
|
|
Sysctl parameters and defaults:
|
|
|
|
* ``kernel.altha.nosuid.enabled = 0``, set to 1 to enable
|
|
-* ``kernel.altha.nosuid.exceptions =``, colon-separated list of enabled SUID binaries, for example: ``/bin/su:/usr/libexec/hasher-priv/hasher-priv``
|
|
+* ``kernel.altha.nosuid.exceptions =``, colon-separated list of enabled SUID and setcap binaries, for example: ``/bin/su:/usr/libexec/hasher-priv/hasher-priv``
|
|
|
|
RestrScript
|
|
============
|
|
diff --git a/security/altha/Kconfig b/security/altha/Kconfig
|
|
index 4bafdef4e58e..cd1dd69cc48d 100644
|
|
--- a/security/altha/Kconfig
|
|
+++ b/security/altha/Kconfig
|
|
@@ -4,7 +4,7 @@ config SECURITY_ALTHA
|
|
default n
|
|
help
|
|
Some hardening options:
|
|
- * ignore SUID on binaries (with exceptions possible);
|
|
+ * ignore SUID and setcap on binaries (with exceptions possible);
|
|
* prevent running selected script interprers in interactive move;
|
|
* WxorX for filesystems (with exceptions possible);
|
|
|
|
diff --git a/security/altha/altha_lsm.c b/security/altha/altha_lsm.c
|
|
index 0dfccddb4d45..dc0fec452821 100644
|
|
--- a/security/altha/altha_lsm.c
|
|
+++ b/security/altha/altha_lsm.c
|
|
@@ -11,6 +11,7 @@
|
|
|
|
#include <linux/lsm_hooks.h>
|
|
#include <linux/cred.h>
|
|
+#include <linux/capability.h>
|
|
#include <linux/sysctl.h>
|
|
#include <linux/binfmts.h>
|
|
#include <linux/file.h>
|
|
@@ -241,6 +242,7 @@ int is_olock_dir(struct inode *inode)
|
|
static int altha_bprm_creds_from_file(struct linux_binprm *bprm, struct file * fi)
|
|
{
|
|
struct altha_list_struct *node;
|
|
+ char *setuidcap_str = "setuid";
|
|
/* when it's not a shebang issued script interpreter */
|
|
if (rstrscript_enabled && bprm->executable == bprm->interpreter) {
|
|
char *path_p;
|
|
@@ -267,11 +269,37 @@ static int altha_bprm_creds_from_file(struct linux_binprm *bprm, struct file * f
|
|
up_read(&interpreters_sem);
|
|
kfree(path_buffer);
|
|
}
|
|
- if (unlikely(nosuid_enabled &&
|
|
- !uid_eq(bprm->cred->uid, bprm->cred->euid))) {
|
|
+ if (nosuid_enabled) {
|
|
char *path_p;
|
|
char *path_buffer;
|
|
- uid_t cur_uid;
|
|
+ int is_setuid = 0, is_setcap = 0;
|
|
+ uid_t cur_uid, cur_euid;
|
|
+
|
|
+ /*
|
|
+ * While nosuid is supposed to prevent switching to superuser,
|
|
+ * it does not check swtiching to a non-privileged user because
|
|
+ * it is almost never used.
|
|
+ */
|
|
+ is_setuid = !uid_eq(bprm->cred->uid, bprm->cred->euid);
|
|
+
|
|
+ if (!is_setuid) {
|
|
+ cur_euid = from_kuid(bprm->cred->user_ns, bprm->cred->euid);
|
|
+ /*
|
|
+ * Check capabilities only for effectivly non-superuser
|
|
+ * processes: superuser processess always have
|
|
+ * capabilities, should keep them so these processes
|
|
+ * continue working correctly.
|
|
+ */
|
|
+ if (cur_euid != (uid_t) 0)
|
|
+ is_setcap = !(cap_isclear(bprm->cred->cap_permitted)
|
|
+ && cap_isclear(bprm->cred->cap_effective));
|
|
+
|
|
+ setuidcap_str = "setcap";
|
|
+ }
|
|
+
|
|
+ /* If no suid and no caps detected, exit. */
|
|
+ if (!is_setuid && !is_setcap)
|
|
+ return 0;
|
|
|
|
path_buffer = kmalloc(PATH_MAX, GFP_KERNEL);
|
|
if (!path_buffer)
|
|
@@ -283,8 +311,8 @@ static int altha_bprm_creds_from_file(struct linux_binprm *bprm, struct file * f
|
|
list_for_each_entry(node, &nosuid_exceptions_list, list) {
|
|
if (strcmp(path_p, node->spath) == 0) {
|
|
pr_notice_ratelimited
|
|
- ("AltHa/NoSUID: %s permitted to setuid from %d\n",
|
|
- bprm->filename, cur_uid);
|
|
+ ("AltHa/NoSUID: %s permitted to %s from %d\n",
|
|
+ bprm->filename, setuidcap_str, cur_uid);
|
|
up_read(&nosuid_exceptions_sem);
|
|
kfree(path_buffer);
|
|
return 0;
|
|
@@ -292,9 +320,12 @@ static int altha_bprm_creds_from_file(struct linux_binprm *bprm, struct file * f
|
|
}
|
|
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;
|
|
+ ("AltHa/NoSUID: %s prevented to %s from %d\n",
|
|
+ bprm->filename, setuidcap_str, cur_uid);
|
|
+ if (is_setuid)
|
|
+ bprm->cred->euid = bprm->cred->uid;
|
|
+ cap_clear(bprm->cred->cap_permitted);
|
|
+ cap_clear(bprm->cred->cap_effective);
|
|
kfree(path_buffer);
|
|
}
|
|
return 0;
|
|
--
|
|
2.40.1
|
|
|