There is same problem found in linux 4.19.y as upstream commit. The 
changes of crypto_user_* and cryptouser.h files from upstream patch are merged 
into 
crypto/crypto_user.c for backporting.

Upstream commit:
    commit 91b05a7e7d8033a90a64f5fc0e3808db423e420a
    Author: Ondrej Mosnacek <omosn...@redhat.com>
    Date:   Tue,  9 Jul 2019 13:11:24 +0200

    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.

    Signed-off-by: Ondrej Mosnacek <omosn...@redhat.com>
    Signed-off-by: default avatarHerbert Xu <herb...@gondor.apana.org.au>

Signed-off-by: Jianmin Wang <jian...@iscas.ac.cn>
---
 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 f847c181a39c..3f9e8e6e96f2 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -22,8 +22,9 @@
 #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/sock.h>
 #include <net/net_namespace.h>
 #include <crypto/internal/skcipher.h>
 #include <crypto/internal/rng.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;
@@ -260,6 +258,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;
@@ -293,7 +292,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)
@@ -494,6 +493,7 @@ static const struct crypto_link {
 static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
                               struct netlink_ext_ack *extack)
 {
+       struct net *net = sock_net(skb->sk);
        struct nlattr *attrs[CRYPTOCFGA_MAX+1];
        const struct crypto_link *link;
        int type, err;
@@ -524,7 +524,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct 
nlmsghdr *nlh,
                                .done = link->done,
                                .min_dump_alloc = min(dump_alloc, 65535UL),
                        };
-                       err = netlink_dump_start(crypto_nlsk, skb, nlh, &c);
+                       err = netlink_dump_start(net->crypto_nlsk, skb, nlh, 
&c);
                }
 
                return err;
@@ -548,22 +548,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 5007eaba207d..ab5e8fd011f9 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -158,6 +158,9 @@ struct net {
 #endif
 #if IS_ENABLED(CONFIG_CAN)
        struct netns_can        can;
+#endif
+#if IS_ENABLED(CONFIG_CRYPTO_USER)
+       struct sock             *crypto_nlsk;
 #endif
        struct sock             *diag_nlsk;
        atomic_t                fnhe_genid;
-- 
2.27.0

Reply via email to