[PATCH] Crypto_user: Make crypto user API available for all net ns

From: Christian Langrock
Date: Thu Jul 13 2017 - 10:22:54 EST


With this patch it's possible to use crypto user API form all
network namespaces, not only form the initial net ns.

Signed-off-by: Christian Langrock <christian.langrock@xxxxxxxxxxx>
---
crypto/crypto_user.c | 39 ++++++++++++++++++++++++++++++---------
include/net/net_namespace.h | 1 +
2 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 0dbe2be7..359ec2f 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -23,7 +23,7 @@
#include <linux/cryptouser.h>
#include <linux/sched.h>
#include <net/netlink.h>
-#include <linux/security.h>
+#include <net/sock.h>
#include <net/net_namespace.h>
#include <crypto/internal/skcipher.h>
#include <crypto/internal/rng.h>
@@ -36,9 +36,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;
@@ -257,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;
@@ -288,7 +286,7 @@ static int crypto_report(struct sk_buff *in_skb,
struct nlmsghdr *in_nlh,
if (err)
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)
@@ -486,6 +484,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;
@@ -515,7 +514,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);

@@ -540,22 +539,44 @@ 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_user_net_init(struct net *net)
{
+ struct sock *crypto_nlsk;
struct netlink_kernel_cfg cfg = {
.input = crypto_netlink_rcv,
};

- crypto_nlsk = netlink_kernel_create(&init_net, NETLINK_CRYPTO, &cfg);
+ crypto_nlsk = netlink_kernel_create(net, NETLINK_CRYPTO, &cfg);
if (!crypto_nlsk)
return -ENOMEM;

+ net->crypto_nlsk = crypto_nlsk;
+
+ return 0;
+}
+
+static void __net_exit crypto_user_net_exit(struct net *net)
+{
+ netlink_kernel_release(net->crypto_nlsk);
+ net->crypto_nlsk = NULL;
+}
+
+static struct pernet_operations crypto_user_net_ops = {
+ .init = crypto_user_net_init,
+ .exit = crypto_user_net_exit,
+};
+
+
+static int __init crypto_user_init(void)
+{
+ if (register_pernet_subsys(&crypto_user_net_ops))
+ panic("crypto_user_init: cannot initialize crypto_user\n");
return 0;
}

static void __exit crypto_user_exit(void)
{
- netlink_kernel_release(crypto_nlsk);
+ unregister_pernet_subsys(&crypto_user_net_ops);
}

module_init(crypto_user_init);
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 31a2b51..d5d831d 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -148,6 +148,7 @@ struct net {
#endif
struct sock *diag_nlsk;
atomic_t fnhe_genid;
+ struct sock *crypto_nlsk;
};

#include <linux/seq_file_net.h>
--
2.7.4


Attachment: 0x82EB6B5E.asc
Description: application/pgp-keys

Attachment: signature.asc
Description: OpenPGP digital signature