This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: secureplt breaks ld on Alpha Linux


On 08/29/2014 12:29 PM, Mikulas Patocka wrote:
> I found out that the patch cc75d373fdb9668f367959f99f0b67e056a6c18a 
> (Enable secureplt by default for alpha-linux) committed to binutils git 
> breaks ld on alpha.
> 
> This is a minimalized testcase that shows the breakage:
> http://people.redhat.com/~mpatocka/testcases/alpha-ld-bug/ld-bug.tar.xz
> 
> To reproduce the bug, run ./ld-bug.sh to perform the linking, then run the 
> resulting binary:
> LD_PRELOAD=./libots.so ./memset

Incidentally, you can't package your ld.so and libc.so and then use the system
ld.so.  The ld.so and libc.so used must match.  That said, removing the stuff
redundant with my system libraries I can reproduce the crash.

> The bug happens when using the Compaq C Compiler (ccc) on Alpha Linux (it 
> can be downloaded from 
> ftp://ftp.compaq.com/pub/products/C-CXX/linux/compaq_c/ ). When using 
> optimization, Compaq C replaces a call to memset with a call to _OtsZero 
> located in libots.so. The above patch breaks ld in such a way that the 
> resulting program crashes when performing the dynamic call to _OtsZero.

The code that ccc is generating is incorrect:

  1c:   00 40 5b 6b     jsr     ra,(t12),20 <main+0x20>
                        1c: LITUSE      printf+0x3
                        1c: HINT        printf
  20:   00 00 ba 27     ldah    gp,0(ra)
                        20: GPDISP      *ABS*+0x8
  24:   90 01 3f 22     lda     a1,400
  28:   00 00 bd 23     lda     gp,0(gp)
  2c:   00 00 7d a7     ldq     t12,0(gp)
                        2c: ELF_LITERAL _OtsZero
  30:   00 00 1d a6     ldq     a0,0(gp)
                        30: ELF_LITERAL a
  34:   00 00 1d a4     ldq     v0,0(gp)
                        34: ELF_LITERAL .data
  38:   00 00 fe 2f     unop
  3c:   00 40 5b 6b     jsr     ra,(t12),40 <main+0x40>
                        3c: LITUSE      _OtsZero+0x3
                        3c: HINT        _OtsZero
  40:   00 00 7d a7     ldq     t12,0(gp)
                        40: ELF_LITERAL printf
  44:   10 00 00 22     lda     a0,16(v0)
                        44: LITUSE      .data+0x1
  48:   00 00 fe 2f     unop
  4c:   00 40 5b 6b     jsr     ra,(t12),50 <main+0x50>
                        4c: LITUSE      printf+0x3
                        4c: HINT        printf

At 0x40, the compiler has failed to reload gp after the call, like it did after
the first call to printf at 0x20.

The Compaq compiler seems to be assuming non-standard calling conventions in
the call to _OtsZero.  If you force LD_BIND_NOW=1 so that all relocation
happens first, the program does run correctly.

There are several ways libots could have been written to annotate the function
for non-standard calling conventions.  But Compaq probably went under before
that bug was exposed.  Assuming that one can't get the source, it may be
possible to modify the libots.so binary so that it works with modern linkers.

This is not a bug in ld, per se.


r~


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]