[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 09/18] linux-user: Define AT_RANDOM to support targe
From: |
riku . voipio |
Subject: |
[Qemu-devel] [PATCH 09/18] linux-user: Define AT_RANDOM to support target stack protection mechanism. |
Date: |
Mon, 20 Jun 2011 19:20:14 +0300 |
From: Laurent ALFONSI <address@hidden>
Note that the support for the command-line argument requires:
1. add the new field "uint8_t rand_bytes[16]" to "struct
image_info" since only the variable "info" lives both in
main() and in create_elf_tables()
2. write a dedicated parser to convert the command-line to fill
rand_bytes[]
These two steps aren't really hard to achieve but I finally think they
are a little bit overkill regarding the purpose of these 16 bytes.
Maybe we could always fill the 16 bytes pointed to by AT_RANDOM with
zero if we really want to get reproducibility.
Regards,
Cédric.
8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----
The dynamic linker from the GNU C library v2.10+ uses the ELF
auxiliary vector AT_RANDOM [1] as a pointer to 16 bytes with random
values to initialize the stack protection mechanism. Technically the
emulated GNU dynamic linker crashes due to a NULL pointer
derefencement if it is built with stack protection enabled and if
AT_RANDOM is not defined by the QEMU ELF loader.
[1] This ELF auxiliary vector was introduced in Linux v2.6.29.
This patch can be tested with the code above:
#include <elf.h> /* Elf*_auxv_t, AT_RANDOM, */
#include <stdio.h> /* printf(3), */
#include <stdlib.h> /* exit(3), EXIT_*, */
#include <stdint.h> /* uint8_t, */
#include <string.h> /* memcpy(3), */
#if defined(__LP64__) || defined(__ILP64__) || defined(__LLP64__)
# define Elf_auxv_t Elf64_auxv_t
#else
# define Elf_auxv_t Elf32_auxv_t
#endif
main(int argc, char* argv[], char* envp[])
{
Elf_auxv_t *auxv;
/* *envp = NULL marks end of envp. */
while (*envp++ != NULL);
/* auxv->a_type = AT_NULL marks the end of auxv. */
for (auxv = (Elf_auxv_t *)envp; auxv->a_type != AT_NULL; auxv++) {
if (auxv->a_type == AT_RANDOM) {
int i;
uint8_t rand_bytes[16];
printf("AT_RANDOM is: 0x%x\n", auxv->a_un.a_val);
memcpy(rand_bytes, (const uint8_t *)auxv->a_un.a_val,
sizeof(rand_bytes));
printf("it points to: ");
for (i = 0; i < 16; i++) {
printf("0x%02x ", rand_bytes[i]);
}
printf("\n");
exit(EXIT_SUCCESS);
}
}
exit(EXIT_FAILURE);
}
Changes introduced in v2 and v3:
* Fix typos + thinko (AT_RANDOM is used for stack canary, not for
ASLR)
* AT_RANDOM points to 16 random bytes stored inside the user
stack.
* Add a small test program.
Signed-off-by: Cédric VINCENT <address@hidden>
Signed-off-by: Laurent ALFONSI <address@hidden>
Signed-off-by: Riku Voipio <address@hidden>
---
linux-user/elfload.c | 21 ++++++++++++++++++++-
1 files changed, 20 insertions(+), 1 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index a13eb7b..b2746f2 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -927,7 +927,7 @@ struct exec
#define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned
long)(TARGET_ELF_EXEC_PAGESIZE-1))
#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
-#define DLINFO_ITEMS 12
+#define DLINFO_ITEMS 13
static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
{
@@ -1202,6 +1202,9 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc,
int envc,
{
abi_ulong sp;
int size;
+ int i;
+ abi_ulong u_rand_bytes;
+ uint8_t k_rand_bytes[16];
abi_ulong u_platform;
const char *k_platform;
const int n = sizeof(elf_addr_t);
@@ -1231,6 +1234,20 @@ static abi_ulong create_elf_tables(abi_ulong p, int
argc, int envc,
/* FIXME - check return value of memcpy_to_target() for failure */
memcpy_to_target(sp, k_platform, len);
}
+
+ /*
+ * Generate 16 random bytes for userspace PRNG seeding (not
+ * cryptically secure but it's not the aim of QEMU).
+ */
+ srand((unsigned int) time(NULL));
+ for (i = 0; i < 16; i++) {
+ k_rand_bytes[i] = rand();
+ }
+ sp -= 16;
+ u_rand_bytes = sp;
+ /* FIXME - check return value of memcpy_to_target() for failure */
+ memcpy_to_target(sp, k_rand_bytes, 16);
+
/*
* Force 16 byte _final_ alignment here for generality.
*/
@@ -1271,6 +1288,8 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc,
int envc,
NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid());
NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP);
NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
+ NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes);
+
if (k_platform)
NEW_AUX_ENT(AT_PLATFORM, u_platform);
#ifdef ARCH_DLINFO
--
1.7.4.1
- [Qemu-devel] [PATCH 05/18] arm-semi.c: Use correct check for failure of do_brk(), (continued)
- [Qemu-devel] [PATCH 05/18] arm-semi.c: Use correct check for failure of do_brk(), riku . voipio, 2011/06/20
- [Qemu-devel] [PATCH 04/18] linux-user: Don't use MAP_FIXED in do_brk(), riku . voipio, 2011/06/20
- [Qemu-devel] [PATCH 02/18] linux-user: Fix the load of ELF files that have no "useful" symbol, riku . voipio, 2011/06/20
- [Qemu-devel] [PATCH 07/18] linux-user: Fix the computation of the requested heap size, riku . voipio, 2011/06/20
- [Qemu-devel] [PATCH 03/18] linux-user: Handle images where lowest vaddr is not page aligned, riku . voipio, 2011/06/20
- [Qemu-devel] [PATCH 06/18] m68k-semi.c: Use correct check for failure of do_brk(), riku . voipio, 2011/06/20
- [Qemu-devel] [PATCH 08/18] linux-user: add pselect6 syscall support, riku . voipio, 2011/06/20
- [Qemu-devel] [PATCH 09/18] linux-user: Define AT_RANDOM to support target stack protection mechanism.,
riku . voipio <=
- [Qemu-devel] [PATCH 10/18] linuxload: id_change was a write only variable, riku . voipio, 2011/06/20
- [Qemu-devel] [PATCH 11/18] syscall: really return ret code, riku . voipio, 2011/06/20
- [Qemu-devel] [PATCH 12/18] linux-user: syscall should use sanitized arg1, riku . voipio, 2011/06/20
- [Qemu-devel] [PATCH 13/18] flatload: end_code was only used in a debug message, riku . voipio, 2011/06/20
- [Qemu-devel] [PATCH 14/18] flatload: memp was a write-only variable, riku . voipio, 2011/06/20
- [Qemu-devel] [PATCH 15/18] linux-user: Bump do_syscall() up to 8 syscall arguments, riku . voipio, 2011/06/20
- [Qemu-devel] [PATCH 16/18] linux-user/signal.c: Remove only-ever-set variable fpu_save_addr, riku . voipio, 2011/06/20
- [Qemu-devel] [PATCH 17/18] linux-user/signal.c: Remove unused fenab, riku . voipio, 2011/06/20
- [Qemu-devel] [PATCH 18/18] linux-user: Fix sync_file_range on 32bit mips, riku . voipio, 2011/06/20