[haiku-commits] BRANCH pdziepak-github.aslr - in src/system: kernel ldscripts

  • From: pdziepak-github.aslr <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 16 Apr 2013 02:45:33 +0200 (CEST)

added 2 changesets to branch 'refs/remotes/pdziepak-github/aslr'
old head: d0a8e6ef2bc88d776c0e6f167bbd4ac9b8c262dd
new head: db1ca60528285ea0c6620a5acac93c083fbbca6a
overview: https://github.com/pdziepak/Haiku/compare/d0a8e6e...db1ca60

----------------------------------------------------------------------------

cf35dcc: vm: make aslr use more secure PRNG

db1ca60: runtime_loader: randomize position of runtime_loader
   * make runtime_loader a dynammically linked object
   * add kernel support for loading user images that need to be relocated
   * load runtime_loader at random address

                                    [ Pawel Dziepak <pdziepak@xxxxxxxxxxx> ]

----------------------------------------------------------------------------

5 files changed, 71 insertions(+), 24 deletions(-)
src/system/kernel/elf.cpp                     | 87 +++++++++++++++++------
src/system/kernel/vm/VMUserAddressSpace.cpp   |  2 +-
src/system/ldscripts/x86/runtime_loader.ld    |  2 +-
src/system/ldscripts/x86_64/runtime_loader.ld |  2 +-
src/system/runtime_loader/Jamfile             |  2 +-

############################################################################

Commit:      cf35dcc5bc7827e242b5322fb6a06550c9395896
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Thu Apr 11 15:16:49 2013 UTC

vm: make aslr use more secure PRNG

----------------------------------------------------------------------------

