linux-user: Define AT_RANDOM to support target stack protection mechanism.
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 <cedric.vincent@st.com>
Signed-off-by: Laurent ALFONSI <laurent.alfonsi@st.com>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
			
			
This commit is contained in:
		
							parent
							
								
									055e090687
								
							
						
					
					
						commit
						14322bad88
					
				@ -927,7 +927,7 @@ struct exec
 | 
				
			|||||||
#define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1))
 | 
					#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 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)
 | 
					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;
 | 
					    abi_ulong sp;
 | 
				
			||||||
    int size;
 | 
					    int size;
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    abi_ulong u_rand_bytes;
 | 
				
			||||||
 | 
					    uint8_t k_rand_bytes[16];
 | 
				
			||||||
    abi_ulong u_platform;
 | 
					    abi_ulong u_platform;
 | 
				
			||||||
    const char *k_platform;
 | 
					    const char *k_platform;
 | 
				
			||||||
    const int n = sizeof(elf_addr_t);
 | 
					    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 */
 | 
					        /* FIXME - check return value of memcpy_to_target() for failure */
 | 
				
			||||||
        memcpy_to_target(sp, k_platform, len);
 | 
					        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.
 | 
					     * 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_EGID, (abi_ulong) getegid());
 | 
				
			||||||
    NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP);
 | 
					    NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP);
 | 
				
			||||||
    NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
 | 
					    NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
 | 
				
			||||||
 | 
					    NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (k_platform)
 | 
					    if (k_platform)
 | 
				
			||||||
        NEW_AUX_ENT(AT_PLATFORM, u_platform);
 | 
					        NEW_AUX_ENT(AT_PLATFORM, u_platform);
 | 
				
			||||||
#ifdef ARCH_DLINFO
 | 
					#ifdef ARCH_DLINFO
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user