This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc 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]

[Bug libc/23296] Data race in setting function descriptor during lazy binding


https://sourceware.org/bugzilla/show_bug.cgi?id=23296

--- Comment #9 from dave.anglin at bell dot net ---
On 2018-06-20 10:21 AM, carlos at redhat dot com wrote:
> https://sourceware.org/bugzilla/show_bug.cgi?id=23296
>
> --- Comment #8 from Carlos O'Donell <carlos at redhat dot com> ---
> (In reply to dave.anglin from comment #7)
>> On 2018-06-18 4:17 PM, carlos at redhat dot com wrote:
>>> Here we would compare fptr to the plt entry we're trying to update.
>> Unfortunately, we don't have fptr.  We have got, gp and l.  This gives
>> jmprel and end_jmprel but I don't think gp is sufficient to find the reloc.
> It should be sufficient.
>
> If you have jmprel and end_jmprel you can iterate over all the relocs.
>
> If you can iterate the relocs you can compute the address that each reloc
> adjusts.
Yes.
>
> You can compare the adjusted address to the PLT you are going to adjust?
I don't think we know the PLT entry requiring adjustment.  That came 
from the reloc offset
which has been clobbered.

The trampoline code could be modified so it doesn't use r22.  If we 
modified the call stubs
and gcc so that r22 contains the address of the PLT entry, then we 
should be able to find the
reloc offset.

We don't need to clobber r22 in plt_stub:

static const bfd_byte plt_stub[] =
{
   0x0e, 0x80, 0x10, 0x96,  /* 1: ldw    0(%r20),%r22            */
   0xea, 0xc0, 0xc0, 0x00,  /*    bv     %r0(%r22)               */
   0x0e, 0x88, 0x10, 0x95,  /*    ldw    4(%r20),%r21            */
#define PLT_STUB_ENTRY (3*4)
   0xea, 0x9f, 0x1f, 0xdd,  /*    b,l    1b,%r20                 */
   0xd6, 0x80, 0x1c, 0x1e,  /*    depi   0,31,2,%r20             */
   0x00, 0xc0, 0xff, 0xee,  /* 9: .word  fixup_func              */
   0xde, 0xad, 0xbe, 0xef   /*    .word  fixup_ltp               */
};

We would need an extra ldo instruction in the following stubs:

    Import stub to call shared library routine from normal object file
    (single sub-space version)
    :            addil LR'lt_ptr+ltoff,%dp       ; get procedure entry point
    :            ldw RR'lt_ptr+ltoff(%r1),%r21
    :            bv %r0(%r21)
    :            ldw RR'lt_ptr+ltoff+4(%r1),%r19 ; get new dlt value.

    Import stub to call shared library routine from shared library
    (single sub-space version)
    :            addil LR'ltoff,%r19             ; get procedure entry point
    :            ldw RR'ltoff(%r1),%r21
    :            bv %r0(%r21)
    :            ldw RR'ltoff+4(%r1),%r19        ; get new dlt value.

I don't much like increasing the size of these stubs it would eliminate 
one relocation.

$$dyncall would need fixing to use r21 for branch target.  The LTP value
should be loaded after target address as in the stubs:

#ifdef L_dyncall
         SUBSPA_MILLI
         ATTR_DATA
GSYM($$dyncall)
         .export $$dyncall,millicode
         .proc
         .callinfo       millicode
         .entry
         bb,>=,n %r22,30,LREF(1)         ; branch if not plabel address
         depi    0,31,2,%r22             ; clear the two least 
significant bits
         ldw     4(%r22),%r19            ; load new LTP value
         ldw     0(%r22),%r22            ; load address of target
LSYM(1)
#ifdef LINUX
         bv      %r0(%r22)               ; branch to the real target
#else
         ldsid   (%sr0,%r22),%r1         ; get the "space ident" 
selected by r22
         mtsp    %r1,%sr0                ; move that space identifier 
into sr0
         be      0(%sr0,%r22)            ; branch to the real target
#endif
         stw     %r2,-24(%r30)           ; save return address into 
frame marker
         .exit
         .procend

The inline indirect calls generated by gcc would need review.

We need to implement your suggestion for setting the LSB in the reloc 
offset.  PLT
entries could be updated atomically using a floating point store. Then, 
the only
possible race is between the load of the target address and the new LTP 
value.
If the LSB in reloc offset is not set, then we should be able to just 
reload the target
address using r22 and transfer to the target.

The only thing I don't like is making the stubs larger.  This has caused 
no end of trouble.

Dave

-- 
You are receiving this mail because:
You are on the CC list for the bug.

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