0

I found a crash in memcpy() function, which gets called from one of 802.11n specific aggregation function in wifi driver. From the core analysis, the crash point is mentioned below,

0x012014f8 <memcpy+100>: ldmge r1!, {r4, r5, r6, r7, r8, r9, r10, r11}

Why do we see a crash after the ldmge instruction execution?

I would like to know which parameter of memcpy() is corrupted - src_addr,dest_addr or length? Could you please provide your inputs by looking into the disassemble code. Please find the disassemble code of memcpy() from gdb and backtrace from core file.


disas *

Dump of assembler code for function memcpy:
0x01201494 &lt;memcpy+0&gt;:    cmp r2, #0  ; 0x0
0x01201498 &lt;memcpy+4&gt;:    moveq   pc, lr
0x0120149c &lt;memcpy+8&gt;:    push    {r4, r5, r6, r7, r8, r9, r10, r11, lr}
0x012014a0 &lt;memcpy+12&gt;:   mov r3, r0
0x012014a4 &lt;memcpy+16&gt;:   cmp r2, #16 ; 0x10
0x012014a8 &lt;memcpy+20&gt;:   blt 0x12016b8 &lt;mc_bytes&gt;
0x012014ac &lt;memcpy+24&gt;:   ands    r12, r3, #3 ; 0x3
0x012014b0 &lt;memcpy+28&gt;:   beq 0x12014d8 &lt;memcpy+68&gt;
0x012014b4 &lt;memcpy+32&gt;:   rsb r12, r12, #4    ; 0x4
0x012014b8 &lt;memcpy+36&gt;:   cmp r12, #2 ; 0x2
0x012014bc &lt;memcpy+40&gt;:   ldrb    r4, [r1], #1
0x012014c0 &lt;memcpy+44&gt;:   ldrbge  r5, [r1], #1
0x012014c4 &lt;memcpy+48&gt;:   ldrbgt  r6, [r1], #1
0x012014c8 &lt;memcpy+52&gt;:   strb    r4, [r3], #1
0x012014cc &lt;memcpy+56&gt;:   strbge  r5, [r3], #1
0x012014d0 &lt;memcpy+60&gt;:   strbgt  r6, [r3], #1
0x012014d4 &lt;memcpy+64&gt;:   sub r2, r2, r12
0x012014d8 &lt;memcpy+68&gt;:   ands    r12, r1, #3 ; 0x3
0x012014dc &lt;memcpy+72&gt;:   bne 0x120156c &lt;mc_unaligned&gt;
0x012014e0 &lt;memcpy+76&gt;:   tst r3, #15 ; 0xf
0x012014e4 &lt;memcpy+80&gt;:   ldrne   r4, [r1], #4
0x012014e8 &lt;memcpy+84&gt;:   subne   r2, r2, #4  ; 0x4
0x012014ec &lt;memcpy+88&gt;:   strne   r4, [r3], #4
0x012014f0 &lt;memcpy+92&gt;:   bne 0x12014e0 &lt;memcpy+76&gt;
0x012014f4 &lt;memcpy+96&gt;:   cmp r2, #32 ; 0x20
**0x012014f8 &lt;memcpy+100&gt;:    ldmge   r1!, {r4, r5, r6, r7, r8, r9, r10, r11}****
0x012014fc &lt;memcpy+104&gt;:  subge   r2, r2, #32 ; 0x20
0x01201500 &lt;memcpy+108&gt;:  stmiage r3!, {r4, r5, r6, r7, r8, r9, r10, r11}
0x01201504 &lt;memcpy+112&gt;:  bge 0x12014f4 &lt;memcpy+96&gt;
0x01201508 &lt;memcpy+116&gt;:  cmp r2, #16 ; 0x10
0x0120150c &lt;memcpy+120&gt;:  ldmge   r1!, {r4, r5, r6, r7}
0x01201510 &lt;memcpy+124&gt;:  subge   r2, r2, #16 ; 0x10
0x01201514 &lt;memcpy+128&gt;:  stmiage r3!, {r4, r5, r6, r7}
0x01201518 &lt;memcpy+132&gt;:  tst r2, #8  ; 0x8
0x0120151c &lt;memcpy+136&gt;:  beq 0x1201534 &lt;memcpy+160&gt;
0x01201520 &lt;memcpy+140&gt;:  ldr r4, [r1], #4
0x01201524 &lt;memcpy+144&gt;:  ldr r5, [r1], #4
0x01201528 &lt;memcpy+148&gt;:  sub r2, r2, #8  ; 0x8
0x0120152c &lt;memcpy+152&gt;:  str r4, [r3], #4
0x01201530 &lt;memcpy+156&gt;:  str r5, [r3], #4
0x01201534 &lt;memcpy+160&gt;:  tst r2, #4  ; 0x4
0x01201538 &lt;memcpy+164&gt;:  ldrne   r4, [r1], #4
0x0120153c &lt;memcpy+168&gt;:  subne   r2, r2, #4  ; 0x4
0x01201540 &lt;memcpy+172&gt;:  strne   r4, [r3], #4
0x01201544 &lt;memcpy+176&gt;:  cmp r2, #0  ; 0x0
0x01201548 &lt;memcpy+180&gt;:  beq 0x1201568 &lt;memcpy+212&gt;
0x0120154c &lt;memcpy+184&gt;:  cmp r2, #2  ; 0x2
0x01201550 &lt;memcpy+188&gt;:  ldrb    r4, [r1], #1
0x01201554 &lt;memcpy+192&gt;:  ldrbge  r5, [r1], #1
0x01201558 &lt;memcpy+196&gt;:  ldrbgt  r6, [r1], #1
0x0120155c &lt;memcpy+200&gt;:  strb    r4, [r3], #1
0x01201560 &lt;memcpy+204&gt;:  strbge  r5, [r3], #1
0x01201564 &lt;memcpy+208&gt;:  strbgt  r6, [r3], #1
0x01201568 &lt;memcpy+212&gt;:  pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
0x0120156c &lt;mc_unaligned+0&gt;:  bic r1, r1, #3  ; 0x3
0x01201570 &lt;mc_unaligned+4&gt;:  teq r12, #1 ; 0x1
0x01201574 &lt;mc_unaligned+8&gt;:  beq 0x12015e8 &lt;mc_1&gt;
0x01201578 &lt;mc_unaligned+12&gt;: teq r12, #2 ; 0x2
0x0120157c &lt;mc_unaligned+16&gt;: beq 0x1201650 &lt;mc_2&gt;
0x01201580 &lt;mc_3+0&gt;:  ldr r8, [r1], #4
0x01201584 &lt;mc_3+4&gt;:  cmp r2, #16 ; 0x10
0x01201588 &lt;mc_3+8&gt;:  blt 0x12015d8 &lt;mc_3+88&gt;
0x0120158c &lt;mc_3+12&gt;: lsr r4, r8, #24
0x01201590 &lt;mc_3+16&gt;: ldm r1!, {r5, r6, r7, r8}
0x01201594 &lt;mc_3+20&gt;: orr r4, r4, r5, lsl #8
0x01201598 &lt;mc_3+24&gt;: lsr r5, r5, #24
0x0120159c &lt;mc_3+28&gt;: orr r5, r5, r6, lsl #8
0x012015a0 &lt;mc_3+32&gt;: lsr r6, r6, #24
0x012015a4 &lt;mc_3+36&gt;: orr r6, r6, r7, lsl #8
0x012015a8 &lt;mc_3+40&gt;: lsr r7, r7, #24
0x012015ac &lt;mc_3+44&gt;: orr r7, r7, r8, lsl #8
0x012015b0 &lt;mc_3+48&gt;: stmia   r3!, {r4, r5, r6, r7}
0x012015b4 &lt;mc_3+52&gt;: sub r2, r2, #16 ; 0x10
0x012015b8 &lt;mc_3+56&gt;: cmp r2, #32 ; 0x20
0x012015bc &lt;mc_3+60&gt;: bge 0x120158c &lt;mc_3+12&gt;
0x012015c0 &lt;mc_3+64&gt;: b   0x12015d8 &lt;mc_3+88&gt;
0x012015c4 &lt;mc_3+68&gt;: lsr r4, r8, #24
0x012015c8 &lt;mc_3+72&gt;: ldr r8, [r1], #4
0x012015cc &lt;mc_3+76&gt;: orr r4, r4, r8, lsl #8
0x012015d0 &lt;mc_3+80&gt;: str r4, [r3], #4
0x012015d4 &lt;mc_3+84&gt;: sub r2, r2, #4  ; 0x4
0x012015d8 &lt;mc_3+88&gt;: cmp r2, #4  ; 0x4
0x012015dc &lt;mc_3+92&gt;: bge 0x12015c4 &lt;mc_3+68&gt;
0x012015e0 &lt;mc_3+96&gt;: sub r1, r1, #1  ; 0x1
0x012015e4 &lt;mc_3+100&gt;:    b   0x1201544 &lt;memcpy+176&gt;
0x012015e8 &lt;mc_1+0&gt;:  ldr r8, [r1], #4
0x012015ec &lt;mc_1+4&gt;:  cmp r2, #16 ; 0x10
0x012015f0 &lt;mc_1+8&gt;:  blt 0x1201640 &lt;mc_1+88&gt;
0x012015f4 &lt;mc_1+12&gt;: lsr r4, r8, #8
0x012015f8 &lt;mc_1+16&gt;: ldm r1!, {r5, r6, r7, r8}
0x012015fc &lt;mc_1+20&gt;: orr r4, r4, r5, lsl #24
0x01201600 &lt;mc_1+24&gt;: lsr r5, r5, #8
0x01201604 &lt;mc_1+28&gt;: orr r5, r5, r6, lsl #24
0x01201608 &lt;mc_1+32&gt;: lsr r6, r6, #8
0x0120160c &lt;mc_1+36&gt;: orr r6, r6, r7, lsl #24
0x01201610 &lt;mc_1+40&gt;: lsr r7, r7, #8
0x01201614 &lt;mc_1+44&gt;: orr r7, r7, r8, lsl #24
0x01201618 &lt;mc_1+48&gt;: stmia   r3!, {r4, r5, r6, r7}
0x0120161c &lt;mc_1+52&gt;: sub r2, r2, #16 ; 0x10
0x01201620 &lt;mc_1+56&gt;: cmp r2, #32 ; 0x20
0x01201624 &lt;mc_1+60&gt;: bge 0x12015f4 &lt;mc_1+12&gt;
0x01201628 &lt;mc_1+64&gt;: b   0x1201640 &lt;mc_1+88&gt;
0x0120162c &lt;mc_1+68&gt;: lsr r4, r8, #8
0x01201630 &lt;mc_1+72&gt;: ldr r8, [r1], #4
0x01201634 &lt;mc_1+76&gt;: orr r4, r4, r8, lsl #24
0x01201638 &lt;mc_1+80&gt;: str r4, [r3], #4
0x0120163c &lt;mc_1+84&gt;: sub r2, r2, #4  ; 0x4
0x01201640 &lt;mc_1+88&gt;: cmp r2, #4  ; 0x4
0x01201644 &lt;mc_1+92&gt;: bge 0x120162c &lt;mc_1+68&gt;
0x01201648 &lt;mc_1+96&gt;: sub r1, r1, #3  ; 0x3
0x0120164c &lt;mc_1+100&gt;:    b   0x1201544 &lt;memcpy+176&gt;
0x01201650 &lt;mc_2+0&gt;:  ldr r8, [r1], #4
0x01201654 &lt;mc_2+4&gt;:  cmp r2, #16 ; 0x10
0x01201658 &lt;mc_2+8&gt;:  blt 0x12016a8 &lt;mc_2+88&gt;
0x0120165c &lt;mc_2+12&gt;: lsr r4, r8, #16
0x01201660 &lt;mc_2+16&gt;: ldm r1!, {r5, r6, r7, r8}
0x01201664 &lt;mc_2+20&gt;: orr r4, r4, r5, lsl #16
0x01201668 &lt;mc_2+24&gt;: lsr r5, r5, #16
0x0120166c &lt;mc_2+28&gt;: orr r5, r5, r6, lsl #16
0x01201670 &lt;mc_2+32&gt;: lsr r6, r6, #16
0x01201674 &lt;mc_2+36&gt;: orr r6, r6, r7, lsl #16
0x01201678 &lt;mc_2+40&gt;: lsr r7, r7, #16
0x0120167c &lt;mc_2+44&gt;: orr r7, r7, r8, lsl #16
0x01201680 &lt;mc_2+48&gt;: stmia   r3!, {r4, r5, r6, r7}
0x01201684 &lt;mc_2+52&gt;: sub r2, r2, #16 ; 0x10
0x01201688 &lt;mc_2+56&gt;: cmp r2, #32 ; 0x20
0x0120168c &lt;mc_2+60&gt;: bge 0x120165c &lt;mc_2+12&gt;
0x01201690 &lt;mc_2+64&gt;: b   0x12016a8 &lt;mc_2+88&gt;
0x01201694 &lt;mc_2+68&gt;: lsr r4, r8, #16
0x01201698 &lt;mc_2+72&gt;: ldr r8, [r1], #4
0x0120169c &lt;mc_2+76&gt;: orr r4, r4, r8, lsl #16
0x012016a0 &lt;mc_2+80&gt;: str r4, [r3], #4
0x012016a4 &lt;mc_2+84&gt;: sub r2, r2, #4  ; 0x4
0x012016a8 &lt;mc_2+88&gt;: cmp r2, #4  ; 0x4
0x012016ac &lt;mc_2+92&gt;: bge 0x1201694 &lt;mc_2+68&gt;
0x012016b0 &lt;mc_2+96&gt;: sub r1, r1, #2  ; 0x2
0x012016b4 &lt;mc_2+100&gt;:    b   0x1201544 &lt;memcpy+176&gt;
0x012016b8 &lt;mc_bytes+0&gt;:  teq r2, #0  ; 0x0
0x012016bc &lt;mc_bytes+4&gt;:  ldrbne  r12, [r1], #1
0x012016c0 &lt;mc_bytes+8&gt;:  strbne  r12, [r3], #1
0x012016c4 &lt;mc_bytes+12&gt;: subsne  r2, r2, #1  ; 0x1
0x012016c8 &lt;mc_bytes+16&gt;: bne 0x12016bc &lt;mc_bytes+4&gt;
0x012016cc &lt;mc_bytes+20&gt;: pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}

