[XFRM]: nlmsg length not computed correctly in the presence of subpolicies
authorJamal Hadi Salim <hadi@cyberus.ca>
Sun, 19 Nov 2006 22:55:30 +0000 (14:55 -0800)
committerDavid S. Miller <davem@sunset.davemloft.net>
Wed, 22 Nov 2006 00:16:35 +0000 (16:16 -0800)
I actually dont have a test case for these; i just found them by
inspection. Refer to patch "[XFRM]: Sub-policies broke policy events"
for more info

Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
Acked-by: Masahide NAKAMURA <nakam@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/xfrm/xfrm_user.c

index 2dae1c1ea362503c98d67d752af331c11d745e38..c4cde57d9216cc82b529baf8009600583f4a078d 100644 (file)
@@ -1927,6 +1927,9 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt,
        len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
        len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire));
        len += RTA_SPACE(xfrm_user_sec_ctx_size(xp));
+#ifdef CONFIG_XFRM_SUB_POLICY
+       len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
+#endif
        skb = alloc_skb(len, GFP_ATOMIC);
        if (skb == NULL)
                return -ENOMEM;
@@ -2034,6 +2037,9 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_eve
        len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
        len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire));
        len += RTA_SPACE(xfrm_user_sec_ctx_size(xp));
+#ifdef CONFIG_XFRM_SUB_POLICY
+       len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
+#endif
        skb = alloc_skb(len, GFP_ATOMIC);
        if (skb == NULL)
                return -ENOMEM;
@@ -2109,10 +2115,12 @@ static int xfrm_notify_policy_flush(struct km_event *c)
        struct nlmsghdr *nlh;
        struct sk_buff *skb;
        unsigned char *b;
+       int len = 0;
 #ifdef CONFIG_XFRM_SUB_POLICY
        struct xfrm_userpolicy_type upt;
+       len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
 #endif
-       int len = NLMSG_LENGTH(0);
+       len += NLMSG_LENGTH(0);
 
        skb = alloc_skb(len, GFP_ATOMIC);
        if (skb == NULL)