diff options
author | Matthew Dempsky <matthew@cvs.openbsd.org> | 2012-08-20 23:25:08 +0000 |
---|---|---|
committer | Matthew Dempsky <matthew@cvs.openbsd.org> | 2012-08-20 23:25:08 +0000 |
commit | e8aa6e1c7aa4074e069f239019ca7c438fbe8fe6 (patch) | |
tree | 26a226348a9cd5eb3a30c52e2291b5c5bf316a9e /libexec | |
parent | 56a2a8770254909ecd8125ccde946f43704bb32a (diff) |
Add support for .openbsd.randomdata sections and PT_OPENBSD_RANDOMIZE
segments to the kernel, ld (2.15), and ld.so. Tested on alpha, amd64,
i386, macppc, and sparc64 (thanks naddy, mpi, and okan!).
Idea discussed for some time; committing now for further testing.
ok deraadt
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/ld.so/SPECS.randomdata | 48 | ||||
-rw-r--r-- | libexec/ld.so/library.c | 15 | ||||
-rw-r--r-- | libexec/ld.so/library_mquery.c | 8 |
3 files changed, 68 insertions, 3 deletions
diff --git a/libexec/ld.so/SPECS.randomdata b/libexec/ld.so/SPECS.randomdata new file mode 100644 index 00000000000..434de2ee3de --- /dev/null +++ b/libexec/ld.so/SPECS.randomdata @@ -0,0 +1,48 @@ +$OpenBSD: SPECS.randomdata,v 1.1 2012/08/20 23:25:07 matthew Exp $ + +This document describes the OpenBSD operating system supplement for +adding "random data" sections to the ELF ABI. These sections can be +useful for holding values like GCC's stack-smashing protector cookies +and offer additional benefits like ensuring the data is initialized +before any constructor methods are called and allowing the dynamic +linker to mark the memory as read-only after initialization. + + +Program Header + +OpenBSD defines the following operating system-specific segment type: + + Name Value + PT_OPENBSD_RANDOMIZE 0x65a3dbe6 + + + PT_OPENBSD_RANDOMIZE + + The array element specifies the location and size of a random data + section. The system will initialize the specified memory range + with random data. The memory range must be separately mapped + (e.g., by use of a PT_LOAD segment). + + +Special Sections + +OpenBSD defines the following operating system-specific special +sections: + + Name Type Attributes + .openbsd.randomdata SHT_PROGBITS SHF_ALLOC + + + .openbsd.randomdata + + This section holds the random data section. + + +Implementation Notes + +On OpenBSD, PT_OPENBSD_RANDOMIZE segments are handled alongside +PT_LOAD segments: the kernel handles initializing random data segments +in executables and program interpreters (i.e., ld.so), while ld.so +handles initializing them in shared libraries. Additionally, the +kernel limits the total number of PT_OPENBSD_RANDOMIZE segment bytes +in an executable or interpreter to 1024 bytes. diff --git a/libexec/ld.so/library.c b/libexec/ld.so/library.c index 1dd2013e6df..60c69f370c6 100644 --- a/libexec/ld.so/library.c +++ b/libexec/ld.so/library.c @@ -1,4 +1,4 @@ -/* $OpenBSD: library.c,v 1.66 2012/06/12 20:32:17 matthew Exp $ */ +/* $OpenBSD: library.c,v 1.67 2012/08/20 23:25:07 matthew Exp $ */ /* * Copyright (c) 2002 Dale Rahn @@ -181,7 +181,8 @@ _dl_tryload_shlib(const char *libname, int type, int flags) phdp = (Elf_Phdr *)(hbuf + ehdr->e_phoff); for (i = 0; i < ehdr->e_phnum; i++, phdp++) { - if (phdp->p_type == PT_LOAD) { + switch (phdp->p_type) { + case PT_LOAD: { char *start = (char *)(TRUNC_PG(phdp->p_vaddr)) + loff; Elf_Addr off = (phdp->p_vaddr & align); Elf_Addr size = off + phdp->p_filesz; @@ -233,6 +234,16 @@ _dl_tryload_shlib(const char *libname, int type, int flags) return(0); } } + break; + } + + case PT_OPENBSD_RANDOMIZE: + _dl_randombuf((char *)(phdp->p_vaddr + loff), + phdp->p_memsz); + break; + + default: + break; } } diff --git a/libexec/ld.so/library_mquery.c b/libexec/ld.so/library_mquery.c index aedfd091f8b..abbde2e533d 100644 --- a/libexec/ld.so/library_mquery.c +++ b/libexec/ld.so/library_mquery.c @@ -1,4 +1,4 @@ -/* $OpenBSD: library_mquery.c,v 1.43 2012/07/21 06:46:58 matthew Exp $ */ +/* $OpenBSD: library_mquery.c,v 1.44 2012/08/20 23:25:07 matthew Exp $ */ /* * Copyright (c) 2002 Dale Rahn @@ -266,6 +266,12 @@ retry: load_end = (Elf_Addr)ld->start + ROUND_PG(ld->size); } + phdp = (Elf_Phdr *)(hbuf + ehdr->e_phoff); + for (i = 0; i < ehdr->e_phnum; i++, phdp++) + if (phdp->p_type == PT_OPENBSD_RANDOMIZE) + _dl_randombuf((char *)(phdp->p_vaddr + LOFF), + phdp->p_memsz); + prebind_data = prebind_load_fd(libfile, libname); _dl_close(libfile); |