All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 1/2] Landlock: Add signal control
@ 2024-07-05 21:21 Tahera Fahimi
  2024-07-05 21:21 ` [PATCH v1 2/2] Landlock: Signal scoping tests Tahera Fahimi
  2024-07-22 12:45 ` [PATCH v1 1/2] Landlock: Add signal control Jann Horn
  0 siblings, 2 replies; 4+ messages in thread
From: Tahera Fahimi @ 2024-07-05 21:21 UTC (permalink / raw)
  To: mic, gnoack, paul, jmorris, serge, linux-security-module,
	linux-kernel, bjorn3_gh, jannh, outreachy, netdev
  Cc: Tahera Fahimi

Currently, a sandbox process is not restricted to send a signal
(e.g. SIGKILL) to a process outside of the sandbox environment.
Ability to sending a signal for a sandboxed process should be
scoped the same way abstract unix sockets are scoped.

The same way as abstract unix socket, we extend "scoped" field
in a ruleset with "LANDLOCK_SCOPED_SIGNAL" to specify that a ruleset
will deny sending any signal from within a sandbox process to its
parent(i.e. any parent sandbox or non-sandboxed procsses).

Signed-off-by: Tahera Fahimi <fahimitahera@gmail.com>
---
 include/uapi/linux/landlock.h |  3 +++
 security/landlock/limits.h    |  2 +-
 security/landlock/task.c      | 49 +++++++++++++++++++++++++++++++++++
 3 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h
index 010aaca5b05a..878479a1b9dd 100644
--- a/include/uapi/linux/landlock.h
+++ b/include/uapi/linux/landlock.h
@@ -291,8 +291,11 @@ struct landlock_net_port_attr {
  *   from connecting to an abstract unix socket created by a process
  *   outside the related Landlock domain (e.g. a parent domain or a process
  *   which is not sandboxed).
+ * - %LANDLOCK_SCOPED_SIGNAL: Restrict a sandboxed process from sending a signal
+ *   to another process outside sandbox domain.
  */
 /* clang-format off */
 #define LANDLOCK_SCOPED_ABSTRACT_UNIX_SOCKET		(1ULL << 0)
+#define LANDLOCK_SCOPED_SIGNAL		                (1ULL << 1)
 /* clang-format on*/
 #endif /* _UAPI_LINUX_LANDLOCK_H */
diff --git a/security/landlock/limits.h b/security/landlock/limits.h
index eb01d0fb2165..fa28f9236407 100644
--- a/security/landlock/limits.h
+++ b/security/landlock/limits.h
@@ -26,7 +26,7 @@
 #define LANDLOCK_MASK_ACCESS_NET	((LANDLOCK_LAST_ACCESS_NET << 1) - 1)
 #define LANDLOCK_NUM_ACCESS_NET		__const_hweight64(LANDLOCK_MASK_ACCESS_NET)
 
-#define LANDLOCK_LAST_SCOPE		LANDLOCK_SCOPED_ABSTRACT_UNIX_SOCKET
+#define LANDLOCK_LAST_SCOPE		LANDLOCK_SCOPED_SIGNAL
 #define LANDLOCK_MASK_SCOPE		((LANDLOCK_LAST_SCOPE << 1) - 1)
 #define LANDLOCK_NUM_SCOPE		__const_hweight64(LANDLOCK_MASK_SCOPE)
 /* clang-format on */
diff --git a/security/landlock/task.c b/security/landlock/task.c
index acc6e0fbc111..caee485b97b2 100644
--- a/security/landlock/task.c
+++ b/security/landlock/task.c
@@ -168,11 +168,60 @@ static int hook_unix_may_send(struct socket *const sock,
 	return -EPERM;
 }
 
+static bool signal_is_scoped(const struct landlock_ruleset *const sender_dom,
+			     struct task_struct *const target)
+{
+	const struct landlock_ruleset *target_dom =
+		landlock_get_task_domain(target);
+
+	/* quick return if there is no domain or .scoped is not set */
+	if (!sender_dom || !get_scoped_accesses(sender_dom))
+		return true;
+
+	if (!target_dom || !get_scoped_accesses(target_dom))
+		return false;
+
+	/* other is scoped, they connect if they are in the same domain */
+	return domain_scope_le(sender_dom, target_dom);
+}
+
+static int hook_task_kill(struct task_struct *const p,
+			  struct kernel_siginfo *const info, const int sig,
+			  const struct cred *const cred)
+{
+	const struct landlock_ruleset *const dom =
+		landlock_get_current_domain();
+	bool ret = false;
+
+	if (!cred)
+		ret = signal_is_scoped(dom, p);
+	else
+		ret = signal_is_scoped(landlock_cred(cred)->domain, p);
+	if (ret)
+		return 0;
+	return EPERM;
+}
+
+static int hook_file_send_sigiotask(struct task_struct *tsk,
+				    struct fown_struct *fown, int signum)
+{
+	const struct task_struct *result =
+		get_pid_task(fown->pid, fown->pid_type);
+
+	const struct landlock_ruleset *const dom =
+		landlock_get_task_domain(result);
+	if (signal_is_scoped(dom, tsk))
+		return 0;
+	return EPERM;
+}
+
 static struct security_hook_list landlock_hooks[] __ro_after_init = {
 	LSM_HOOK_INIT(ptrace_access_check, hook_ptrace_access_check),
 	LSM_HOOK_INIT(ptrace_traceme, hook_ptrace_traceme),
 	LSM_HOOK_INIT(unix_stream_connect, hook_unix_stream_connect),
 	LSM_HOOK_INIT(unix_may_send, hook_unix_may_send),
+	LSM_HOOK_INIT(task_kill, hook_task_kill),
+	LSM_HOOK_INIT(file_send_sigiotask, hook_file_send_sigiotask),
 };
 
 __init void landlock_add_task_hooks(void)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-07-22 12:46 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-05 21:21 [PATCH v1 1/2] Landlock: Add signal control Tahera Fahimi
2024-07-05 21:21 ` [PATCH v1 2/2] Landlock: Signal scoping tests Tahera Fahimi
2024-07-09 15:18   ` Günther Noack
2024-07-22 12:45 ` [PATCH v1 1/2] Landlock: Add signal control Jann Horn

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.