Bug 31218 - PLT rewrite overflows large displacement on x32
Summary: PLT rewrite overflows large displacement on x32
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: dynamic-link (show other bugs)
Version: 2.39
: P2 normal
Target Milestone: 2.39
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-01-06 17:06 UTC by H.J. Lu
Modified: 2024-01-06 22:26 UTC (History)
1 user (show)

See Also:
Host:
Target: x86-64
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2024-01-06 17:06:09 UTC
When a R_X86_64_JUMP_SLOT relocation is resolved to the unrelocated object,
PLT rewrite will write the wrong address to PLT entry if the definition in
the unrelocated object will be updated by IFUNC relocation later.
Comment 1 H.J. Lu 2024-01-06 18:59:17 UTC
IFUNC is fine.  The problem is with x32.  On x32, PLT rewrite generates:

   0xf7fbe060 <+0>:	jmp    0x401030
   0xf7fbe065 <+5>:	int3
   0xf7fbe066 <+6>:	int3
   0xf7fbe067 <+7>:	int3
   0xf7fbe068 <+8>:	int3
   0xf7fbe069 <+9>:	int3
   0xf7fbe06a <+10>:	int3
   0xf7fbe06b <+11>:	int3
   0xf7fbe06c <+12>:	int3
   0xf7fbe06d <+13>:	int3
   0xf7fbe06e <+14>:	int3
   0xf7fbe06f <+15>:	int3

0xf7fbe060 + 0x401030 overflows.
Comment 2 Sourceware Commits 2024-01-06 22:26:19 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=0f9afc265a4a0f4ba658d7f71c9602a3fda3538e

commit 0f9afc265a4a0f4ba658d7f71c9602a3fda3538e
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Sat Jan 6 14:03:37 2024 -0800

    x32: Handle displacement overflow in PLT rewrite [BZ #31218]
    
    PLT rewrite calculated displacement with
    
    ElfW(Addr) disp = value - branch_start - JMP32_INSN_SIZE;
    
    On x32, displacement from 0xf7fbe060 to 0x401030 was calculated as
    
    unsigned int disp = 0x401030 - 0xf7fbe060 - 5;
    
    with disp == 0x8442fcb and caused displacement overflow. The PLT entry
    was changed to:
    
    0xf7fbe060 <+0>:        e9 cb 2f 44 08          jmp    0x401030
    0xf7fbe065 <+5>:        cc                      int3
    0xf7fbe066 <+6>:        cc                      int3
    0xf7fbe067 <+7>:        cc                      int3
    0xf7fbe068 <+8>:        cc                      int3
    0xf7fbe069 <+9>:        cc                      int3
    0xf7fbe06a <+10>:       cc                      int3
    0xf7fbe06b <+11>:       cc                      int3
    0xf7fbe06c <+12>:       cc                      int3
    0xf7fbe06d <+13>:       cc                      int3
    0xf7fbe06e <+14>:       cc                      int3
    0xf7fbe06f <+15>:       cc                      int3
    
    x32 has 32-bit address range, but it doesn't wrap address around at 4GB,
    JMP target was changed to 0x100401030 (0xf7fbe060LL + 0x8442fcbLL + 5),
    which is above 4GB.
    
    Always use uint64_t to calculate displacement.  This fixes BZ #31218.
    Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
Comment 3 H.J. Lu 2024-01-06 22:26:52 UTC
Fixed.