lkml.org 
[lkml]   [2012]   [Oct]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 1/3] pppoatm: don't send frames to destroyed vcc
    Date
    The pppoatm_send() uses vcc->send() directly and does not check if vcc
    is ready for send(). This causes Oops when send() is used after
    vcc_destroy_socket() at least with usbatm driver:

    Oops: 0000 [#1] PREEMPT
    Pid: 0, comm: swapper Not tainted 3.6.0-krzysiek-00001-gb7cd93b-dirty #60 /AK32
    EIP: 0060:[<c01413c6>] EFLAGS: 00010082 CPU: 0
    EIP is at __wake_up_common+0x16/0x70
    EAX: 30707070 EBX: 00000292 ECX: 00000001 EDX: dca75fc0
    ESI: 00000000 EDI: de7f500f EBP: df409f24 ESP: df409f08
    DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
    CR0: 8005003b CR2: 30707070 CR3: 1c920000 CR4: 000007d0
    DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
    DR6: ffff0ff0 DR7: 00000400
    Process swapper (pid: 0, ti=df408000 task=c07bd4e0 task.ti=c07b0000)
    Stack:
    00000000 00000001 00000001 dca75fc0 00000292 00000000 de7f500f df409f3c
    c0143299 00000000 00000000 dc84f000 dc84f000 df409f4c c0602bf0 00000000
    dc84f000 df409f58 c0604301 dc840cc0 df409fb4 c04672e5 c076a240 00000000
    Call Trace:
    [<c0143299>] __wake_up+0x29/0x50
    [<c0602bf0>] vcc_write_space+0x40/0x80
    [<c0604301>] atm_pop_raw+0x21/0x30
    [<c04672e5>] usbatm_tx_process+0x2a5/0x380
    [<c0126cf9>] tasklet_action+0x39/0x70
    [<c0126f1f>] __do_softirq+0x7f/0x120
    [<c0126ea0>] ? local_bh_enable_ip+0xa0/0xa0
    <IRQ>

    Now pppoatm_send(), like vcc_sendmsg(), checks for vcc flags that
    indicate that vcc is not ready.

    Signed-off-by: Krzysztof Mazur <krzysiek@podlesie.net>
    Cc: David Woodhouse <dwmw2@infradead.org>
    ---
    Previously sent with more details as:
    http://marc.info/?l=linux-kernel&m=134952646810580&w=2

    This patch extends race window between pppoatm_send() and vcc_destroy_socket().
    This race exists also without this patch and it's fixed in patch 2.

    net/atm/pppoatm.c | 8 ++++++++
    1 file changed, 8 insertions(+)

    diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c
    index 226dca9..0dcb5dc 100644
    --- a/net/atm/pppoatm.c
    +++ b/net/atm/pppoatm.c
    @@ -269,6 +269,8 @@ static inline int pppoatm_may_send(struct pppoatm_vcc *pvcc, int size)
    static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)
    {
    struct pppoatm_vcc *pvcc = chan_to_pvcc(chan);
    + struct atm_vcc *vcc;
    +
    ATM_SKB(skb)->vcc = pvcc->atmvcc;
    pr_debug("(skb=0x%p, vcc=0x%p)\n", skb, pvcc->atmvcc);
    if (skb->data[0] == '\0' && (pvcc->flags & SC_COMP_PROT))
    @@ -301,6 +303,12 @@ static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)
    return 1;
    }

    + vcc = ATM_SKB(skb)->vcc;
    + if (test_bit(ATM_VF_RELEASED, &vcc->flags)
    + || test_bit(ATM_VF_CLOSE, &vcc->flags)
    + || !test_bit(ATM_VF_READY, &vcc->flags))
    + goto nospace;
    +
    atomic_add(skb->truesize, &sk_atm(ATM_SKB(skb)->vcc)->sk_wmem_alloc);
    ATM_SKB(skb)->atm_options = ATM_SKB(skb)->vcc->atm_options;
    pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n",
    --
    1.8.0.2.g35080e9


    \
     
     \ /
      Last update: 2012-10-22 20:01    [W:4.242 / U:0.160 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site