End of assembler dump.

Crash Point:

backtrace *

#0  0x012014f8 in memcpy () from libc.so.3
#1  0x78276c04 in wlan_11n_aggregate_pkt (priv=0x0, pra_list=0x3f5898, 
    headroom=&lt;value optimized out&gt;, ptrindex=0)
    at \mlan\mlan_11n_aggr.c:98
#2  0x002ff4e8 in ?? ()

Please let me know if you need further information.

Anil
  • 1
  • 1
  • 1
    Presumably the crash is a segfault, yes? It's on a load, so either the source pointer is wrong and you've crashed straight away, or the length is wrong and you've overrun. Knowing what was in r0-r3 at the time might help, particularly if you have an idea of what the parameters _should_ have been. – Notlikethat Sep 23 '14 at 11:00
  • You should be using [this code for memcpy](https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/arm/lib/copy_template.S), so the driver has something strange. Other possibilities are stack overwrites in the `dest` pointer; Ie, `dest` is pointing to the stack and you have munged it and interrupt context save/restore won't work; most likely the issue is in `source` or `len` as per Notlikethat. It could also be some weird configuration as the routine doesn't have standard ABI as the `memcpy` above would. Stack frames must be consistent on context switches. Er, what OS? – artless noise Sep 23 '14 at 15:07

0 Answers0