[NETLINK]: Fix infinite loops in synchronous netlink changes.
[linux-2.6.git] / net / xfrm / xfrm_user.c
index 52b5843937c582f15ffca93f84440ff73d4255d2..e8740a4a1d7845704cabda0f0f6f4891bf683761 100644 (file)
@@ -1008,12 +1008,18 @@ static int xfrm_user_rcv_skb(struct sk_buff *skb)
 
 static void xfrm_netlink_rcv(struct sock *sk, int len)
 {
+       unsigned int qlen = skb_queue_len(&sk->sk_receive_queue);
+
        do {
                struct sk_buff *skb;
 
                down(&xfrm_cfg_sem);
 
-               while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
+               if (qlen > skb_queue_len(&sk->sk_receive_queue))
+                       qlen = skb_queue_len(&sk->sk_receive_queue);
+
+               for (; qlen; qlen--) {
+                       skb = skb_dequeue(&sk->sk_receive_queue);
                        if (xfrm_user_rcv_skb(skb)) {
                                if (skb->len)
                                        skb_queue_head(&sk->sk_receive_queue,
@@ -1027,7 +1033,7 @@ static void xfrm_netlink_rcv(struct sock *sk, int len)
 
                up(&xfrm_cfg_sem);
 
-       } while (xfrm_nl && xfrm_nl->sk_receive_queue.qlen);
+       } while (qlen);
 }
 
 static int build_expire(struct sk_buff *skb, struct xfrm_state *x, int hard)