Commit 53058104 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'tcp-ulp-diag-expose-more-to-non-net-admin-users'

Matthieu Baerts says:

====================
tcp: ulp: diag: expose more to non net admin users

Since its introduction in commit 61723b39 ("tcp: ulp: add functions
to dump ulp-specific information"), the ULP diag info have been exported
only to users with CAP_NET_ADMIN capability.

Not everything is sensitive, and some info can be exported to all users
in order to ease the debugging from the userspace side without requiring
additional capabilities.

First, the ULP name can be easily exported. Then more depending on each
layer:

 - On kTLS side, it looks like everything can be exported to all users:
   version, cipher type, tx/rx user config type, plus some flags.

 - On MPTCP side, everything but the sequence numbers are exported to
   all non net admin users, similar to TCP.
====================

Link: https://patch.msgid.link/20250306-net-next-tcp-ulp-diag-net-admin-v1-0-06afdd860fc9@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 15933ad1 0d7336f8
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -2598,8 +2598,8 @@ struct tcp_ulp_ops {
	/* cleanup ulp */
	void (*release)(struct sock *sk);
	/* diagnostic */
	int (*get_info)(struct sock *sk, struct sk_buff *skb);
	size_t (*get_info_size)(const struct sock *sk);
	int (*get_info)(struct sock *sk, struct sk_buff *skb, bool net_admin);
	size_t (*get_info_size)(const struct sock *sk, bool net_admin);
	/* clone ulp */
	void (*clone)(const struct request_sock *req, struct sock *newsk,
		      const gfp_t priority);
+10 −11
Original line number Diff line number Diff line
@@ -83,7 +83,7 @@ static int tcp_diag_put_md5sig(struct sk_buff *skb,
#endif

static int tcp_diag_put_ulp(struct sk_buff *skb, struct sock *sk,
			    const struct tcp_ulp_ops *ulp_ops)
			    const struct tcp_ulp_ops *ulp_ops, bool net_admin)
{
	struct nlattr *nest;
	int err;
@@ -97,7 +97,7 @@ static int tcp_diag_put_ulp(struct sk_buff *skb, struct sock *sk,
		goto nla_failure;

	if (ulp_ops->get_info)
		err = ulp_ops->get_info(sk, skb);
		err = ulp_ops->get_info(sk, skb, net_admin);
	if (err)
		goto nla_failure;

@@ -113,6 +113,7 @@ static int tcp_diag_get_aux(struct sock *sk, bool net_admin,
			    struct sk_buff *skb)
{
	struct inet_connection_sock *icsk = inet_csk(sk);
	const struct tcp_ulp_ops *ulp_ops;
	int err = 0;

#ifdef CONFIG_TCP_MD5SIG
@@ -129,15 +130,13 @@ static int tcp_diag_get_aux(struct sock *sk, bool net_admin,
	}
#endif

	if (net_admin) {
		const struct tcp_ulp_ops *ulp_ops;

	ulp_ops = icsk->icsk_ulp_ops;
		if (ulp_ops)
			err = tcp_diag_put_ulp(skb, sk, ulp_ops);
		if (err)
	if (ulp_ops) {
		err = tcp_diag_put_ulp(skb, sk, ulp_ops, net_admin);
		if (err < 0)
			return err;
	}

	return 0;
}

@@ -164,7 +163,7 @@ static size_t tcp_diag_get_aux_size(struct sock *sk, bool net_admin)
	}
#endif

	if (net_admin && sk_fullsock(sk)) {
	if (sk_fullsock(sk)) {
		const struct tcp_ulp_ops *ulp_ops;

		ulp_ops = icsk->icsk_ulp_ops;
@@ -172,7 +171,7 @@ static size_t tcp_diag_get_aux_size(struct sock *sk, bool net_admin)
			size += nla_total_size(0) +
				nla_total_size(TCP_ULP_NAME_MAX);
			if (ulp_ops->get_info_size)
				size += ulp_ops->get_info_size(sk);
				size += ulp_ops->get_info_size(sk, net_admin);
		}
	}
	return size;
+26 −16
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@
#include <net/netlink.h>
#include "protocol.h"

static int subflow_get_info(struct sock *sk, struct sk_buff *skb)
static int subflow_get_info(struct sock *sk, struct sk_buff *skb, bool net_admin)
{
	struct mptcp_subflow_context *sf;
	struct nlattr *start;
@@ -56,7 +56,16 @@ static int subflow_get_info(struct sock *sk, struct sk_buff *skb)

	if (nla_put_u32(skb, MPTCP_SUBFLOW_ATTR_TOKEN_REM, sf->remote_token) ||
	    nla_put_u32(skb, MPTCP_SUBFLOW_ATTR_TOKEN_LOC, sf->token) ||
	    nla_put_u32(skb, MPTCP_SUBFLOW_ATTR_RELWRITE_SEQ,
	    nla_put_u32(skb, MPTCP_SUBFLOW_ATTR_FLAGS, flags) ||
	    nla_put_u8(skb, MPTCP_SUBFLOW_ATTR_ID_REM, sf->remote_id) ||
	    nla_put_u8(skb, MPTCP_SUBFLOW_ATTR_ID_LOC, subflow_get_local_id(sf))) {
		err = -EMSGSIZE;
		goto nla_failure;
	}

	/* Only export seq related counters to user with CAP_NET_ADMIN */
	if (net_admin &&
	    (nla_put_u32(skb, MPTCP_SUBFLOW_ATTR_RELWRITE_SEQ,
			 sf->rel_write_seq) ||
	     nla_put_u64_64bit(skb, MPTCP_SUBFLOW_ATTR_MAP_SEQ, sf->map_seq,
			       MPTCP_SUBFLOW_ATTR_PAD) ||
@@ -64,10 +73,7 @@ static int subflow_get_info(struct sock *sk, struct sk_buff *skb)
			 sf->map_subflow_seq) ||
	     nla_put_u32(skb, MPTCP_SUBFLOW_ATTR_SSN_OFFSET, sf->ssn_offset) ||
	     nla_put_u16(skb, MPTCP_SUBFLOW_ATTR_MAP_DATALEN,
			sf->map_data_len) ||
	    nla_put_u32(skb, MPTCP_SUBFLOW_ATTR_FLAGS, flags) ||
	    nla_put_u8(skb, MPTCP_SUBFLOW_ATTR_ID_REM, sf->remote_id) ||
	    nla_put_u8(skb, MPTCP_SUBFLOW_ATTR_ID_LOC, subflow_get_local_id(sf))) {
			 sf->map_data_len))) {
		err = -EMSGSIZE;
		goto nla_failure;
	}
@@ -84,22 +90,26 @@ static int subflow_get_info(struct sock *sk, struct sk_buff *skb)
	return err;
}

static size_t subflow_get_info_size(const struct sock *sk)
static size_t subflow_get_info_size(const struct sock *sk, bool net_admin)
{
	size_t size = 0;

	size += nla_total_size(0) +	/* INET_ULP_INFO_MPTCP */
		nla_total_size(4) +	/* MPTCP_SUBFLOW_ATTR_TOKEN_REM */
		nla_total_size(4) +	/* MPTCP_SUBFLOW_ATTR_TOKEN_LOC */
		nla_total_size(4) +	/* MPTCP_SUBFLOW_ATTR_RELWRITE_SEQ */
		nla_total_size(4) +	/* MPTCP_SUBFLOW_ATTR_FLAGS */
		nla_total_size(1) +	/* MPTCP_SUBFLOW_ATTR_ID_REM */
		nla_total_size(1) +	/* MPTCP_SUBFLOW_ATTR_ID_LOC */
		0;

	if (net_admin)
		size += nla_total_size(4) +	/* MPTCP_SUBFLOW_ATTR_RELWRITE_SEQ */
			nla_total_size_64bit(8) +	/* MPTCP_SUBFLOW_ATTR_MAP_SEQ */
			nla_total_size(4) +	/* MPTCP_SUBFLOW_ATTR_MAP_SFSEQ */
			nla_total_size(4) +	/* MPTCP_SUBFLOW_ATTR_SSN_OFFSET */
			nla_total_size(2) +	/* MPTCP_SUBFLOW_ATTR_MAP_DATALEN */
		nla_total_size(4) +	/* MPTCP_SUBFLOW_ATTR_FLAGS */
		nla_total_size(1) +	/* MPTCP_SUBFLOW_ATTR_ID_REM */
		nla_total_size(1) +	/* MPTCP_SUBFLOW_ATTR_ID_LOC */
			0;

	return size;
}

+2 −2
Original line number Diff line number Diff line
@@ -1057,7 +1057,7 @@ static u16 tls_user_config(struct tls_context *ctx, bool tx)
	return 0;
}

static int tls_get_info(struct sock *sk, struct sk_buff *skb)
static int tls_get_info(struct sock *sk, struct sk_buff *skb, bool net_admin)
{
	u16 version, cipher_type;
	struct tls_context *ctx;
@@ -1115,7 +1115,7 @@ static int tls_get_info(struct sock *sk, struct sk_buff *skb)
	return err;
}

static size_t tls_get_info_size(const struct sock *sk)
static size_t tls_get_info_size(const struct sock *sk, bool net_admin)
{
	size_t size = 0;