Bug 10107 - 32-bit PowerPC POWER6 memcpy uses erroneous cmpldi but should use cmplwi
Summary: 32-bit PowerPC POWER6 memcpy uses erroneous cmpldi but should use cmplwi
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: 2.9
: P1 normal
Target Milestone: 2.10
Assignee: Ulrich Drepper
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-04-27 17:04 UTC by Ryan S. Arnold
Modified: 2014-06-30 09:17 UTC (History)
1 user (show)

See Also:
Host: powerpc-linux
Target: powerpc-linux
Build: powerpc-linux
Last reconfirmed: 2009-04-27 17:09:38
fweimer: security-


Attachments
cmpldi-to-cmplwi.diff (437 bytes, patch)
2009-04-27 17:08 UTC, Ryan S. Arnold
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ryan S. Arnold 2009-04-27 17:04:35 UTC
The 32-bit PowerPC POWER6 memcpy uses the cmpldi insn when it should use a cmplwi.

    /* Compare the contents of register 'r5' to the value '16' where r5 */
    /* holds '12'.  */
    cmpldi      cr1,5,16

This doesn't normally prove to be a problem except when the 'length' parameter
to memcpy, held in register r5 is a computed value and the result has the high
32-bits of the register populated with junk due 64-bit operation (in the error
case a rlwinm insn),e.g.

0x1007c240 <r_gset+152>:        rlwinm  r9,r0,0,0,29
0x1007c244 <r_gset+156>:        addi    r5,r9,16
0x1007c248 <r_gset+160>:        bl      0x100dc750 <memcpy@plt>

This causes the cmpldi to result in 'greater' than when comparing '12' to '16'
which is erroneous.

The correction instruction is cmplwi which ignores the high 32-bits or 'r5':

    cmplwi      cr1,5,16

I'll supply a patch and a testcase shortly.
Comment 1 Ryan S. Arnold 2009-04-27 17:08:32 UTC
Created attachment 3911 [details]
cmpldi-to-cmplwi.diff

This is a fix to correct usage of cmpldi to cmplwi in the 32-bit POWER6
mem[cpy|set].  I'll attach a testcase shortly.
Comment 2 Ryan S. Arnold 2009-04-30 15:38:21 UTC
I attempted to produce a standalone testcase that would pass the high-word bits
of r5 as non-zero to the power6 memcpy but I was unable to get the compiler to
cooperate and reproduce the failure that I originally debugged.

Regardless, using cmpldi in 32-bit code is erroneous and in this case can cause
an overwrite of an array if r5 (length) parameter has bits set in the high-word
of the register.

Please check-in.
Comment 3 Ulrich Drepper 2009-06-16 15:30:03 UTC
Patch applied to git.