diff --git a/src/system/kernel/vm/VMUserAddressSpace.cpp 
b/src/system/kernel/vm/VMUserAddressSpace.cpp
index a366cf7..71d48a6 100644
--- a/src/system/kernel/vm/VMUserAddressSpace.cpp
+++ b/src/system/kernel/vm/VMUserAddressSpace.cpp
@@ -407,7 +407,7 @@ VMUserAddressSpace::_RandomizeAddress(addr_t start, addr_t 
end,
        else
                range = min_c(range, kMaxRandomize);
 
-       addr_t random = get_random<addr_t>();
+       addr_t random = secure_get_random<addr_t>();
        random %= range;
        random &= ~addr_t(alignment - 1);
 

############################################################################

Commit:      db1ca60528285ea0c6620a5acac93c083fbbca6a
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Tue Apr 16 00:29:05 2013 UTC

runtime_loader: randomize position of runtime_loader
 * make runtime_loader a dynammically linked object
 * add kernel support for loading user images that need to be relocated
 * load runtime_loader at random address

----------------------------------------------------------------------------

diff --git a/src/system/kernel/elf.cpp b/src/system/kernel/elf.cpp
index 307b55b..d937d8a 100644
--- a/src/system/kernel/elf.cpp
+++ b/src/system/kernel/elf.cpp
@@ -1069,7 +1069,7 @@ elf_resolve_symbol(struct elf_image_info *image, elf_sym 
*symbol,
 
 /*! Until we have shared library support, just this links against the kernel */
 static int
-elf_relocate(struct elf_image_info *image)
+elf_relocate(struct elf_image_info* image, struct elf_image_info* resolveImage)
 {
        int status = B_NO_ERROR;
 
@@ -1079,7 +1079,7 @@ elf_relocate(struct elf_image_info *image)
        if (image->rel) {
                TRACE(("total %i rel relocs\n", image->rel_len / 
(int)sizeof(elf_rel)));
 
-               status = arch_elf_relocate_rel(image, sKernelImage, image->rel,
+               status = arch_elf_relocate_rel(image, resolveImage, image->rel,
                        image->rel_len);
                if (status < B_OK)
                        return status;
@@ -1089,12 +1089,12 @@ elf_relocate(struct elf_image_info *image)
                if (image->pltrel_type == DT_REL) {
                        TRACE(("total %i plt-relocs\n",
                                image->pltrel_len / (int)sizeof(elf_rel)));
-                       status = arch_elf_relocate_rel(image, sKernelImage, 
image->pltrel,
+                       status = arch_elf_relocate_rel(image, resolveImage, 
image->pltrel,
                                image->pltrel_len);
                } else {
                        TRACE(("total %i plt-relocs\n",
                                image->pltrel_len / (int)sizeof(elf_rela)));
-                       status = arch_elf_relocate_rela(image, sKernelImage,
+                       status = arch_elf_relocate_rela(image, resolveImage,
                                (elf_rela *)image->pltrel, image->pltrel_len);
                }
                if (status < B_OK)
@@ -1105,7 +1105,7 @@ elf_relocate(struct elf_image_info *image)
                TRACE(("total %i rel relocs\n",
                        image->rela_len / (int)sizeof(elf_rela)));
 
-               status = arch_elf_relocate_rela(image, sKernelImage, 
image->rela,
+               status = arch_elf_relocate_rela(image, resolveImage, 
image->rela,
                        image->rela_len);
                if (status < B_OK)
                        return status;
@@ -1288,7 +1288,7 @@ insert_preloaded_image(preloaded_elf_image 
*preloadedImage, bool kernel)
                if (status != B_OK)
                        goto error1;
 
-               status = elf_relocate(image);
+               status = elf_relocate(image, sKernelImage);
                if (status != B_OK)
                        goto error1;
        } else
@@ -1825,6 +1825,8 @@ elf_load_user_image(const char *path, Team *team, int 
flags, addr_t *entry)
        ssize_t length;
        int fd;
        int i;
+       addr_t delta = 0;
+       uint32 addressSpec = B_RANDOMIZED_BASE_ADDRESS;
 
        TRACE(("elf_load: entry path '%s', team %p\n", path, team));
 
@@ -1854,6 +1856,14 @@ elf_load_user_image(const char *path, Team *team, int 
flags, addr_t *entry)
        if (status < B_OK)
                goto error;
 
+       struct elf_image_info* image;
+       image = create_image_struct();
+       if (image == NULL) {
+               status = B_NO_MEMORY;
+               goto error;
+       }
+       image->elf_header = &elfHeader;
+
        // read program header
 
        programHeaders = (elf_phdr *)malloc(
@@ -1861,7 +1871,7 @@ elf_load_user_image(const char *path, Team *team, int 
flags, addr_t *entry)
        if (programHeaders == NULL) {
                dprintf("error allocating space for program headers\n");
                status = B_NO_MEMORY;
-               goto error;
+               goto error2;
        }
 
        TRACE(("reading in program headers at 0x%lx, length 0x%x\n",
@@ -1871,12 +1881,12 @@ elf_load_user_image(const char *path, Team *team, int 
flags, addr_t *entry)
        if (length < B_OK) {
                status = length;
                dprintf("error reading in program headers\n");
-               goto error;
+               goto error2;
        }
        if (length != elfHeader.e_phnum * elfHeader.e_phentsize) {
                dprintf("short read while reading in program headers\n");
                status = -1;
-               goto error;
+               goto error2;
        }
 
        // construct a nice name for the region we have to create below
@@ -1904,13 +1914,21 @@ elf_load_user_image(const char *path, Team *team, int 
flags, addr_t *entry)
        for (i = 0; i < elfHeader.e_phnum; i++) {
                char regionName[B_OS_NAME_LENGTH];
                char *regionAddress;
+               char *originalRegionAddress;
                area_id id;
 
+               if (programHeaders[i].p_type == PT_DYNAMIC) {
+                       image->dynamic_section = programHeaders[i].p_vaddr;
+                       continue;
+               }
+
                if (programHeaders[i].p_type != PT_LOAD)
                        continue;
 
-               regionAddress = (char *)ROUNDDOWN(programHeaders[i].p_vaddr,
-                       B_PAGE_SIZE);
+               regionAddress = (char *)(ROUNDDOWN(programHeaders[i].p_vaddr,
+                       B_PAGE_SIZE) + delta);
+               originalRegionAddress = regionAddress;
+
                if (programHeaders[i].p_flags & PF_WRITE) {
                        // rw/data segment
                        size_t memUpperBound = (programHeaders[i].p_vaddr % 
B_PAGE_SIZE)
@@ -1924,18 +1942,21 @@ elf_load_user_image(const char *path, Team *team, int 
flags, addr_t *entry)
                        sprintf(regionName, "%s_seg%drw", baseName, i);
 
                        id = vm_map_file(team->id, regionName, (void 
**)&regionAddress,
-                               B_EXACT_ADDRESS, fileUpperBound,
+                               addressSpec, fileUpperBound,
                                B_READ_AREA | B_WRITE_AREA, REGION_PRIVATE_MAP, 
false,
                                fd, ROUNDDOWN(programHeaders[i].p_offset, 
B_PAGE_SIZE));
                        if (id < B_OK) {
                                dprintf("error mapping file data: %s!\n", 
strerror(id));
                                status = B_NOT_AN_EXECUTABLE;
-                               goto error;
+                               goto error2;
                        }
 
                        imageInfo.data = regionAddress;
                        imageInfo.data_size = memUpperBound;
 
+                       image->data_region.start = (addr_t)regionAddress;
+                       image->data_region.size = memUpperBound;
+
                        // clean garbage brought by mmap (the region behind the 
file,
                        // at least parts of it are the bss and have to be 
zeroed)
                        addr_t start = (addr_t)regionAddress
@@ -1965,7 +1986,7 @@ elf_load_user_image(const char *path, Team *team, int 
flags, addr_t *entry)
                                if (id < B_OK) {
                                        dprintf("error allocating bss area: 
%s!\n", strerror(id));
                                        status = B_NOT_AN_EXECUTABLE;
-                                       goto error;
+                                       goto error2;
                                }
                        }
                } else {
@@ -1976,20 +1997,42 @@ elf_load_user_image(const char *path, Team *team, int 
flags, addr_t *entry)
                                + (programHeaders[i].p_vaddr % B_PAGE_SIZE), 
B_PAGE_SIZE);
 
                        id = vm_map_file(team->id, regionName, (void 
**)&regionAddress,
-                               B_EXACT_ADDRESS, segmentSize,
-                               B_READ_AREA | B_EXECUTE_AREA, 
REGION_PRIVATE_MAP, false,
-                               fd, ROUNDDOWN(programHeaders[i].p_offset, 
B_PAGE_SIZE));
+                               addressSpec, segmentSize,
+                               B_READ_AREA | B_EXECUTE_AREA | B_WRITE_AREA, 
REGION_PRIVATE_MAP,
+                               false, fd, 
ROUNDDOWN(programHeaders[i].p_offset, B_PAGE_SIZE));
                        if (id < B_OK) {
                                dprintf("error mapping file text: %s!\n", 
strerror(id));
                                status = B_NOT_AN_EXECUTABLE;
-                               goto error;
+                               goto error2;
                        }
 
                        imageInfo.text = regionAddress;
                        imageInfo.text_size = segmentSize;
+
+                       image->text_region.start = (addr_t)regionAddress;
+                       image->text_region.size = segmentSize;
+               }
+
+               if (addressSpec != B_EXACT_ADDRESS) {
+                       addressSpec = B_EXACT_ADDRESS;
+                       delta = regionAddress - originalRegionAddress;
                }
        }
 
+       image->data_region.delta = delta;
+       image->text_region.delta = delta;
+
+       // modify the dynamic ptr by the delta of the regions
+       image->dynamic_section += image->text_region.delta;
+
+       status = elf_parse_dynamic_section(image);
+       if (status != B_OK)
+               goto error2;
+
+       status = elf_relocate(image, image);
+       if (status != B_OK)
+               goto error2;
+
        // register the loaded image
        imageInfo.type = B_LIBRARY_IMAGE;
     imageInfo.device = st.st_dev;
@@ -2009,9 +2052,13 @@ elf_load_user_image(const char *path, Team *team, int 
flags, addr_t *entry)
 
        TRACE(("elf_load: done!\n"));
 
-       *entry = elfHeader.e_entry;
+       *entry = elfHeader.e_entry + delta;
        status = B_OK;
 
+error2:
+       image->elf_header = NULL;
+       delete_elf_image(image);
+
 error:
        free(programHeaders);
        _kern_close(fd);
@@ -2258,7 +2305,7 @@ load_kernel_add_on(const char *path)
        if (status != B_OK)
                goto error5;
 
-       status = elf_relocate(image);
+       status = elf_relocate(image, sKernelImage);
        if (status < B_OK)
                goto error5;
 
diff --git a/src/system/ldscripts/x86/runtime_loader.ld 
b/src/system/ldscripts/x86/runtime_loader.ld
index 2bc53c6..ae1062f 100644
--- a/src/system/ldscripts/x86/runtime_loader.ld
+++ b/src/system/ldscripts/x86/runtime_loader.ld
@@ -5,7 +5,7 @@ ENTRY(runtime_loader)
 SEARCH_DIR("libgcc");
 SECTIONS
 {
-       . = 0x00100000 + SIZEOF_HEADERS;
+       . = 0x00000000 + SIZEOF_HEADERS;
 
        .interp : { *(.interp) }
        .hash : { *(.hash) }
diff --git a/src/system/ldscripts/x86_64/runtime_loader.ld 
b/src/system/ldscripts/x86_64/runtime_loader.ld
index a83a6de..ee0b42f 100644
--- a/src/system/ldscripts/x86_64/runtime_loader.ld
+++ b/src/system/ldscripts/x86_64/runtime_loader.ld
@@ -5,7 +5,7 @@ ENTRY(runtime_loader)
 SEARCH_DIR("libgcc");
 SECTIONS
 {
-       . = 0x00200000 + SIZEOF_HEADERS;
+       . = 0x00000000 + SIZEOF_HEADERS;
 
        .interp : { *(.interp) }
        .hash : { *(.hash) }
diff --git a/src/system/runtime_loader/Jamfile 
b/src/system/runtime_loader/Jamfile
index d687912..11bc811 100644
--- a/src/system/runtime_loader/Jamfile
+++ b/src/system/runtime_loader/Jamfile
@@ -91,7 +91,7 @@ Ld runtime_loader :
        $(TARGET_STATIC_LIBSUPC++)
        $(TARGET_GCC_LIBGCC)
        : $(HAIKU_TOP)/src/system/ldscripts/$(TARGET_ARCH)/runtime_loader.ld
-       : --no-undefined
+       : --no-undefined -shared -soname=runtime_loader
 ;
 
 HaikuSubInclude arch $(TARGET_ARCH) ;


Other related posts:

  • » [haiku-commits] BRANCH pdziepak-github.aslr - in src/system: kernel ldscripts - pdziepak-github . aslr