Remove the AT_SYSINFO and AT_SYSINFO_EHDR values if the sysinfo page
is in one of our reserved ranges.
This commit is contained in:
parent
9d66d94780
commit
f558741fab
|
@ -282,17 +282,6 @@ static inline void *wld_memset( void *dest, int val, size_t len )
|
|||
return dest;
|
||||
}
|
||||
|
||||
static inline void *wld_memmove( void *dest, const void *src, size_t len )
|
||||
{
|
||||
const char *s = src;
|
||||
char *d = dest;
|
||||
int i;
|
||||
|
||||
if (d < s) for (i = 0; i < len; i++) d[i] = s[i];
|
||||
else for (i = len - 1; i >= 0; i--) d[i] = s[i];
|
||||
return dest;
|
||||
}
|
||||
|
||||
/*
|
||||
* wld_printf - just the basics
|
||||
*
|
||||
|
@ -377,6 +366,8 @@ static void dump_auxiliary( ElfW(auxv_t) *av )
|
|||
NAME(AT_PHENT),
|
||||
NAME(AT_PHNUM),
|
||||
NAME(AT_PLATFORM),
|
||||
NAME(AT_SYSINFO),
|
||||
NAME(AT_SYSINFO_EHDR),
|
||||
NAME(AT_UID),
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
@ -398,13 +389,28 @@ static void dump_auxiliary( ElfW(auxv_t) *av )
|
|||
*
|
||||
* Set the new auxiliary values
|
||||
*/
|
||||
static void set_auxiliary_values( ElfW(auxv_t) *av, const ElfW(auxv_t) *new_av, void **stack )
|
||||
static void set_auxiliary_values( ElfW(auxv_t) *av, const ElfW(auxv_t) *new_av,
|
||||
const ElfW(auxv_t) *delete_av, void **stack )
|
||||
{
|
||||
int i, j, av_count = 0, new_count = 0;
|
||||
int i, j, av_count = 0, new_count = 0, delete_count = 0;
|
||||
char *src, *dst;
|
||||
|
||||
/* count how many aux values we have already */
|
||||
while (av[av_count].a_type != AT_NULL) av_count++;
|
||||
|
||||
/* delete unwanted values */
|
||||
for (j = 0; delete_av[j].a_type != AT_NULL; j++)
|
||||
{
|
||||
for (i = 0; i < av_count; i++) if (av[i].a_type == delete_av[j].a_type)
|
||||
{
|
||||
av[i].a_type = av[av_count-1].a_type;
|
||||
av[i].a_un.a_val = av[av_count-1].a_un.a_val;
|
||||
av[--av_count].a_type = AT_NULL;
|
||||
delete_count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* count how many values we have in new_av that aren't in av */
|
||||
for (j = 0; new_av[j].a_type != AT_NULL; j++)
|
||||
{
|
||||
|
@ -412,13 +418,20 @@ static void set_auxiliary_values( ElfW(auxv_t) *av, const ElfW(auxv_t) *new_av,
|
|||
if (i == av_count) new_count++;
|
||||
}
|
||||
|
||||
if (new_count) /* need to make room for the extra values */
|
||||
src = (char *)*stack;
|
||||
dst = src - (new_count - delete_count) * sizeof(*av);
|
||||
if (new_count > delete_count) /* need to make room for the extra values */
|
||||
{
|
||||
char *new_stack = (char *)*stack - new_count * sizeof(*av);
|
||||
wld_memmove( new_stack, *stack, (char *)(av + av_count) - (char *)*stack );
|
||||
*stack = new_stack;
|
||||
av -= new_count;
|
||||
int len = (char *)(av + av_count + 1) - src;
|
||||
for (i = 0; i < len; i++) dst[i] = src[i];
|
||||
}
|
||||
else if (new_count < delete_count) /* get rid of unused values */
|
||||
{
|
||||
int len = (char *)(av + av_count + 1) - dst;
|
||||
for (i = len - 1; i >= 0; i--) dst[i] = src[i];
|
||||
}
|
||||
*stack = dst;
|
||||
av -= (new_count - delete_count);
|
||||
|
||||
/* now set the values */
|
||||
for (j = 0; new_av[j].a_type != AT_NULL; j++)
|
||||
|
@ -803,6 +816,28 @@ error:
|
|||
fatal_error( "invalid WINEPRELOADRESERVE value '%s'\n", str );
|
||||
}
|
||||
|
||||
/*
|
||||
* is_in_preload_range
|
||||
*
|
||||
* Check if address of the given aux value is in one of the reserved ranges
|
||||
*/
|
||||
static int is_in_preload_range( const ElfW(auxv_t) *av, int type )
|
||||
{
|
||||
int i;
|
||||
|
||||
while (av->a_type != type && av->a_type != AT_NULL) av++;
|
||||
|
||||
if (av->a_type == type)
|
||||
{
|
||||
for (i = 0; preload_info[i].size; i++)
|
||||
{
|
||||
if ((char *)av->a_un.a_ptr >= (char *)preload_info[i].addr &&
|
||||
(char *)av->a_un.a_ptr < (char *)preload_info[i].addr + preload_info[i].size)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* wld_start
|
||||
|
@ -816,7 +851,7 @@ void* wld_start( void **stack )
|
|||
int i, *pargc;
|
||||
char **argv, **p;
|
||||
char *interp, *reserve = NULL;
|
||||
ElfW(auxv_t) new_av[11], *av;
|
||||
ElfW(auxv_t) new_av[12], delete_av[3], *av;
|
||||
struct wld_link_map main_binary_map, ld_so_map;
|
||||
struct wine_preload_info **wine_main_preload_info;
|
||||
|
||||
|
@ -879,13 +914,20 @@ void* wld_start( void **stack )
|
|||
SET_NEW_AV( 8, AT_EUID, get_auxiliary( av, AT_EUID, wld_geteuid() ) );
|
||||
SET_NEW_AV( 9, AT_GID, get_auxiliary( av, AT_GID, wld_getgid() ) );
|
||||
SET_NEW_AV(10, AT_EGID, get_auxiliary( av, AT_EGID, wld_getegid() ) );
|
||||
SET_NEW_AV(11, AT_NULL, 0 );
|
||||
#undef SET_NEW_AV
|
||||
|
||||
i = 0;
|
||||
/* delete sysinfo values if addresses conflict */
|
||||
if (is_in_preload_range( av, AT_SYSINFO )) delete_av[i++].a_type = AT_SYSINFO;
|
||||
if (is_in_preload_range( av, AT_SYSINFO_EHDR )) delete_av[i++].a_type = AT_SYSINFO_EHDR;
|
||||
delete_av[i].a_type = AT_NULL;
|
||||
|
||||
/* get rid of first argument */
|
||||
pargc[1] = pargc[0] - 1;
|
||||
*stack = pargc + 1;
|
||||
|
||||
set_auxiliary_values( av, new_av, stack );
|
||||
set_auxiliary_values( av, new_av, delete_av, stack );
|
||||
|
||||
#ifdef DUMP_AUX_INFO
|
||||
wld_printf("new stack = %x\n", *stack);
|
||||
|
|
Loading…
Reference in New Issue