Ticket #12427: 0001-runtime_loader-Randomly-position-only-relocatable-co.patch

File 0001-runtime_loader-Randomly-position-only-relocatable-co.patch, 4.9 KB (added by simonsouth, 9 years ago)

Base test for relocatability on object type, not presence of "dynamic" section

  • headers/private/system/elf_common.h

    From e8bc83db442ccaea2a971b99c07bca17e645d152 Mon Sep 17 00:00:00 2001
    From: Simon South <ssouth@simonsouth.com>
    Date: Wed, 21 Oct 2015 08:18:43 -0400
    Subject: [PATCH] runtime_loader: Randomly position only relocatable code
    
    The use of an unreliable test for relocatability effectively broke
    runtime_loader's support for non-position-independent executables, as it
    would insist on randomly positioning these files' segments in memory
    anyway causing the program to quickly crash.
    
    With this change runtime_loader uses the object type specified in the
    file's header to determine whether its segments can be safely relocated,
    restoring support for non-PI executables.
    
    Fixes #12427.
    ---
     headers/private/system/elf_common.h          | 11 +++++++++++
     src/system/runtime_loader/elf_load_image.cpp |  2 +-
     src/system/runtime_loader/images.cpp         | 16 +++++++++++-----
     src/system/runtime_loader/images.h           |  2 +-
     4 files changed, 24 insertions(+), 7 deletions(-)
    
    diff --git a/headers/private/system/elf_common.h b/headers/private/system/elf_common.h
    index 3e65305..23ab555 100644
    a b  
    3131#define EI_VERSION  6
    3232#define EI_PAD      7
    3333
     34// e_type (Object file type)
     35#define ET_NONE         0 // No file type
     36#define ET_REL          1 // Relocatable file
     37#define ET_EXEC         2 // Executable file
     38#define ET_DYN          3 // Shared object file
     39#define ET_CORE         4 // Core file
     40#define ET_LOOS         0xfe00 // OS-specific range start
     41#define ET_HIOS         0xfeff // OS-specific range end
     42#define ET_LOPROC       0xff00 // Processor-specific range start
     43#define ET_HIPROC       0xffff // Processor-specific range end
     44
    3445// e_machine (Architecture)
    3546#define EM_NONE         0 // No machine
    3647#define EM_M32          1 // AT&T WE 32100
  • src/system/runtime_loader/elf_load_image.cpp

    diff --git a/src/system/runtime_loader/elf_load_image.cpp b/src/system/runtime_loader/elf_load_image.cpp
    index 0110948..6393c26 100644
    a b load_image(char const* name, image_type type, const char* rpath,  
    527527        goto err2;
    528528    }
    529529
    530     status = map_image(fd, path, image);
     530    status = map_image(fd, path, image, eheader.e_type == ET_EXEC);
    531531    if (status < B_OK) {
    532532        FATAL("%s: Could not map image: %s\n", image->path, strerror(status));
    533533        status = B_ERROR;
  • src/system/runtime_loader/images.cpp

    diff --git a/src/system/runtime_loader/images.cpp b/src/system/runtime_loader/images.cpp
    index d851f9f..2b7f6df 100644
    a b topological_sort(image_t* image, uint32 slot, image_t** initList,  
    169169*/
    170170static void
    171171get_image_region_load_address(image_t* image, uint32 index, long lastDelta,
    172     addr_t& loadAddress, uint32& addressSpecifier)
     172    bool fixed, addr_t& loadAddress, uint32& addressSpecifier)
    173173{
    174     if (image->dynamic_ptr != 0) {
     174    if (!fixed) {
    175175        // relocatable image... we can afford to place wherever
    176176        if (index == 0) {
    177177            // but only the first segment gets a free ride
    put_image(image_t* image)  
    286286
    287287
    288288status_t
    289 map_image(int fd, char const* path, image_t* image)
     289map_image(int fd, char const* path, image_t* image, bool fixed)
    290290{
    291291    // cut the file name from the path as base name for the created areas
    292292    const char* baseName = strrchr(path, '/');
    map_image(int fd, char const* path, image_t* image)  
    304304    uint32 addressSpecifier = B_RANDOMIZED_ANY_ADDRESS;
    305305
    306306    for (uint32 i = 0; i < image->num_regions; i++) {
     307        // for BeOS compatibility: if we load an old BeOS executable, we
     308        // have to relocate it, if possible - we recognize it because the
     309        // vmstart is set to 0 (hopefully always)
     310        if (fixed && image->regions[i].vmstart == 0)
     311            fixed = false;
     312
    307313        uint32 regionAddressSpecifier;
    308314        get_image_region_load_address(image, i,
    309315            i > 0 ? loadAddress - image->regions[i - 1].vmstart : 0,
    310             loadAddress, regionAddressSpecifier);
     316            fixed, loadAddress, regionAddressSpecifier);
    311317        if (i == 0) {
    312318            reservedAddress = loadAddress;
    313319            addressSpecifier = regionAddressSpecifier;
    map_image(int fd, char const* path, image_t* image)  
    339345            baseName, i, (image->regions[i].flags & RFLAG_RW) ? "rw" : "ro");
    340346
    341347        get_image_region_load_address(image, i,
    342             i > 0 ? image->regions[i - 1].delta : 0, loadAddress,
     348            i > 0 ? image->regions[i - 1].delta : 0, fixed, loadAddress,
    343349            addressSpecifier);
    344350
    345351        // If the image position is arbitrary, we must let it point to the start
  • src/system/runtime_loader/images.h

    diff --git a/src/system/runtime_loader/images.h b/src/system/runtime_loader/images.h
    index 7a309bb..a929040 100644
    a b void delete_image_struct(image_t* image);  
    5050void        delete_image(image_t* image);
    5151void        put_image(image_t* image);
    5252
    53 status_t    map_image(int fd, char const* path, image_t* image);
     53status_t    map_image(int fd, char const* path, image_t* image, bool fixed);
    5454void        unmap_image(image_t* image);
    5555void        remap_images();
    5656