Add audit support for unix_stream_connect, unix_may_send, task_kill, and
file_send_sigiotask hooks.

The related blockers are:
- scope.abstract_unix_socket
- scope.signal

Audit event sample for abstract unix socket:

  type=LANDLOCK_DENY msg=audit(1729738800.268:30): domain=195ba459b 
blockers=scope.abstract_unix_socket path=00666F6F

Audit event sample for signal:

  type=LANDLOCK_DENY msg=audit(1729738800.291:31): domain=195ba459b 
blockers=scope.signal opid=1 ocomm="systemd"

Cc: Günther Noack <[email protected]>
Cc: Tahera Fahimi <[email protected]>
Signed-off-by: Mickaël Salaün <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---

Changes since v3:
- Cosmetic change to the "scope.*" blocker names.
- Extend commit message.

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 2744e3d4fe73..7a2183ac9add 100644
--- a/security/landlock/audit.c
+++ b/security/landlock/audit.c
@@ -70,6 +70,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 9a3697b901b5..dd5deaf7dc4d 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 4fef963274fd..1b3d5de89e14 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.1


Reply via email to