Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=f2a77991a918218be4a3ac78250e7eba2282be59
Commit:     f2a77991a918218be4a3ac78250e7eba2282be59
Parent:     d44447229e35115675d166b51a52e512c281475c
Author:     Ursula Braun <[EMAIL PROTECTED]>
AuthorDate: Thu Feb 7 18:07:44 2008 -0800
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Thu Feb 7 18:07:44 2008 -0800

    [AF_IUCV]: defensive programming of iucv_callback_txdone
    
    The loop in iucv_callback_txdone presumes existence of an entry
    with msg->tag in the send_skb_q list. In error cases this
    assumption might be wrong and might cause an endless loop.
    Loop is rewritten to guarantee loop end in case of missing
    msg->tag entry in send_skb_q.
    
    Signed-off-by: Ursula Braun <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 net/iucv/af_iucv.c |   21 ++++++++++++++-------
 1 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index b3f5f84..fee22ca 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -1112,24 +1112,31 @@ static void iucv_callback_txdone(struct iucv_path *path,
                                 struct iucv_message *msg)
 {
        struct sock *sk = path->private;
-       struct sk_buff *this;
+       struct sk_buff *this = NULL;
        struct sk_buff_head *list = &iucv_sk(sk)->send_skb_q;
        struct sk_buff *list_skb = list->next;
        unsigned long flags;
 
-       if (list_skb) {
+       if (!skb_queue_empty(list)) {
                spin_lock_irqsave(&list->lock, flags);
 
-               do {
-                       this = list_skb;
+               while (list_skb != (struct sk_buff *)list) {
+                       if (!memcmp(&msg->tag, list_skb->cb, 4)) {
+                               this = list_skb;
+                               break;
+                       }
                        list_skb = list_skb->next;
-               } while (memcmp(&msg->tag, this->cb, 4) && list_skb);
-               __skb_unlink(this, list);
+               }
+               if (this)
+                       __skb_unlink(this, list);
 
                spin_unlock_irqrestore(&list->lock, flags);
 
-               kfree_skb(this);
+               if (this)
+                       kfree_skb(this);
        }
+       if (!this)
+               printk(KERN_ERR "AF_IUCV msg tag %u not found\n", msg->tag);
 
        if (sk->sk_state == IUCV_CLOSING) {
                if (skb_queue_empty(&iucv_sk(sk)->send_skb_q)) {
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to