aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOndrej Mosnacek <omosnace@redhat.com>2019-07-09 07:11:24 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2019-07-26 08:08:02 -0400
commit91b05a7e7d8033a90a64f5fc0e3808db423e420a (patch)
treeb883a067a751829e504a48127b80546e8e22efc6
parent31fb084c4eb556fac30115d99bc518c7944887d2 (diff)
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@redhat.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--crypto/crypto_user_base.c37
-rw-r--r--crypto/crypto_user_stat.c4
-rw-r--r--include/crypto/internal/cryptouser.h2
-rw-r--r--include/net/net_namespace.h3
4 files changed, 31 insertions, 15 deletions
diff --git a/crypto/crypto_user_base.c b/crypto/crypto_user_base.c
index c65e39005ce2..910e0b46012e 100644
--- a/crypto/crypto_user_base.c
+++ b/crypto/crypto_user_base.c
@@ -10,9 +10,10 @@
10#include <linux/crypto.h> 10#include <linux/crypto.h>
11#include <linux/cryptouser.h> 11#include <linux/cryptouser.h>
12#include <linux/sched.h> 12#include <linux/sched.h>
13#include <net/netlink.h>
14#include <linux/security.h> 13#include <linux/security.h>
14#include <net/netlink.h>
15#include <net/net_namespace.h> 15#include <net/net_namespace.h>
16#include <net/sock.h>
16#include <crypto/internal/skcipher.h> 17#include <crypto/internal/skcipher.h>
17#include <crypto/internal/rng.h> 18#include <crypto/internal/rng.h>
18#include <crypto/akcipher.h> 19#include <crypto/akcipher.h>
@@ -25,9 +26,6 @@
25 26
26static DEFINE_MUTEX(crypto_cfg_mutex); 27static DEFINE_MUTEX(crypto_cfg_mutex);
27 28
28/* The crypto netlink socket */
29struct sock *crypto_nlsk;
30
31struct crypto_dump_info { 29struct crypto_dump_info {
32 struct sk_buff *in_skb; 30 struct sk_buff *in_skb;
33 struct sk_buff *out_skb; 31 struct sk_buff *out_skb;
@@ -186,6 +184,7 @@ out:
186static int crypto_report(struct sk_buff *in_skb, struct nlmsghdr *in_nlh, 184static int crypto_report(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
187 struct nlattr **attrs) 185 struct nlattr **attrs)
188{ 186{
187 struct net *net = sock_net(in_skb->sk);
189 struct crypto_user_alg *p = nlmsg_data(in_nlh); 188 struct crypto_user_alg *p = nlmsg_data(in_nlh);
190 struct crypto_alg *alg; 189 struct crypto_alg *alg;
191 struct sk_buff *skb; 190 struct sk_buff *skb;
@@ -217,7 +216,7 @@ drop_alg:
217 if (err) 216 if (err)
218 return err; 217 return err;
219 218
220 return nlmsg_unicast(crypto_nlsk, skb, NETLINK_CB(in_skb).portid); 219 return nlmsg_unicast(net->crypto_nlsk, skb, NETLINK_CB(in_skb).portid);
221} 220}
222 221
223static int crypto_dump_report(struct sk_buff *skb, struct netlink_callback *cb) 222static int crypto_dump_report(struct sk_buff *skb, struct netlink_callback *cb)
@@ -420,6 +419,7 @@ static const struct crypto_link {
420static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, 419static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
421 struct netlink_ext_ack *extack) 420 struct netlink_ext_ack *extack)
422{ 421{
422 struct net *net = sock_net(skb->sk);
423 struct nlattr *attrs[CRYPTOCFGA_MAX+1]; 423 struct nlattr *attrs[CRYPTOCFGA_MAX+1];
424 const struct crypto_link *link; 424 const struct crypto_link *link;
425 int type, err; 425 int type, err;
@@ -450,7 +450,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
450 .done = link->done, 450 .done = link->done,
451 .min_dump_alloc = min(dump_alloc, 65535UL), 451 .min_dump_alloc = min(dump_alloc, 65535UL),
452 }; 452 };
453 err = netlink_dump_start(crypto_nlsk, skb, nlh, &c); 453 err = netlink_dump_start(net->crypto_nlsk, skb, nlh, &c);
454 } 454 }
455 455
456 return err; 456 return err;
@@ -474,22 +474,35 @@ static void crypto_netlink_rcv(struct sk_buff *skb)
474 mutex_unlock(&crypto_cfg_mutex); 474 mutex_unlock(&crypto_cfg_mutex);
475} 475}
476 476
477static int __init crypto_user_init(void) 477static int __net_init crypto_netlink_init(struct net *net)
478{ 478{
479 struct netlink_kernel_cfg cfg = { 479 struct netlink_kernel_cfg cfg = {
480 .input = crypto_netlink_rcv, 480 .input = crypto_netlink_rcv,
481 }; 481 };
482 482
483 crypto_nlsk = netlink_kernel_create(&init_net, NETLINK_CRYPTO, &cfg); 483 net->crypto_nlsk = netlink_kernel_create(net, NETLINK_CRYPTO, &cfg);
484 if (!crypto_nlsk) 484 return net->crypto_nlsk == NULL ? -ENOMEM : 0;
485 return -ENOMEM; 485}
486 486
487 return 0; 487static void __net_exit crypto_netlink_exit(struct net *net)
488{
489 netlink_kernel_release(net->crypto_nlsk);
490 net->crypto_nlsk = NULL;
491}
492
493static struct pernet_operations crypto_netlink_net_ops = {
494 .init = crypto_netlink_init,
495 .exit = crypto_netlink_exit,
496};
497
498static int __init crypto_user_init(void)
499{
500 return register_pernet_subsys(&crypto_netlink_net_ops);
488} 501}
489 502
490static void __exit crypto_user_exit(void) 503static void __exit crypto_user_exit(void)
491{ 504{
492 netlink_kernel_release(crypto_nlsk); 505 unregister_pernet_subsys(&crypto_netlink_net_ops);
493} 506}
494 507
495module_init(crypto_user_init); 508module_init(crypto_user_init);
diff --git a/crypto/crypto_user_stat.c b/crypto/crypto_user_stat.c
index a03f326a63d3..8bad88413de1 100644
--- a/crypto/crypto_user_stat.c
+++ b/crypto/crypto_user_stat.c
@@ -10,6 +10,7 @@
10#include <linux/cryptouser.h> 10#include <linux/cryptouser.h>
11#include <linux/sched.h> 11#include <linux/sched.h>
12#include <net/netlink.h> 12#include <net/netlink.h>
13#include <net/sock.h>
13#include <crypto/internal/skcipher.h> 14#include <crypto/internal/skcipher.h>
14#include <crypto/internal/rng.h> 15#include <crypto/internal/rng.h>
15#include <crypto/akcipher.h> 16#include <crypto/akcipher.h>
@@ -298,6 +299,7 @@ out:
298int crypto_reportstat(struct sk_buff *in_skb, struct nlmsghdr *in_nlh, 299int crypto_reportstat(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
299 struct nlattr **attrs) 300 struct nlattr **attrs)
300{ 301{
302 struct net *net = sock_net(in_skb->sk);
301 struct crypto_user_alg *p = nlmsg_data(in_nlh); 303 struct crypto_user_alg *p = nlmsg_data(in_nlh);
302 struct crypto_alg *alg; 304 struct crypto_alg *alg;
303 struct sk_buff *skb; 305 struct sk_buff *skb;
@@ -329,7 +331,7 @@ drop_alg:
329 if (err) 331 if (err)
330 return err; 332 return err;
331 333
332 return nlmsg_unicast(crypto_nlsk, skb, NETLINK_CB(in_skb).portid); 334 return nlmsg_unicast(net->crypto_nlsk, skb, NETLINK_CB(in_skb).portid);
333} 335}
334 336
335MODULE_LICENSE("GPL"); 337MODULE_LICENSE("GPL");
diff --git a/include/crypto/internal/cryptouser.h b/include/crypto/internal/cryptouser.h
index 8c602b187c58..40623f4457df 100644
--- a/include/crypto/internal/cryptouser.h
+++ b/include/crypto/internal/cryptouser.h
@@ -1,8 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2#include <net/netlink.h> 2#include <net/netlink.h>
3 3
4extern struct sock *crypto_nlsk;
5
6struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p, int exact); 4struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p, int exact);
7 5
8#ifdef CONFIG_CRYPTO_STATS 6#ifdef CONFIG_CRYPTO_STATS
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 4a9da951a794..85bc1de5dece 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -171,6 +171,9 @@ struct net {
171#ifdef CONFIG_XDP_SOCKETS 171#ifdef CONFIG_XDP_SOCKETS
172 struct netns_xdp xdp; 172 struct netns_xdp xdp;
173#endif 173#endif
174#if IS_ENABLED(CONFIG_CRYPTO_USER)
175 struct sock *crypto_nlsk;
176#endif
174 struct sock *diag_nlsk; 177 struct sock *diag_nlsk;
175 atomic_t fnhe_genid; 178 atomic_t fnhe_genid;
176} __randomize_layout; 179} __randomize_layout;