[Pixman] [ARM] stack corruption in pixman 0.30.2

Siarhei Siamashka siarhei.siamashka at gmail.com
Wed Sep 18 16:00:37 PDT 2013

On Wed, 18 Sep 2013 18:11:59 +0200
"Patrik, Kluba" <pkluba at dension.com> wrote:

> Hi!

Hi, thanks for your report.
> I am playing with WebKitDFB on an ARMv6 platform, and have faced a
> strange segmentation fault with PC/LR being 0x8/0x6, obviously meaning
> control was transferred to NULL pointer somewhere. With a bit of luck
> and gdb magic, I could track it down to
> pixman_composite_src_8_8_asm_armv6(). Using breakpoints it was
> confirmed to cause the problem.
> That function comes from pixman-arm-simd*.*, the SOC being used has an
> ARM1176JZF-S core, so all the required instructions are supported.
> Based on the disassembly, pixman_composite_src_8_8_asm_armv6() has very
> little to do with the stack. In the prologue it pushes several
> registers, and in the epilogue it pops them. Besides that 2 registers are
> pushed on the stack in the middle, and popped later. Jumps are made all
> over the place, so based on conditions it could happen that this push and
> pop can get out of sync. If the logic is good, then this will not happen,
> just a theoretical possibility.
> Before the epilogue (final pop), there's an unconditional SP+=8, which is
> skipped from some places above by jumping to the instruction following it
> (final pop). This is presumably to counter the 2-register-push before without
> doing the 2-register-pop, in case.
> But for me, that SP+=8 happens even when it should not, ruining the
> stack frame. The mentioned 2-register-push/2-register-pop instructions are
> not even executed.
> I've tried to decipher the heavy macro usage in C and assembly, but failed.
> It's possible that the root of the problem lies somewhere above, and
> bad parameters reach pixman_composite_src_8_8_asm_armv6(), leading to this
> situation, but I don't know how this could be tracked down.
> Could somebody give me a hand, please?
> A disassembly of the function can be found at:
> http://pastebin.ca/2454215
> A captured instruction flow can be found at:
> http://pastebin.ca/2454212
> A more detailed instruction flow with all register values for each
> instruction (different execution but same flow) can be found at:
> (gzipped txt)
> http://ttb.li/fvthv

Based on the disassembly listing and the trace from gdb,
your analysis looks correct.

But something seems to be really odd there. Your
disassembly shows the following code at the end of
the "pixman_composite_src_8_8_asm_armv6" function:

679e4:       e2511001       subs  r1, r1, #1
679e8:       e0822003       add   r2, r2, r3
679ec:       e0844005       add   r4, r4, r5
679f0:       e1a0000e       mov   r0, lr
679f4:       2affffc9       bcs   67920 <pixman_composite_src_8_8_asm_armv6+0x340>
679f8:       e28dd008       add   sp, sp, #8
679fc:       e8bd8ff0       pop   {r4, r5, r6, r7, r8, r9, sl, fp, pc}

But if I download http://cairographics.org/releases/pixman-0.30.2.tar.gz
and compile it myself, then I get the following disassembly
for the end of the same function:

a08:	e2511001 	subs	r1, r1, #1
a0c:	e0822003 	add	r2, r2, r3
a10:	e0844005 	add	r4, r4, r5
a14:	e1a0000e 	mov	r0, lr
a18:	2affffc9 	bcs	944 <pixman_composite_src_8_8_asm_armv6+0x340>
a1c:	ea000000 	b	a24 <pixman_composite_src_8_8_asm_armv6+0x420>
a20:	e28dd008 	add	sp, sp, #8
a24:	e8bd8ff0 	pop	{r4, r5, r6, r7, r8, r9, sl, fp, pc}

As you can see, there is an extra branch instruction jumping over
this problematic stack pointer increment:

a1c:	ea000000 	b	a24 <pixman_composite_src_8_8_asm_armv6+0x420>

In the assembly source code, the relevant parts are:


Which version of binutils are you using to compile pixman 0.30.2?
I also think that your pixman build hardly has any chances to
pass the "make check" test, but you can try it just for the
sake of experiment.

Best regards,
Siarhei Siamashka

More information about the Pixman mailing list