]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/xfrm/xfrm_user.c
[PATCH] acpi build fix: x86 setup.c
[mirror_ubuntu-bionic-kernel.git] / net / xfrm / xfrm_user.c
index e8740a4a1d7845704cabda0f0f6f4891bf683761..97509011c274c7c0f1c698acc24fed817f861a2d 100644 (file)
@@ -34,14 +34,21 @@ static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t type)
 {
        struct rtattr *rt = xfrma[type - 1];
        struct xfrm_algo *algp;
+       int len;
 
        if (!rt)
                return 0;
 
-       if ((rt->rta_len - sizeof(*rt)) < sizeof(*algp))
+       len = (rt->rta_len - sizeof(*rt)) - sizeof(*algp);
+       if (len < 0)
                return -EINVAL;
 
        algp = RTA_DATA(rt);
+
+       len -= (algp->alg_key_len + 7U) / 8; 
+       if (len < 0)
+               return -EINVAL;
+
        switch (type) {
        case XFRMA_ALG_AUTH:
                if (!algp->alg_key_len &&
@@ -162,6 +169,7 @@ static int attach_one_algo(struct xfrm_algo **algpp, u8 *props,
        struct rtattr *rta = u_arg;
        struct xfrm_algo *p, *ualg;
        struct xfrm_algo_desc *algo;
+       int len;
 
        if (!rta)
                return 0;
@@ -173,11 +181,12 @@ static int attach_one_algo(struct xfrm_algo **algpp, u8 *props,
                return -ENOSYS;
        *props = algo->desc.sadb_alg_id;
 
-       p = kmalloc(sizeof(*ualg) + ualg->alg_key_len, GFP_KERNEL);
+       len = sizeof(*ualg) + (ualg->alg_key_len + 7U) / 8;
+       p = kmalloc(len, GFP_KERNEL);
        if (!p)
                return -ENOMEM;
 
-       memcpy(p, ualg, sizeof(*ualg) + ualg->alg_key_len);
+       memcpy(p, ualg, len);
        *algpp = p;
        return 0;
 }
@@ -1024,8 +1033,10 @@ static void xfrm_netlink_rcv(struct sock *sk, int len)
                                if (skb->len)
                                        skb_queue_head(&sk->sk_receive_queue,
                                                       skb);
-                               else
+                               else {
                                        kfree_skb(skb);
+                                       qlen--;
+                               }
                                break;
                        }
                        kfree_skb(skb);