Add audit support for unix_stream_connect, unix_may_send, task_kill, and
file_send_sigiotask hooks.
Audit event sample:
type=LL_DENY [...]: domain=195ba459b blockers=scope_abstract_unix_socket path=00666F6F
Cc: Günther Noack <gnoack@google.com>
Cc: Tahera Fahimi <fahimitahera@gmail.com>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20241122143353.59367-19-mic@digikod.net
---
Changes since v1:
- New patch.
---
security/landlock/audit.c | 8 ++++++
security/landlock/audit.h | 2 ++
security/landlock/task.c | 58 ++++++++++++++++++++++++++++++++++++---
3 files changed, 64 insertions(+), 4 deletions(-)
diff --git a/security/landlock/audit.c b/security/landlock/audit.c
index 0b69b4c9ba1c..7e4acc746cd6 100644
--- a/security/landlock/audit.c
+++ b/security/landlock/audit.c
@@ -71,6 +71,14 @@ get_blocker(const enum landlock_request_type type,
if (WARN_ON_ONCE(access_bit >= ARRAY_SIZE(net_access_strings)))
return "unknown";
return net_access_strings[access_bit];
+
+ case LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET:
+ WARN_ON_ONCE(access_bit != -1);
+ return "scope_abstract_unix_socket";
+
+ case LANDLOCK_REQUEST_SCOPE_SIGNAL:
+ WARN_ON_ONCE(access_bit != -1);
+ return "scope_signal";
}
WARN_ON_ONCE(1);
diff --git a/security/landlock/audit.h b/security/landlock/audit.h
index 1075b0c8401f..1e0a9164bacc 100644
--- a/security/landlock/audit.h
+++ b/security/landlock/audit.h
@@ -19,6 +19,8 @@ enum landlock_request_type {
LANDLOCK_REQUEST_FS_CHANGE_LAYOUT,
LANDLOCK_REQUEST_FS_ACCESS,
LANDLOCK_REQUEST_NET_ACCESS,
+ LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET,
+ LANDLOCK_REQUEST_SCOPE_SIGNAL,
};
/*
diff --git a/security/landlock/task.c b/security/landlock/task.c
index 1decd6f114e8..bdf7adc14e32 100644
--- a/security/landlock/task.c
+++ b/security/landlock/task.c
@@ -263,13 +263,27 @@ static int hook_unix_stream_connect(struct sock *const sock,
const struct landlock_ruleset *const dom =
landlock_get_applicable_domain(landlock_get_current_domain(),
unix_scope);
+ struct lsm_network_audit audit_net = {
+ .sk = other,
+ };
+ struct landlock_request request = {
+ .type = LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET,
+ .audit = {
+ .type = LSM_AUDIT_DATA_NET,
+ .u.net = &audit_net,
+ },
+ };
/* Quick return for non-landlocked tasks. */
if (!dom)
return 0;
- if (is_abstract_socket(other) && sock_is_scoped(other, dom))
+ if (is_abstract_socket(other) && sock_is_scoped(other, dom)) {
+ request.layer_plus_one =
+ landlock_match_layer_level(dom, unix_scope) + 1;
+ landlock_log_denial(dom, &request);
return -EPERM;
+ }
return 0;
}
@@ -280,6 +294,16 @@ static int hook_unix_may_send(struct socket *const sock,
const struct landlock_ruleset *const dom =
landlock_get_applicable_domain(landlock_get_current_domain(),
unix_scope);
+ struct lsm_network_audit audit_net = {
+ .sk = other->sk,
+ };
+ struct landlock_request request = {
+ .type = LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET,
+ .audit = {
+ .type = LSM_AUDIT_DATA_NET,
+ .u.net = &audit_net,
+ },
+ };
if (!dom)
return 0;
@@ -291,8 +315,12 @@ static int hook_unix_may_send(struct socket *const sock,
if (unix_peer(sock->sk) == other->sk)
return 0;
- if (is_abstract_socket(other->sk) && sock_is_scoped(other->sk, dom))
+ if (is_abstract_socket(other->sk) && sock_is_scoped(other->sk, dom)) {
+ request.layer_plus_one =
+ landlock_match_layer_level(dom, unix_scope) + 1;
+ landlock_log_denial(dom, &request);
return -EPERM;
+ }
return 0;
}
@@ -307,6 +335,13 @@ static int hook_task_kill(struct task_struct *const p,
{
bool is_scoped;
const struct landlock_ruleset *dom;
+ struct landlock_request request = {
+ .type = LANDLOCK_REQUEST_SCOPE_SIGNAL,
+ .audit = {
+ .type = LSM_AUDIT_DATA_TASK,
+ .u.tsk = p,
+ },
+ };
if (cred) {
/* Dealing with USB IO. */
@@ -324,8 +359,12 @@ static int hook_task_kill(struct task_struct *const p,
is_scoped = domain_is_scoped(dom, landlock_get_task_domain(p),
LANDLOCK_SCOPE_SIGNAL);
rcu_read_unlock();
- if (is_scoped)
+ if (is_scoped) {
+ request.layer_plus_one =
+ landlock_match_layer_level(dom, signal_scope) + 1;
+ landlock_log_denial(dom, &request);
return -EPERM;
+ }
return 0;
}
@@ -334,6 +373,13 @@ static int hook_file_send_sigiotask(struct task_struct *tsk,
struct fown_struct *fown, int signum)
{
const struct landlock_ruleset *dom;
+ struct landlock_request request = {
+ .type = LANDLOCK_REQUEST_SCOPE_SIGNAL,
+ .audit = {
+ .type = LSM_AUDIT_DATA_TASK,
+ .u.tsk = tsk,
+ },
+ };
bool is_scoped = false;
/* Lock already held by send_sigio() and send_sigurg(). */
@@ -349,8 +395,12 @@ static int hook_file_send_sigiotask(struct task_struct *tsk,
is_scoped = domain_is_scoped(dom, landlock_get_task_domain(tsk),
LANDLOCK_SCOPE_SIGNAL);
rcu_read_unlock();
- if (is_scoped)
+ if (is_scoped) {
+ request.layer_plus_one =
+ landlock_match_layer_level(dom, signal_scope) + 1;
+ landlock_log_denial(dom, &request);
return -EPERM;
+ }
return 0;
}
--
2.47.0