Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next
Steffen Klassert says: ==================== pull request (net-next): ipsec-next 2017-06-23 1) Use memdup_user to spmlify xfrm_user_policy. From Geliang Tang. 2) Make xfrm_dev_register static to silence a sparse warning. From Wei Yongjun. 3) Use crypto_memneq to check the ICV in the AH protocol. From Sabrina Dubroca. 4) Remove some unused variables in esp6. From Stephen Hemminger. 5) Extend XFRM MIGRATE to allow to change the UDP encapsulation port. From Antony Antony. 6) Include the UDP encapsulation port to km_migrate announcements. From Antony Antony. Please pull or let me know if there are problems. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
93bbbfbb4a
9 changed files with 74 additions and 48 deletions
|
@ -631,7 +631,8 @@ struct xfrm_mgr {
|
|||
u8 dir, u8 type,
|
||||
const struct xfrm_migrate *m,
|
||||
int num_bundles,
|
||||
const struct xfrm_kmaddress *k);
|
||||
const struct xfrm_kmaddress *k,
|
||||
const struct xfrm_encap_tmpl *encap);
|
||||
bool (*is_alive)(const struct km_event *c);
|
||||
};
|
||||
|
||||
|
@ -1675,13 +1676,16 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
|
|||
#ifdef CONFIG_XFRM_MIGRATE
|
||||
int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
|
||||
const struct xfrm_migrate *m, int num_bundles,
|
||||
const struct xfrm_kmaddress *k);
|
||||
const struct xfrm_kmaddress *k,
|
||||
const struct xfrm_encap_tmpl *encap);
|
||||
struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net);
|
||||
struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
|
||||
struct xfrm_migrate *m);
|
||||
struct xfrm_migrate *m,
|
||||
struct xfrm_encap_tmpl *encap);
|
||||
int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
|
||||
struct xfrm_migrate *m, int num_bundles,
|
||||
struct xfrm_kmaddress *k, struct net *net);
|
||||
struct xfrm_kmaddress *k, struct net *net,
|
||||
struct xfrm_encap_tmpl *encap);
|
||||
#endif
|
||||
|
||||
int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#define pr_fmt(fmt) "IPsec: " fmt
|
||||
|
||||
#include <crypto/algapi.h>
|
||||
#include <crypto/hash.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/module.h>
|
||||
|
@ -279,7 +280,7 @@ static void ah_input_done(struct crypto_async_request *base, int err)
|
|||
auth_data = ah_tmp_auth(work_iph, ihl);
|
||||
icv = ah_tmp_icv(ahp->ahash, auth_data, ahp->icv_trunc_len);
|
||||
|
||||
err = memcmp(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG: 0;
|
||||
err = crypto_memneq(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG : 0;
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
|
@ -417,7 +418,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
|
|||
goto out_free;
|
||||
}
|
||||
|
||||
err = memcmp(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG: 0;
|
||||
err = crypto_memneq(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG : 0;
|
||||
if (err)
|
||||
goto out_free;
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#define pr_fmt(fmt) "IPv6: " fmt
|
||||
|
||||
#include <crypto/algapi.h>
|
||||
#include <crypto/hash.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -483,7 +484,7 @@ static void ah6_input_done(struct crypto_async_request *base, int err)
|
|||
auth_data = ah_tmp_auth(work_iph, hdr_len);
|
||||
icv = ah_tmp_icv(ahp->ahash, auth_data, ahp->icv_trunc_len);
|
||||
|
||||
err = memcmp(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG : 0;
|
||||
err = crypto_memneq(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG : 0;
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
|
@ -631,7 +632,7 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
|
|||
goto out_free;
|
||||
}
|
||||
|
||||
err = memcmp(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG : 0;
|
||||
err = crypto_memneq(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG : 0;
|
||||
if (err)
|
||||
goto out_free;
|
||||
|
||||
|
|
|
@ -118,7 +118,6 @@ static inline struct scatterlist *esp_req_sg(struct crypto_aead *aead,
|
|||
|
||||
static void esp_ssg_unref(struct xfrm_state *x, void *tmp)
|
||||
{
|
||||
__be32 *seqhi;
|
||||
struct crypto_aead *aead = x->data;
|
||||
int seqhilen = 0;
|
||||
u8 *iv;
|
||||
|
@ -128,7 +127,6 @@ static void esp_ssg_unref(struct xfrm_state *x, void *tmp)
|
|||
if (x->props.flags & XFRM_STATE_ESN)
|
||||
seqhilen += sizeof(__be32);
|
||||
|
||||
seqhi = esp_tmp_seqhi(tmp);
|
||||
iv = esp_tmp_iv(aead, tmp, seqhilen);
|
||||
req = esp_tmp_req(aead, iv);
|
||||
|
||||
|
@ -224,12 +222,9 @@ int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
|
|||
u8 *vaddr;
|
||||
int nfrags;
|
||||
struct page *page;
|
||||
struct ip_esp_hdr *esph;
|
||||
struct sk_buff *trailer;
|
||||
int tailen = esp->tailen;
|
||||
|
||||
esph = ip_esp_hdr(skb);
|
||||
|
||||
if (!skb_cloned(skb)) {
|
||||
if (tailen <= skb_availroom(skb)) {
|
||||
nfrags = 1;
|
||||
|
|
|
@ -2589,7 +2589,7 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb,
|
|||
}
|
||||
|
||||
return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i,
|
||||
kma ? &k : NULL, net);
|
||||
kma ? &k : NULL, net, NULL);
|
||||
|
||||
out:
|
||||
return err;
|
||||
|
@ -3488,7 +3488,8 @@ static int set_ipsecrequest(struct sk_buff *skb,
|
|||
#ifdef CONFIG_NET_KEY_MIGRATE
|
||||
static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
|
||||
const struct xfrm_migrate *m, int num_bundles,
|
||||
const struct xfrm_kmaddress *k)
|
||||
const struct xfrm_kmaddress *k,
|
||||
const struct xfrm_encap_tmpl *encap)
|
||||
{
|
||||
int i;
|
||||
int sasize_sel;
|
||||
|
@ -3598,7 +3599,8 @@ err:
|
|||
#else
|
||||
static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
|
||||
const struct xfrm_migrate *m, int num_bundles,
|
||||
const struct xfrm_kmaddress *k)
|
||||
const struct xfrm_kmaddress *k,
|
||||
const struct xfrm_encap_tmpl *encap)
|
||||
{
|
||||
return -ENOPROTOOPT;
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ ok:
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(xfrm_dev_offload_ok);
|
||||
|
||||
int xfrm_dev_register(struct net_device *dev)
|
||||
static int xfrm_dev_register(struct net_device *dev)
|
||||
{
|
||||
if ((dev->features & NETIF_F_HW_ESP) && !dev->xfrmdev_ops)
|
||||
return NOTIFY_BAD;
|
||||
|
|
|
@ -3279,11 +3279,6 @@ static int xfrm_migrate_check(const struct xfrm_migrate *m, int num_migrate)
|
|||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < num_migrate; i++) {
|
||||
if (xfrm_addr_equal(&m[i].old_daddr, &m[i].new_daddr,
|
||||
m[i].old_family) &&
|
||||
xfrm_addr_equal(&m[i].old_saddr, &m[i].new_saddr,
|
||||
m[i].old_family))
|
||||
return -EINVAL;
|
||||
if (xfrm_addr_any(&m[i].new_daddr, m[i].new_family) ||
|
||||
xfrm_addr_any(&m[i].new_saddr, m[i].new_family))
|
||||
return -EINVAL;
|
||||
|
@ -3307,7 +3302,8 @@ static int xfrm_migrate_check(const struct xfrm_migrate *m, int num_migrate)
|
|||
|
||||
int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
|
||||
struct xfrm_migrate *m, int num_migrate,
|
||||
struct xfrm_kmaddress *k, struct net *net)
|
||||
struct xfrm_kmaddress *k, struct net *net,
|
||||
struct xfrm_encap_tmpl *encap)
|
||||
{
|
||||
int i, err, nx_cur = 0, nx_new = 0;
|
||||
struct xfrm_policy *pol = NULL;
|
||||
|
@ -3330,7 +3326,8 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
|
|||
if ((x = xfrm_migrate_state_find(mp, net))) {
|
||||
x_cur[nx_cur] = x;
|
||||
nx_cur++;
|
||||
if ((xc = xfrm_state_migrate(x, mp))) {
|
||||
xc = xfrm_state_migrate(x, mp, encap);
|
||||
if (xc) {
|
||||
x_new[nx_new] = xc;
|
||||
nx_new++;
|
||||
} else {
|
||||
|
@ -3351,7 +3348,7 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
|
|||
}
|
||||
|
||||
/* Stage 5 - announce */
|
||||
km_migrate(sel, dir, type, m, num_migrate, k);
|
||||
km_migrate(sel, dir, type, m, num_migrate, k, encap);
|
||||
|
||||
xfrm_pol_put(pol);
|
||||
|
||||
|
|
|
@ -1309,7 +1309,8 @@ out:
|
|||
EXPORT_SYMBOL(xfrm_state_add);
|
||||
|
||||
#ifdef CONFIG_XFRM_MIGRATE
|
||||
static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig)
|
||||
static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig,
|
||||
struct xfrm_encap_tmpl *encap)
|
||||
{
|
||||
struct net *net = xs_net(orig);
|
||||
struct xfrm_state *x = xfrm_state_alloc(net);
|
||||
|
@ -1351,8 +1352,14 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig)
|
|||
}
|
||||
x->props.calgo = orig->props.calgo;
|
||||
|
||||
if (orig->encap) {
|
||||
x->encap = kmemdup(orig->encap, sizeof(*x->encap), GFP_KERNEL);
|
||||
if (encap || orig->encap) {
|
||||
if (encap)
|
||||
x->encap = kmemdup(encap, sizeof(*x->encap),
|
||||
GFP_KERNEL);
|
||||
else
|
||||
x->encap = kmemdup(orig->encap, sizeof(*x->encap),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!x->encap)
|
||||
goto error;
|
||||
}
|
||||
|
@ -1442,11 +1449,12 @@ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *n
|
|||
EXPORT_SYMBOL(xfrm_migrate_state_find);
|
||||
|
||||
struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
|
||||
struct xfrm_migrate *m)
|
||||
struct xfrm_migrate *m,
|
||||
struct xfrm_encap_tmpl *encap)
|
||||
{
|
||||
struct xfrm_state *xc;
|
||||
|
||||
xc = xfrm_state_clone(x);
|
||||
xc = xfrm_state_clone(x, encap);
|
||||
if (!xc)
|
||||
return NULL;
|
||||
|
||||
|
@ -1958,7 +1966,8 @@ EXPORT_SYMBOL(km_policy_expired);
|
|||
#ifdef CONFIG_XFRM_MIGRATE
|
||||
int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
|
||||
const struct xfrm_migrate *m, int num_migrate,
|
||||
const struct xfrm_kmaddress *k)
|
||||
const struct xfrm_kmaddress *k,
|
||||
const struct xfrm_encap_tmpl *encap)
|
||||
{
|
||||
int err = -EINVAL;
|
||||
int ret;
|
||||
|
@ -1967,7 +1976,8 @@ int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
|
|||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(km, &xfrm_km_list, list) {
|
||||
if (km->migrate) {
|
||||
ret = km->migrate(sel, dir, type, m, num_migrate, k);
|
||||
ret = km->migrate(sel, dir, type, m, num_migrate, k,
|
||||
encap);
|
||||
if (!ret)
|
||||
err = ret;
|
||||
}
|
||||
|
@ -2025,13 +2035,9 @@ int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen
|
|||
if (optlen <= 0 || optlen > PAGE_SIZE)
|
||||
return -EMSGSIZE;
|
||||
|
||||
data = kmalloc(optlen, GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
err = -EFAULT;
|
||||
if (copy_from_user(data, optval, optlen))
|
||||
goto out;
|
||||
data = memdup_user(optval, optlen);
|
||||
if (IS_ERR(data))
|
||||
return PTR_ERR(data);
|
||||
|
||||
err = -EINVAL;
|
||||
rcu_read_lock();
|
||||
|
@ -2049,7 +2055,6 @@ int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen
|
|||
err = 0;
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(data);
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -2243,6 +2243,7 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
int err;
|
||||
int n = 0;
|
||||
struct net *net = sock_net(skb->sk);
|
||||
struct xfrm_encap_tmpl *encap = NULL;
|
||||
|
||||
if (attrs[XFRMA_MIGRATE] == NULL)
|
||||
return -EINVAL;
|
||||
|
@ -2260,9 +2261,18 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
if (!n)
|
||||
return 0;
|
||||
|
||||
xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net);
|
||||
if (attrs[XFRMA_ENCAP]) {
|
||||
encap = kmemdup(nla_data(attrs[XFRMA_ENCAP]),
|
||||
sizeof(*encap), GFP_KERNEL);
|
||||
if (!encap)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err = xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net, encap);
|
||||
|
||||
kfree(encap);
|
||||
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
|
@ -2304,17 +2314,20 @@ static int copy_to_user_kmaddress(const struct xfrm_kmaddress *k, struct sk_buff
|
|||
return nla_put(skb, XFRMA_KMADDRESS, sizeof(uk), &uk);
|
||||
}
|
||||
|
||||
static inline size_t xfrm_migrate_msgsize(int num_migrate, int with_kma)
|
||||
static inline size_t xfrm_migrate_msgsize(int num_migrate, int with_kma,
|
||||
int with_encp)
|
||||
{
|
||||
return NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_id))
|
||||
+ (with_kma ? nla_total_size(sizeof(struct xfrm_kmaddress)) : 0)
|
||||
+ (with_encp ? nla_total_size(sizeof(struct xfrm_encap_tmpl)) : 0)
|
||||
+ nla_total_size(sizeof(struct xfrm_user_migrate) * num_migrate)
|
||||
+ userpolicy_type_attrsize();
|
||||
}
|
||||
|
||||
static int build_migrate(struct sk_buff *skb, const struct xfrm_migrate *m,
|
||||
int num_migrate, const struct xfrm_kmaddress *k,
|
||||
const struct xfrm_selector *sel, u8 dir, u8 type)
|
||||
const struct xfrm_selector *sel,
|
||||
const struct xfrm_encap_tmpl *encap, u8 dir, u8 type)
|
||||
{
|
||||
const struct xfrm_migrate *mp;
|
||||
struct xfrm_userpolicy_id *pol_id;
|
||||
|
@ -2336,6 +2349,11 @@ static int build_migrate(struct sk_buff *skb, const struct xfrm_migrate *m,
|
|||
if (err)
|
||||
goto out_cancel;
|
||||
}
|
||||
if (encap) {
|
||||
err = nla_put(skb, XFRMA_ENCAP, sizeof(*encap), encap);
|
||||
if (err)
|
||||
goto out_cancel;
|
||||
}
|
||||
err = copy_to_user_policy_type(type, skb);
|
||||
if (err)
|
||||
goto out_cancel;
|
||||
|
@ -2355,17 +2373,19 @@ out_cancel:
|
|||
|
||||
static int xfrm_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
|
||||
const struct xfrm_migrate *m, int num_migrate,
|
||||
const struct xfrm_kmaddress *k)
|
||||
const struct xfrm_kmaddress *k,
|
||||
const struct xfrm_encap_tmpl *encap)
|
||||
{
|
||||
struct net *net = &init_net;
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = nlmsg_new(xfrm_migrate_msgsize(num_migrate, !!k), GFP_ATOMIC);
|
||||
skb = nlmsg_new(xfrm_migrate_msgsize(num_migrate, !!k, !!encap),
|
||||
GFP_ATOMIC);
|
||||
if (skb == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
/* build migrate */
|
||||
if (build_migrate(skb, m, num_migrate, k, sel, dir, type) < 0)
|
||||
if (build_migrate(skb, m, num_migrate, k, sel, encap, dir, type) < 0)
|
||||
BUG();
|
||||
|
||||
return xfrm_nlmsg_multicast(net, skb, 0, XFRMNLGRP_MIGRATE);
|
||||
|
@ -2373,7 +2393,8 @@ static int xfrm_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
|
|||
#else
|
||||
static int xfrm_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
|
||||
const struct xfrm_migrate *m, int num_migrate,
|
||||
const struct xfrm_kmaddress *k)
|
||||
const struct xfrm_kmaddress *k,
|
||||
const struct xfrm_encap_tmpl *encap)
|
||||
{
|
||||
return -ENOPROTOOPT;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue