[Devel] [PATCH RHEL7 COMMIT] ms/crypto: user - make NETLINK_CRYPTO work inside netns

Konstantin Khorenko khorenko at virtuozzo.com
Thu Jun 15 20:05:19 MSK 2023


The commit is pushed to "branch-rh7-3.10.0-1160.90.1.vz7.200.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1160.90.1.vz7.200.1
------>
commit a0b6b73d739e26eebbb8728a0178ec1e0056d023
Author: Ondrej Mosnacek <omosnace at redhat.com>
Date:   Tue Jul 9 13:11:24 2019 +0200

    ms/crypto: user - make NETLINK_CRYPTO work inside netns
    
    Currently, NETLINK_CRYPTO works only in the init network namespace. It
    doesn't make much sense to cut it out of the other network namespaces,
    so do the minor plumbing work necessary to make it work in any network
    namespace. Code inspired by net/core/sock_diag.c.
    
    Tested using kcapi-dgst from libkcapi [1]:
    Before:
        # unshare -n kcapi-dgst -c sha256 </dev/null | wc -c
        libkcapi - Error: Netlink error: sendmsg failed
        libkcapi - Error: Netlink error: sendmsg failed
        libkcapi - Error: NETLINK_CRYPTO: cannot obtain cipher information for hmac(sha512) (is required crypto_user.c patch missing? see documentation)
        0
    
    After:
        # unshare -n kcapi-dgst -c sha256 </dev/null | wc -c
        32
    
    [1] https://github.com/smuellerDD/libkcapi
    
    Signed-off-by: Ondrej Mosnacek <omosnace at redhat.com>
    Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
    
    Building kernel based on RHEL9.2 requires sha512hmac working which
    works through libkcapi which works via NETLINK_CRYPTO socket which were
    allowed only in init_net. So let's backport the patch which allows using
    them in nested netns as well.
    
    https://jira.vzint.dev/browse/PSBM-147375
    Cherry-picked from ms commit 91b05a7e7d80 ("crypto: user - make
    NETLINK_CRYPTO work inside netns")
    
    Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
 crypto/crypto_user.c        | 37 +++++++++++++++++++++++++------------
 include/net/net_namespace.h |  3 +++
 2 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index bbf7399a9461..e14b4fb69af4 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -22,9 +22,10 @@
 #include <linux/crypto.h>
 #include <linux/cryptouser.h>
 #include <linux/sched.h>
-#include <net/netlink.h>
 #include <linux/security.h>
+#include <net/netlink.h>
 #include <net/net_namespace.h>
+#include <net/sock.h>
 #include <crypto/internal/aead.h>
 #include <crypto/internal/skcipher.h>
 #include <crypto/akcipher.h>
@@ -36,9 +37,6 @@
 
 static DEFINE_MUTEX(crypto_cfg_mutex);
 
-/* The crypto netlink socket */
-static struct sock *crypto_nlsk;
-
 struct crypto_dump_info {
 	struct sk_buff *in_skb;
 	struct sk_buff *out_skb;
@@ -256,6 +254,7 @@ static int crypto_report_alg(struct crypto_alg *alg,
 static int crypto_report(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
 			 struct nlattr **attrs)
 {
+	struct net *net = sock_net(in_skb->sk);
 	struct crypto_user_alg *p = nlmsg_data(in_nlh);
 	struct crypto_alg *alg;
 	struct sk_buff *skb;
@@ -287,7 +286,7 @@ static int crypto_report(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
 		return err;
 	}
 
-	return nlmsg_unicast(crypto_nlsk, skb, NETLINK_CB(in_skb).portid);
+	return nlmsg_unicast(net->crypto_nlsk, skb, NETLINK_CB(in_skb).portid);
 }
 
 static int crypto_dump_report(struct sk_buff *skb, struct netlink_callback *cb)
@@ -521,6 +520,7 @@ static const struct crypto_link {
 
 static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
+	struct net *net = sock_net(skb->sk);
 	struct nlattr *attrs[CRYPTOCFGA_MAX+1];
 	const struct crypto_link *link;
 	int type, err;
@@ -553,7 +553,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 				.done = link->done,
 				.min_dump_alloc = dump_alloc,
 			};
-			err = netlink_dump_start(crypto_nlsk, skb, nlh, &c);
+			err = netlink_dump_start(net->crypto_nlsk, skb, nlh, &c);
 		}
 		up_read(&crypto_alg_sem);
 
@@ -578,22 +578,35 @@ static void crypto_netlink_rcv(struct sk_buff *skb)
 	mutex_unlock(&crypto_cfg_mutex);
 }
 
-static int __init crypto_user_init(void)
+static int __net_init crypto_netlink_init(struct net *net)
 {
 	struct netlink_kernel_cfg cfg = {
 		.input	= crypto_netlink_rcv,
 	};
 
-	crypto_nlsk = netlink_kernel_create(&init_net, NETLINK_CRYPTO, &cfg);
-	if (!crypto_nlsk)
-		return -ENOMEM;
+	net->crypto_nlsk = netlink_kernel_create(net, NETLINK_CRYPTO, &cfg);
+	return net->crypto_nlsk == NULL ? -ENOMEM : 0;
+}
 
-	return 0;
+static void __net_exit crypto_netlink_exit(struct net *net)
+{
+	netlink_kernel_release(net->crypto_nlsk);
+	net->crypto_nlsk = NULL;
+}
+
+static struct pernet_operations crypto_netlink_net_ops = {
+	.init = crypto_netlink_init,
+	.exit = crypto_netlink_exit,
+};
+
+static int __init crypto_user_init(void)
+{
+	return register_pernet_subsys(&crypto_netlink_net_ops);
 }
 
 static void __exit crypto_user_exit(void)
 {
-	netlink_kernel_release(crypto_nlsk);
+	unregister_pernet_subsys(&crypto_netlink_net_ops);
 }
 
 module_init(crypto_user_init);
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index fd9e0874ddce..d00dc43efd52 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -133,6 +133,9 @@ struct net {
 	struct netns_xfrm	xfrm;
 #endif
 	struct netns_ipvs	*ipvs;
+#if IS_ENABLED(CONFIG_CRYPTO_USER)
+	struct sock		*crypto_nlsk;
+#endif
 	struct sock		*diag_nlsk;
 	atomic_t		rt_genid;
 


More information about the Devel mailing list