Skip to content

Conversation

Ponsuke07
Copy link

About this PR

This PR fix #146.
In some binaries, the .dynamic section may be located in a read-only PT_LOAD segment.
Therefore, add a writable flag to the PT_LOAD segment in which the .dynamic section is located.

How to test

  1. Reproduce the Issue

Use the repository from #146 (comment) to build a problematic binary:


# Clone the sample repository
$ git clone https://github.com/limeytexan/NixOS-patchelf-issue-146.git
$ cd NixOS-patchelf-issue-146

# Download dependencies
$ go mod download github.com/sirupsen/logrus
$ go get github.com/sirupsen/[email protected]

# Build the binary
$ go build

# Attempt to patchelf
$ patchelf --set-rpath hogehgoe ./issue_146 --output issue_146.patched
$ ./issue_146.patched
Segmentation fault
  1. Verify the Fix

After applying this PR, you will see that a writable flag(PF_W) has been added to the PT_LOAD section in which the .dynamic is located.

$: ./issue_146.patched && echo "WORKED" 
WORKED
$ readelf -l ./issue_146.patched 

Elf file type is EXEC (Executable file)
Entry point 0x465100
There are 10 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
                 0x0000000000000230 0x0000000000000230  R      0x1000
  TLS            0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000008  R      0x8
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x8
  LOOS+0x5041580 0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000         0x8
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x0000000000129030 0x0000000000129030  RWE    0x1000 ★PF_W flag has been added
  NOTE           0x0000000000000278 0x0000000000400278 0x0000000000400278
                 0x0000000000000064 0x0000000000000064  R      0x4
  INTERP         0x00000000000002e0 0x00000000004002e0 0x00000000004002e0
                 0x000000000000001c 0x000000000000001c  R      0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  DYNAMIC        0x0000000000000508 0x0000000000400508 0x0000000000400508
                 0x0000000000000130 0x0000000000000130  RW     0x8
  LOAD           0x000000000012a000 0x000000000052a000 0x000000000052a000
                 0x00000000001307d0 0x00000000001307d0  R      0x1000
  LOAD           0x000000000025b000 0x000000000065b000 0x000000000065b000
                 0x0000000000035f60 0x000000000006bf08  RW     0x1000

 Section to Segment mapping:
  Segment Sections...
   00     
   01     
   02     
   03     
   04     .note.go.buildid .interp .dynstr .dynamic .text .plt 
   05     .note.go.buildid 
   06     .interp 
   07     .dynamic 
   08     .rodata .rela .rela.plt .gnu.version .gnu.version_r .hash .dynsym .typelink .itablink .gosymtab .gopclntab 
   09     .go.buildinfo .got.plt .got .noptrdata .data .bss .noptrbss

It also confirms that make check tests pass.

This commit fix NixOS#146.
In some binaries, the .dynamic section could be placed on a read-only PT_LOAD segment.
Therefore, add a writable flag to PT_LOAD segment where the .dynamic section is placed.

Signed-off-by: Daisuke Yamane <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

PT_DYNAMIC can end up in r/o PT_LOAD segment
1 participant