Magellan Linux

Annotation of /trunk/kernel26-magellan/patches-2.6.16-r12/0130-2.6.16.15-SCTP-infinite-recursion-CVE-2006-2274.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 72 - (hide annotations) (download)
Mon Jun 5 09:25:38 2006 UTC (18 years ago) by niro
File size: 2773 byte(s)
ver bump to 2.6.16-r12:
- updated to linux-2.6.16.19
- updated to ck11

1 niro 72 From: Vladislav Yasevich <vladsilav.yasevich@hp.com>
2     Date: Sat, 6 May 2006 00:03:49 +0000 (-0700)
3     Subject: [PATCH] SCTP: Prevent possible infinite recursion with multiple bundled DATA. (CVE ...
4     X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/stable/linux-2.6.16.y.git;a=commitdiff;h=25958c671804a3829d822fc3ccc3eff534b1aaa0
5    
6     [PATCH] SCTP: Prevent possible infinite recursion with multiple bundled DATA. (CVE-2006-2274)
7    
8     There is a rare situation that causes lksctp to go into infinite recursion
9     and crash the system. The trigger is a packet that contains at least the
10     first two DATA fragments of a message bundled together. The recursion is
11     triggered when the user data buffer is smaller that the full data message.
12     The problem is that we clone the skb for every fragment in the message.
13     When reassembling the full message, we try to link skbs from the "first
14     fragment" clone using the frag_list. However, since the frag_list is shared
15     between two clones in this rare situation, we end up setting the frag_list
16     pointer of the second fragment to point to itself. This causes
17     sctp_skb_pull() to potentially recurse indefinitely.
18    
19     Proposed solution is to make a copy of the skb when attempting to link
20     things using frag_list.
21    
22     Signed-off-by: Vladislav Yasevich <vladsilav.yasevich@hp.com>
23     Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
24     Signed-off-by: David S. Miller <davem@davemloft.net>
25     Signed-off-by: Chris Wright <chrisw@sous-sol.org>
26     ---
27    
28     --- a/net/sctp/ulpqueue.c
29     +++ b/net/sctp/ulpqueue.c
30     @@ -279,6 +279,7 @@ static inline void sctp_ulpq_store_reasm
31     static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *queue, struct sk_buff *f_frag, struct sk_buff *l_frag)
32     {
33     struct sk_buff *pos;
34     + struct sk_buff *new = NULL;
35     struct sctp_ulpevent *event;
36     struct sk_buff *pnext, *last;
37     struct sk_buff *list = skb_shinfo(f_frag)->frag_list;
38     @@ -297,11 +298,33 @@ static struct sctp_ulpevent *sctp_make_r
39     */
40     if (last)
41     last->next = pos;
42     - else
43     - skb_shinfo(f_frag)->frag_list = pos;
44     + else {
45     + if (skb_cloned(f_frag)) {
46     + /* This is a cloned skb, we can't just modify
47     + * the frag_list. We need a new skb to do that.
48     + * Instead of calling skb_unshare(), we'll do it
49     + * ourselves since we need to delay the free.
50     + */
51     + new = skb_copy(f_frag, GFP_ATOMIC);
52     + if (!new)
53     + return NULL; /* try again later */
54     +
55     + new->sk = f_frag->sk;
56     +
57     + skb_shinfo(new)->frag_list = pos;
58     + } else
59     + skb_shinfo(f_frag)->frag_list = pos;
60     + }
61    
62     /* Remove the first fragment from the reassembly queue. */
63     __skb_unlink(f_frag, queue);
64     +
65     + /* if we did unshare, then free the old skb and re-assign */
66     + if (new) {
67     + kfree_skb(f_frag);
68     + f_frag = new;
69     + }
70     +
71     while (pos) {
72    
73     pnext = pos->next;