summaryrefslogtreecommitdiffstats
path: root/tools/soslim
diff options
context:
space:
mode:
authorHristo Bojinov <hristo@google.com>2010-08-02 10:26:17 -0700
committerHristo Bojinov <hristo@google.com>2010-08-02 14:25:01 -0700
commit96be7205dce97977909e93b73f48779fcce3bc65 (patch)
treeae0cf3b9f076c1ed41893e5ec81abcd46c6b85e3 /tools/soslim
parent778c2b690025a91b55b2e841921605c55baf652c (diff)
downloadbuild-96be7205dce97977909e93b73f48779fcce3bc65.tar.gz
build-96be7205dce97977909e93b73f48779fcce3bc65.tar.bz2
build-96be7205dce97977909e93b73f48779fcce3bc65.zip
Working ASLR implementation.
ASLR for shared libraries is controlled by "-a" in ota_from_target_files. Binary files are self-contained (supported by apriori/soslim). Signed-off-by: Hristo Bojinov <hristo@google.com> Change-Id: I500e325bf4a70a8d69a2ab9b2938e83dadb4e65d
Diffstat (limited to 'tools/soslim')
-rw-r--r--tools/soslim/main.c18
-rw-r--r--tools/soslim/prelink_info.c101
-rw-r--r--tools/soslim/prelink_info.h4
-rw-r--r--tools/soslim/soslim.c10
-rw-r--r--tools/soslim/soslim.h5
5 files changed, 131 insertions, 7 deletions
diff --git a/tools/soslim/main.c b/tools/soslim/main.c
index dd8a60bb7..e23fbcec7 100644
--- a/tools/soslim/main.c
+++ b/tools/soslim/main.c
@@ -188,9 +188,13 @@ int main(int argc, char **argv)
else INFO("Not building symbol filter, filter file is empty.\n");
}
#ifdef SUPPORT_ANDROID_PRELINK_TAGS
- int prelinked = 0;
+ int prelinked = 0, retouched = 0;
int elf_little; /* valid if prelinked != 0 */
long prelink_addr; /* valid if prelinked != 0 */
+#define RETOUCH_MAX_SIZE 500000
+ /* _cnt valid if retouched != 0 */
+ unsigned int retouch_byte_cnt = RETOUCH_MAX_SIZE;
+ char retouch_buf[RETOUCH_MAX_SIZE]; /* valid if retouched != 0 */
#endif
clone_elf(elf, newelf,
infile, outfile,
@@ -200,7 +204,10 @@ int main(int argc, char **argv)
#ifdef SUPPORT_ANDROID_PRELINK_TAGS
, &prelinked,
&elf_little,
- &prelink_addr
+ &prelink_addr,
+ &retouched,
+ &retouch_byte_cnt,
+ retouch_buf
#endif
,
true, /* rebuild the section-header-strings table */
@@ -223,6 +230,13 @@ int main(int argc, char **argv)
infile, strerror(errno), errno);
#ifdef SUPPORT_ANDROID_PRELINK_TAGS
+ if (retouched) {
+ INFO("File has retouch data, putting it back in place.\n");
+ retouch_dump(outfile != NULL ? outfile : infile,
+ elf_little,
+ retouch_byte_cnt,
+ retouch_buf);
+ }
if (prelinked) {
INFO("File is prelinked, putting prelink TAG back in place.\n");
setup_prelink_info(outfile != NULL ? outfile : infile,
diff --git a/tools/soslim/prelink_info.c b/tools/soslim/prelink_info.c
index 81d5de304..2600ac73b 100644
--- a/tools/soslim/prelink_info.c
+++ b/tools/soslim/prelink_info.c
@@ -11,6 +11,7 @@
#include <debug.h>
#include <common.h>
+#define RETOUCH_SUFFIX_SIZE 12
typedef struct {
uint32_t mmap_addr;
char tag[4]; /* 'P', 'R', 'E', ' ' */
@@ -28,7 +29,7 @@ static inline void set_prelink(long *prelink_addr,
}
else {
/* Different endianness */
- *prelink_addr = switch_endianness(info->mmap_addr);
+ *prelink_addr = switch_endianness(info->mmap_addr);
}
}
}
@@ -67,10 +68,104 @@ int check_prelinked(const char *fname, int elf_little, long *prelink_addr)
set_prelink(prelink_addr, elf_little, &info);
prelinked = 1;
}
- FAILIF(close(fd) < 0, "close(%d): %s (%d)!\n", fd, strerror(errno), errno);
+ FAILIF(close(fd) < 0,
+ "close(%d): %s (%d)!\n", fd, strerror(errno), errno);
return prelinked;
}
+int check_retouched(const char *fname, int elf_little,
+ unsigned int *retouch_byte_cnt, char *retouch_buf) {
+ FAILIF(sizeof(prelink_info_t) != 8,
+ "Unexpected sizeof(prelink_info_t) == %d!\n",
+ sizeof(prelink_info_t));
+ int fd = open(fname, O_RDONLY);
+ FAILIF(fd < 0, "open(%s, O_RDONLY): %s (%d)!\n",
+ fname, strerror(errno), errno);
+ off_t end = lseek(fd, 0, SEEK_END);
+ int nr = sizeof(prelink_info_t);
+ off_t sz = lseek(fd, -nr-RETOUCH_SUFFIX_SIZE, SEEK_CUR);
+ ASSERT((long)(end - sz) == (long)(nr+RETOUCH_SUFFIX_SIZE));
+ FAILIF(sz == (off_t)-1,
+ "lseek(%d, 0, SEEK_END): %s (%d)!\n",
+ fd, strerror(errno), errno);
+
+ char retouch_meta[RETOUCH_SUFFIX_SIZE];
+ int num_read = read(fd, &retouch_meta, RETOUCH_SUFFIX_SIZE);
+ FAILIF(num_read < 0,
+ "read(%d, &info, sizeof(prelink_info_t)): %s (%d)!\n",
+ fd, strerror(errno), errno);
+ FAILIF(num_read != RETOUCH_SUFFIX_SIZE,
+ "read(%d, &info, sizeof(prelink_info_t)): did not read %d bytes as "
+ "expected (read %d)!\n",
+ fd, RETOUCH_SUFFIX_SIZE, num_read);
+
+ int retouched = 0;
+ if (!strncmp(retouch_meta, "RETOUCH ", 8)) {
+ unsigned int retouch_byte_cnt_meta;
+ if (!(elf_little ^ is_host_little()))
+ retouch_byte_cnt_meta = *(unsigned int *)(retouch_meta+8);
+ else
+ retouch_byte_cnt_meta =
+ switch_endianness(*(unsigned int *)(retouch_meta+8));
+ FAILIF(*retouch_byte_cnt < retouch_byte_cnt_meta,
+ "Retouch buffer too small at %d bytes (%d needed).",
+ *retouch_byte_cnt, retouch_byte_cnt_meta);
+ *retouch_byte_cnt = retouch_byte_cnt_meta;
+ off_t sz = lseek(fd,
+ -((long)*retouch_byte_cnt)-RETOUCH_SUFFIX_SIZE-nr,
+ SEEK_END);
+ ASSERT((long)(end - sz) ==
+ (long)(*retouch_byte_cnt+RETOUCH_SUFFIX_SIZE+nr));
+ FAILIF(sz == (off_t)-1,
+ "lseek(%d, 0, SEEK_END): %s (%d)!\n",
+ fd, strerror(errno), errno);
+ num_read = read(fd, retouch_buf, *retouch_byte_cnt);
+ FAILIF(num_read < 0,
+ "read(%d, &info, sizeof(prelink_info_t)): %s (%d)!\n",
+ fd, strerror(errno), errno);
+ FAILIF(num_read != *retouch_byte_cnt,
+ "read(%d, retouch_buf, %u): did not read %d bytes as "
+ "expected (read %d)!\n",
+ fd, *retouch_byte_cnt, *retouch_byte_cnt, num_read);
+
+ retouched = 1;
+ }
+ FAILIF(close(fd) < 0, "close(%d): %s (%d)!\n", fd, strerror(errno), errno);
+ return retouched;
+}
+
+void retouch_dump(const char *fname, int elf_little,
+ unsigned int retouch_byte_cnt, char *retouch_buf) {
+ int fd = open(fname, O_WRONLY);
+ FAILIF(fd < 0,
+ "open(%s, O_WRONLY): %s (%d)\n",
+ fname, strerror(errno), errno);
+ off_t sz = lseek(fd, 0, SEEK_END);
+ FAILIF(sz == (off_t)-1,
+ "lseek(%d, 0, SEEK_END): %s (%d)!\n",
+ fd, strerror(errno), errno);
+
+ // The retouch blob ends with "RETOUCH XXXX", where XXXX is the 4-byte
+ // size of the retouch blob, in target endianness.
+ strncpy(retouch_buf+retouch_byte_cnt, "RETOUCH ", 8);
+ if (elf_little ^ is_host_little()) {
+ *(unsigned int *)(retouch_buf+retouch_byte_cnt+8) =
+ switch_endianness(retouch_byte_cnt);
+ } else {
+ *(unsigned int *)(retouch_buf+retouch_byte_cnt+8) =
+ retouch_byte_cnt;
+ }
+
+ int num_written = write(fd, retouch_buf, retouch_byte_cnt+12);
+ FAILIF(num_written < 0,
+ "write(%d, &info, sizeof(info)): %s (%d)\n",
+ fd, strerror(errno), errno);
+ FAILIF((retouch_byte_cnt+12) != num_written,
+ "Could not write %d bytes as expected (wrote %d bytes instead)!\n",
+ retouch_byte_cnt, num_written);
+ FAILIF(close(fd) < 0, "close(%d): %s (%d)!\n", fd, strerror(errno), errno);
+}
+
void setup_prelink_info(const char *fname, int elf_little, long base)
{
FAILIF(sizeof(prelink_info_t) != 8, "Unexpected sizeof(prelink_info_t) == %zd!\n", sizeof(prelink_info_t));
@@ -92,7 +187,7 @@ void setup_prelink_info(const char *fname, int elf_little, long base)
else {
/* Different endianness */
INFO("Host and ELF file [%s] have different endianness.\n", fname);
- info.mmap_addr = switch_endianness(base);
+ info.mmap_addr = switch_endianness(base);
}
strncpy(info.tag, "PRE ", 4);
diff --git a/tools/soslim/prelink_info.h b/tools/soslim/prelink_info.h
index e2787cb04..efa84fdab 100644
--- a/tools/soslim/prelink_info.h
+++ b/tools/soslim/prelink_info.h
@@ -3,6 +3,10 @@
#ifdef SUPPORT_ANDROID_PRELINK_TAGS
int check_prelinked(const char *fname, int elf_little, long *prelink_addr);
+int check_retouched(const char *fname, int elf_little,
+ unsigned int *retouch_byte_cnt, char *retouch_buf);
+void retouch_dump(const char *fname, int elf_little,
+ unsigned int retouch_byte_cnt, char *retouch_buf);
void setup_prelink_info(const char *fname, int elf_little, long base);
#endif
diff --git a/tools/soslim/soslim.c b/tools/soslim/soslim.c
index 125e29e89..33b1ee700 100644
--- a/tools/soslim/soslim.c
+++ b/tools/soslim/soslim.c
@@ -27,7 +27,10 @@ void clone_elf(Elf *elf, Elf *newelf,
#ifdef SUPPORT_ANDROID_PRELINK_TAGS
, int *prelinked,
int *elf_little,
- long *prelink_addr
+ long *prelink_addr,
+ int *retouched,
+ unsigned int *retouch_byte_cnt,
+ char *retouch_buf
#endif
, bool rebuild_shstrtab,
bool strip_debug,
@@ -70,6 +73,11 @@ void clone_elf(Elf *elf, Elf *newelf,
ASSERT(elf_little);
*elf_little = (ehdr->e_ident[EI_DATA] == ELFDATA2LSB);
*prelinked = check_prelinked(elf_name, *elf_little, prelink_addr);
+ ASSERT(retouched);
+ ASSERT(retouch_byte_cnt);
+ ASSERT(retouch_buf);
+ *retouched = check_retouched(elf_name, *elf_little,
+ retouch_byte_cnt, retouch_buf);
#endif
INFO("\n\nCALCULATING MODIFICATIONS\n\n");
diff --git a/tools/soslim/soslim.h b/tools/soslim/soslim.h
index dfcb0856b..952c960f3 100644
--- a/tools/soslim/soslim.h
+++ b/tools/soslim/soslim.h
@@ -23,7 +23,10 @@ void clone_elf(Elf *elf, Elf *newelf,
#ifdef SUPPORT_ANDROID_PRELINK_TAGS
, int *prelinked,
int *elf_little,
- long *prelink_addr
+ long *prelink_addr,
+ int *retouched,
+ unsigned int *retouch_byte_cnt,
+ char *retouch_buf
#endif
, bool rebuild_shstrtab,
bool strip_debug,