Commit f558741f authored by Alexandre Julliard's avatar Alexandre Julliard

Remove the AT_SYSINFO and AT_SYSINFO_EHDR values if the sysinfo page

is in one of our reserved ranges.
parent 9d66d947
...@@ -282,17 +282,6 @@ static inline void *wld_memset( void *dest, int val, size_t len ) ...@@ -282,17 +282,6 @@ static inline void *wld_memset( void *dest, int val, size_t len )
return dest; 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 * wld_printf - just the basics
* *
...@@ -377,6 +366,8 @@ static void dump_auxiliary( ElfW(auxv_t) *av ) ...@@ -377,6 +366,8 @@ static void dump_auxiliary( ElfW(auxv_t) *av )
NAME(AT_PHENT), NAME(AT_PHENT),
NAME(AT_PHNUM), NAME(AT_PHNUM),
NAME(AT_PLATFORM), NAME(AT_PLATFORM),
NAME(AT_SYSINFO),
NAME(AT_SYSINFO_EHDR),
NAME(AT_UID), NAME(AT_UID),
{ 0, NULL } { 0, NULL }
}; };
...@@ -398,13 +389,28 @@ static void dump_auxiliary( ElfW(auxv_t) *av ) ...@@ -398,13 +389,28 @@ static void dump_auxiliary( ElfW(auxv_t) *av )
* *
* Set the new auxiliary values * 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 */ /* count how many aux values we have already */
while (av[av_count].a_type != AT_NULL) av_count++; 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 */ /* 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++) 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, ...@@ -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 (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 */
{
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 */
{ {
char *new_stack = (char *)*stack - new_count * sizeof(*av); int len = (char *)(av + av_count + 1) - dst;
wld_memmove( new_stack, *stack, (char *)(av + av_count) - (char *)*stack ); for (i = len - 1; i >= 0; i--) dst[i] = src[i];
*stack = new_stack;
av -= new_count;
} }
*stack = dst;
av -= (new_count - delete_count);
/* now set the values */ /* now set the values */
for (j = 0; new_av[j].a_type != AT_NULL; j++) for (j = 0; new_av[j].a_type != AT_NULL; j++)
...@@ -803,6 +816,28 @@ error: ...@@ -803,6 +816,28 @@ error:
fatal_error( "invalid WINEPRELOADRESERVE value '%s'\n", str ); 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 * wld_start
...@@ -816,7 +851,7 @@ void* wld_start( void **stack ) ...@@ -816,7 +851,7 @@ void* wld_start( void **stack )
int i, *pargc; int i, *pargc;
char **argv, **p; char **argv, **p;
char *interp, *reserve = NULL; 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 wld_link_map main_binary_map, ld_so_map;
struct wine_preload_info **wine_main_preload_info; struct wine_preload_info **wine_main_preload_info;
...@@ -879,13 +914,20 @@ void* wld_start( void **stack ) ...@@ -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( 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( 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(10, AT_EGID, get_auxiliary( av, AT_EGID, wld_getegid() ) );
SET_NEW_AV(11, AT_NULL, 0 );
#undef SET_NEW_AV #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 */ /* get rid of first argument */
pargc[1] = pargc[0] - 1; pargc[1] = pargc[0] - 1;
*stack = pargc + 1; *stack = pargc + 1;
set_auxiliary_values( av, new_av, stack ); set_auxiliary_values( av, new_av, delete_av, stack );
#ifdef DUMP_AUX_INFO #ifdef DUMP_AUX_INFO
wld_printf("new stack = %x\n", *stack); wld_printf("new stack = %x\n", *stack);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment