All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Safonov <dima@arista.com>
To: linux-kernel@vger.kernel.org
Cc: Dmitry Safonov <0x7f454c46@gmail.com>,
	Dmitry Safonov <dima@arista.com>,
	"David S. Miller" <davem@davemloft.net>,
	Florian Westphal <fw@strlen.de>,
	Herbert Xu <herbert@gondor.apana.org.au>,
	Jakub Kicinski <kuba@kernel.org>,
	Steffen Klassert <steffen.klassert@secunet.com>,
	Stephen Suryaputra <ssuryaextr@gmail.com>,
	netdev@vger.kernel.org
Subject: [PATCH v2 2/6] xfrm/compat: Attach xfrm dumps to 64=>32 bit translator
Date: Wed, 26 Aug 2020 02:49:45 +0100	[thread overview]
Message-ID: <20200826014949.644441-3-dima@arista.com> (raw)
In-Reply-To: <20200826014949.644441-1-dima@arista.com>

XFRM is disabled for compatible users because of the UABI difference.
The difference is in structures paddings and in the result the size
of netlink messages differ.

Possibility for compatible application to manage xfrm tunnels was
disabled by: the commmit 19d7df69fdb2 ("xfrm: Refuse to insert 32 bit
userspace socket policies on 64 bit systems") and the commit 74005991b78a
("xfrm: Do not parse 32bits compiled xfrm netlink msg on 64bits host").

This is my second attempt to resolve the xfrm/compat problem by adding
the 64=>32 and 32=>64 bit translators those non-visibly to a user
provide translation between compatible user and kernel.
Previous attempt was to interrupt the message ABI according to a syscall
by xfrm_user, which resulted in over-complicated code [1].

Florian Westphal provided the idea of translator and some draft patches
in the discussion. In these patches, his idea is reused and some of his
initial code is also present.

Currently nlmsg_unicast() is used by functions that dump structures that
can be different in size for compat tasks, see dump_one_state() and
dump_one_policy().

The following nlmsg_unicast() users exist today in xfrm:

         Function                          |    Message can be different
                                           |       in size on compat
-------------------------------------------|------------------------------
    xfrm_get_spdinfo()                     |               N
    xfrm_get_sadinfo()                     |               N
    xfrm_get_sa()                          |               Y
    xfrm_alloc_userspi()                   |               Y
    xfrm_get_policy()                      |               Y
    xfrm_get_ae()                          |               N

Besides, dump_one_state() and dump_one_policy() can be used by filtered
netlink dump for XFRM_MSG_GETSA, XFRM_MSG_GETPOLICY.

Just as for xfrm multicast, allocate frag_list for compat skb journey
down to recvmsg() which will give user the desired skb according to
syscall bitness.

[1]: https://lkml.kernel.org/r/20180726023144.31066-1-dima@arista.com
Signed-off-by: Dmitry Safonov <dima@arista.com>
---
 include/net/xfrm.h     |  6 ++++++
 net/xfrm/xfrm_compat.c | 10 ++++++++--
 net/xfrm/xfrm_user.c   | 20 ++++++++++++++++++++
 3 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 9810b5090338..9febf4f5d2ea 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -2002,12 +2002,18 @@ static inline int xfrm_tunnel_check(struct sk_buff *skb, struct xfrm_state *x,
 
 #ifdef CONFIG_XFRM_USER_COMPAT
 extern int xfrm_alloc_compat(struct sk_buff *skb);
+extern int __xfrm_alloc_compat(struct sk_buff *skb, const struct nlmsghdr *nlh);
 extern const int xfrm_msg_min[XFRM_NR_MSGTYPES];
 #else
 static inline int xfrm_alloc_compat(struct sk_buff *skb)
 {
 	return 0;
 }
+static inline int __xfrm_alloc_compat(struct sk_buff *skb,
+				      const struct nlmsghdr *nlh)
+{
+	return 0;
+}
 #endif
 
 #if IS_ENABLED(CONFIG_IPV6)
diff --git a/net/xfrm/xfrm_compat.c b/net/xfrm/xfrm_compat.c
index b9eb65dde0db..b34c8b56a571 100644
--- a/net/xfrm/xfrm_compat.c
+++ b/net/xfrm/xfrm_compat.c
@@ -272,9 +272,8 @@ static int xfrm_xlate64(struct sk_buff *dst, const struct nlmsghdr *nlh_src)
 	return 0;
 }
 
-int xfrm_alloc_compat(struct sk_buff *skb)
+int __xfrm_alloc_compat(struct sk_buff *skb, const struct nlmsghdr *nlh_src)
 {
-	const struct nlmsghdr *nlh_src = nlmsg_hdr(skb);
 	u16 type = nlh_src->nlmsg_type - XFRM_MSG_BASE;
 	struct sk_buff *new = NULL;
 	int err;
@@ -300,3 +299,10 @@ int xfrm_alloc_compat(struct sk_buff *skb)
 
 	return 0;
 }
+
+int xfrm_alloc_compat(struct sk_buff *skb)
+{
+	const struct nlmsghdr *nlh_src = nlmsg_hdr(skb);
+
+	return __xfrm_alloc_compat(skb, nlh_src);
+}
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 90c57d4a0b47..d135c6949336 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -992,6 +992,13 @@ static int dump_one_state(struct xfrm_state *x, int count, void *ptr)
 		return err;
 	}
 	nlmsg_end(skb, nlh);
+
+	err = __xfrm_alloc_compat(skb, nlh);
+	if (err) {
+		nlmsg_cancel(skb, nlh);
+		return err;
+	}
+
 	return 0;
 }
 
@@ -1365,6 +1372,12 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
 		goto out;
 	}
 
+	err = xfrm_alloc_compat(skb);
+	if (err) {
+		kfree_skb(resp_skb);
+		goto out;
+	}
+
 	err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).portid);
 
 out:
@@ -1795,6 +1808,13 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr
 		return err;
 	}
 	nlmsg_end(skb, nlh);
+
+	err = __xfrm_alloc_compat(skb, nlh);
+	if (err) {
+		nlmsg_cancel(skb, nlh);
+		return err;
+	}
+
 	return 0;
 }
 
-- 
2.27.0


  parent reply	other threads:[~2020-08-26  1:50 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-26  1:49 [PATCH v2 0/6] xfrm: Add compat layer Dmitry Safonov
2020-08-26  1:49 ` [PATCH v2 1/6] xfrm/compat: Add 64=>32-bit messages translator Dmitry Safonov
2020-08-26  4:03   ` kernel test robot
2020-08-26  4:03     ` kernel test robot
2020-09-07 11:24   ` Steffen Klassert
2020-09-07 17:01     ` Dmitry Safonov
2020-08-26  1:49 ` Dmitry Safonov [this message]
2020-08-26  1:49 ` [PATCH v2 3/6] netlink/compat: Append NLMSG_DONE/extack to frag_list Dmitry Safonov
2020-08-26  7:19   ` Johannes Berg
2020-09-07 16:41     ` Dmitry Safonov
2020-08-26  1:49 ` [PATCH v2 4/6] xfrm/compat: Add 32=>64-bit messages translator Dmitry Safonov
2020-08-26  1:49 ` [PATCH v2 5/6] xfrm/compat: Translate 32-bit user_policy from sockptr Dmitry Safonov
2020-08-26  1:49 ` [PATCH v2 6/6] selftest/net/xfrm: Add test for ipsec tunnel Dmitry Safonov
2020-09-07  9:43 ` [PATCH v2 0/6] xfrm: Add compat layer Steffen Klassert
2020-09-07 16:51   ` Dmitry Safonov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200826014949.644441-3-dima@arista.com \
    --to=dima@arista.com \
    --cc=0x7f454c46@gmail.com \
    --cc=davem@davemloft.net \
    --cc=fw@strlen.de \
    --cc=herbert@gondor.apana.org.au \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=ssuryaextr@gmail.com \
    --cc=steffen.klassert@secunet.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.