[PATCH 1/2] security, lsm: Introduce security_mptcp_add_subflow()
Paolo Abeni
pabeni at redhat.com
Wed Dec 14 22:01:57 UTC 2022
MPTCP can create subflows in kernel context, and later indirectly
expose them to user-space, via the owning mptcp socket.
As discussed in the reported link, the above causes unexpected failures
for server, MPTCP-enabled applications.
Let's introduce a new LSM hook to allow the security module to relabel
the subflow according to the owing process.
Link: https://lore.kernel.org/mptcp/CAHC9VhTNh-YwiyTds=P1e3rixEDqbRTFj22bpya=+qJqfcaMfg@mail.gmail.com/
Signed-off-by: Paolo Abeni <pabeni at redhat.com>
---
include/linux/lsm_hook_defs.h | 1 +
include/linux/lsm_hooks.h | 9 +++++++++
include/linux/security.h | 6 ++++++
net/mptcp/subflow.c | 6 ++++++
security/security.c | 5 +++++
5 files changed, 27 insertions(+)
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index ed6cb2ac55fa..860e11e3a26b 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -343,6 +343,7 @@ LSM_HOOK(void, LSM_RET_VOID, sctp_sk_clone, struct sctp_association *asoc,
struct sock *sk, struct sock *newsk)
LSM_HOOK(int, 0, sctp_assoc_established, struct sctp_association *asoc,
struct sk_buff *skb)
+LSM_HOOK(int, 0, mptcp_add_subflow, struct sock *sk, struct sock *ssk)
#endif /* CONFIG_SECURITY_NETWORK */
#ifdef CONFIG_SECURITY_INFINIBAND
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 0a5ba81f7367..84c9c4d4341e 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1096,6 +1096,15 @@
* @skb pointer to skbuff of association packet.
* Return 0 if permission is granted.
*
+ * Security hooks for MPTCP
+ *
+ * @mptcp_add_subflow
+ * Update the labeling for the given MPTCP subflow, to match to
+ * owning MPTCP socket.
+ * @sk: the owning MPTCP socket
+ * @ssk: the new subflow
+ * Return 0 if successful, otherwise < 0 error code.
+ *
* Security hooks for Infiniband
*
* @ib_pkey_access:
diff --git a/include/linux/security.h b/include/linux/security.h
index 5b67f208f7de..137a440e8e10 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1479,6 +1479,7 @@ void security_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk,
struct sock *newsk);
int security_sctp_assoc_established(struct sctp_association *asoc,
struct sk_buff *skb);
+int security_mptcp_add_subflow(struct sock *sk, struct sock *ssk);
#else /* CONFIG_SECURITY_NETWORK */
static inline int security_unix_stream_connect(struct sock *sock,
@@ -1706,6 +1707,11 @@ static inline int security_sctp_assoc_established(struct sctp_association *asoc,
{
return 0;
}
+
+int security_mptcp_add_subflow(struct sock *sk, struct sock *ssk)
+{
+ return 0;
+}
#endif /* CONFIG_SECURITY_NETWORK */
#ifdef CONFIG_SECURITY_INFINIBAND
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index bd387d4b5a38..43b90784d914 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -1680,6 +1680,10 @@ int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock)
lock_sock(sf->sk);
+ err = security_mptcp_add_subflow(sk, sf->sk);
+ if (err)
+ goto release_ssk;
+
/* the newly created socket has to be in the same cgroup as its parent */
mptcp_attach_cgroup(sk, sf->sk);
@@ -1692,6 +1696,8 @@ int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock)
get_net_track(net, &sf->sk->ns_tracker, GFP_KERNEL);
sock_inuse_add(net, 1);
err = tcp_set_ulp(sf->sk, "mptcp");
+
+release_ssk:
release_sock(sf->sk);
if (err) {
diff --git a/security/security.c b/security/security.c
index d1571900a8c7..3491a4fc2b1f 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2493,6 +2493,11 @@ int security_sctp_assoc_established(struct sctp_association *asoc,
}
EXPORT_SYMBOL(security_sctp_assoc_established);
+int security_mptcp_add_subflow(struct sock *sk, struct sock *ssk)
+{
+ return call_int_hook(mptcp_add_subflow, 0, sk, ssk);
+}
+
#endif /* CONFIG_SECURITY_NETWORK */
#ifdef CONFIG_SECURITY_INFINIBAND
--
2.38.1
More information about the Linux-security-module-archive
mailing list