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>
This commit is contained in:
parent
31fb084c4e
commit
91b05a7e7d
|
@ -10,9 +10,10 @@
|
||||||
#include <linux/crypto.h>
|
#include <linux/crypto.h>
|
||||||
#include <linux/cryptouser.h>
|
#include <linux/cryptouser.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <net/netlink.h>
|
|
||||||
#include <linux/security.h>
|
#include <linux/security.h>
|
||||||
|
#include <net/netlink.h>
|
||||||
#include <net/net_namespace.h>
|
#include <net/net_namespace.h>
|
||||||
|
#include <net/sock.h>
|
||||||
#include <crypto/internal/skcipher.h>
|
#include <crypto/internal/skcipher.h>
|
||||||
#include <crypto/internal/rng.h>
|
#include <crypto/internal/rng.h>
|
||||||
#include <crypto/akcipher.h>
|
#include <crypto/akcipher.h>
|
||||||
|
@ -25,9 +26,6 @@
|
||||||
|
|
||||||
static DEFINE_MUTEX(crypto_cfg_mutex);
|
static DEFINE_MUTEX(crypto_cfg_mutex);
|
||||||
|
|
||||||
/* The crypto netlink socket */
|
|
||||||
struct sock *crypto_nlsk;
|
|
||||||
|
|
||||||
struct crypto_dump_info {
|
struct crypto_dump_info {
|
||||||
struct sk_buff *in_skb;
|
struct sk_buff *in_skb;
|
||||||
struct sk_buff *out_skb;
|
struct sk_buff *out_skb;
|
||||||
|
@ -186,6 +184,7 @@ out:
|
||||||
static int crypto_report(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
|
static int crypto_report(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
|
||||||
struct nlattr **attrs)
|
struct nlattr **attrs)
|
||||||
{
|
{
|
||||||
|
struct net *net = sock_net(in_skb->sk);
|
||||||
struct crypto_user_alg *p = nlmsg_data(in_nlh);
|
struct crypto_user_alg *p = nlmsg_data(in_nlh);
|
||||||
struct crypto_alg *alg;
|
struct crypto_alg *alg;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
@ -217,7 +216,7 @@ drop_alg:
|
||||||
if (err)
|
if (err)
|
||||||
return 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)
|
static int crypto_dump_report(struct sk_buff *skb, struct netlink_callback *cb)
|
||||||
|
@ -420,6 +419,7 @@ static const struct crypto_link {
|
||||||
static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
|
static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||||
struct netlink_ext_ack *extack)
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
|
struct net *net = sock_net(skb->sk);
|
||||||
struct nlattr *attrs[CRYPTOCFGA_MAX+1];
|
struct nlattr *attrs[CRYPTOCFGA_MAX+1];
|
||||||
const struct crypto_link *link;
|
const struct crypto_link *link;
|
||||||
int type, err;
|
int type, err;
|
||||||
|
@ -450,7 +450,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||||
.done = link->done,
|
.done = link->done,
|
||||||
.min_dump_alloc = min(dump_alloc, 65535UL),
|
.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;
|
return err;
|
||||||
|
@ -474,22 +474,35 @@ static void crypto_netlink_rcv(struct sk_buff *skb)
|
||||||
mutex_unlock(&crypto_cfg_mutex);
|
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 = {
|
struct netlink_kernel_cfg cfg = {
|
||||||
.input = crypto_netlink_rcv,
|
.input = crypto_netlink_rcv,
|
||||||
};
|
};
|
||||||
|
|
||||||
crypto_nlsk = netlink_kernel_create(&init_net, NETLINK_CRYPTO, &cfg);
|
net->crypto_nlsk = netlink_kernel_create(net, NETLINK_CRYPTO, &cfg);
|
||||||
if (!crypto_nlsk)
|
return net->crypto_nlsk == NULL ? -ENOMEM : 0;
|
||||||
return -ENOMEM;
|
}
|
||||||
|
|
||||||
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)
|
static void __exit crypto_user_exit(void)
|
||||||
{
|
{
|
||||||
netlink_kernel_release(crypto_nlsk);
|
unregister_pernet_subsys(&crypto_netlink_net_ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(crypto_user_init);
|
module_init(crypto_user_init);
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <linux/cryptouser.h>
|
#include <linux/cryptouser.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <net/netlink.h>
|
#include <net/netlink.h>
|
||||||
|
#include <net/sock.h>
|
||||||
#include <crypto/internal/skcipher.h>
|
#include <crypto/internal/skcipher.h>
|
||||||
#include <crypto/internal/rng.h>
|
#include <crypto/internal/rng.h>
|
||||||
#include <crypto/akcipher.h>
|
#include <crypto/akcipher.h>
|
||||||
|
@ -298,6 +299,7 @@ out:
|
||||||
int crypto_reportstat(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
|
int crypto_reportstat(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
|
||||||
struct nlattr **attrs)
|
struct nlattr **attrs)
|
||||||
{
|
{
|
||||||
|
struct net *net = sock_net(in_skb->sk);
|
||||||
struct crypto_user_alg *p = nlmsg_data(in_nlh);
|
struct crypto_user_alg *p = nlmsg_data(in_nlh);
|
||||||
struct crypto_alg *alg;
|
struct crypto_alg *alg;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
@ -329,7 +331,7 @@ drop_alg:
|
||||||
if (err)
|
if (err)
|
||||||
return 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
#include <net/netlink.h>
|
#include <net/netlink.h>
|
||||||
|
|
||||||
extern struct sock *crypto_nlsk;
|
|
||||||
|
|
||||||
struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p, int exact);
|
struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p, int exact);
|
||||||
|
|
||||||
#ifdef CONFIG_CRYPTO_STATS
|
#ifdef CONFIG_CRYPTO_STATS
|
||||||
|
|
|
@ -170,6 +170,9 @@ struct net {
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_XDP_SOCKETS
|
#ifdef CONFIG_XDP_SOCKETS
|
||||||
struct netns_xdp xdp;
|
struct netns_xdp xdp;
|
||||||
|
#endif
|
||||||
|
#if IS_ENABLED(CONFIG_CRYPTO_USER)
|
||||||
|
struct sock *crypto_nlsk;
|
||||||
#endif
|
#endif
|
||||||
struct sock *diag_nlsk;
|
struct sock *diag_nlsk;
|
||||||
atomic_t fnhe_genid;
|
atomic_t fnhe_genid;
|
||||||
|
|
Loading…
Reference in New Issue