Skip to content

Rewriting NEEDED section creates broken .so #374

@lkollar

Description

@lkollar

Describe the bug
Modifying the NEEDED section in libcrypto.so mangles the version needs section.

Original:

Version needs section '.gnu.version_r' contains 2 entries:
 Addr: 0x0000000000037240  Offset: 0x037240  Link: 4 (.dynstr)
  000000: Version: 1  File: libdl.so.2  Cnt: 1
  0x0010:   Name: GLIBC_2.2.5  Flags: none  Version: 9
  0x0020: Version: 1  File: libc.so.6  Cnt: 5
  0x0030:   Name: GLIBC_2.4  Flags: none  Version: 10
  0x0040:   Name: GLIBC_2.3  Flags: none  Version: 8
  0x0050:   Name: GLIBC_2.7  Flags: none  Version: 7
  0x0060:   Name: GLIBC_2.3.4  Flags: none  Version: 6
  0x0070:   Name: GLIBC_2.2.5  Flags: none  Version: 5

Modified:

Version needs section '.gnu.version_r' contains 2 entries:
 Addr: 0x0000000000037240  Offset: 0x037240  Link: 4 (.dynstr)
  000000: Version: 1120  File:   Cnt: 0
  0x0020: Version: 1  File: libc.so.6  Cnt: 5
  0x0030:   Name: GLIBC_2.4  Flags: none  Version: 10
  0x0040:   Name: GLIBC_2.3  Flags: none  Version: 8
  0x0050:   Name: GLIBC_2.7  Flags: none  Version: 7
  0x0060:   Name: GLIBC_2.3.4  Flags: none  Version: 6
  0x0070:   Name: GLIBC_2.2.5  Flags: none  Version: 5

Running ldd on the modified .so produces the following error message:

/tmp/libcrypto_modified.so: error while loading shared libraries: /tmp/libcrypto_modified.so: unsupported version 1120 of Verneed record

To Reproduce
Steps to reproduce the behavior:

Run the following script:

import lief

def replace_needed(file_name, 
                   out_file_name,
                   so_name,
                   new_so_name):                                                                       
  elf = lief.parse(file_name)                                                                                                  
  for lib in elf.dynamic_entries:                                                                                              
      if lib.tag == lief.ELF.DYNAMIC_TAGS.NEEDED and lib.name == so_name:                                                      
          print("Replacing needed library: {} with {} in {}".format(
                      lib.name, new_so_name, file_name))
          lib.name = new_so_name                                                                                               
  elf.write(out_file_name)                                      

replace_needed("/usr/lib64/libcrypto.so.1.0.1e", 
               "/tmp/libcrypto_modified.so",
               "libz.so.1",
               "libz.so.1")

Check the resulting /tmp/libcrypto_modified.so file with readelf -V. The original libcrypto.so.1.0.1e is from the quay.io/pypa/manylinux2010_x86_64 image so the easiest might be to run the example in that Docker image. I can also upload the .so somewhere if you prefer.

Expected behavior
A valid .so file.

Environment (please complete the following information):

  • System and Version : CentOS 6.10 (quay.io/pypa/manylinux2010_x86_64)
  • Target format: ELF
  • LIEF commit version: 0.10.1-bfe5414

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions