flatten_string/process env: realign env and clear trailing bits
envs are stuck after args which are now possibly unaligned, and used
from a non-aligned pointer in prepare_process_ranges_args_envs (env)
The memory immediately after args/envs is copied anyway with memcpy_long,
so make sure the bits are initialized and realign env correctly
Fixes: 70e52faf36 ("flatten_strings: do not return unused trailing bits")
Change-Id: Ic747e947d151c0eea65dec36bc9c888cf6e0c394
This commit is contained in:
committed by
Dominique Martinet
parent
38e68f358a
commit
525b90d028
@@ -1012,7 +1012,7 @@ void print_flat(char *flat)
|
||||
*/
|
||||
int flatten_strings(char *pre_strings, char **strings, char **flat)
|
||||
{
|
||||
int full_len, i;
|
||||
int full_len, len, i;
|
||||
int nr_strings;
|
||||
int pre_strings_count = 0;
|
||||
int pre_strings_len = 0;
|
||||
@@ -1076,7 +1076,11 @@ int flatten_strings(char *pre_strings, char **strings, char **flat)
|
||||
_flat[nr_strings + pre_strings_count + 1] = p - (char *)_flat;
|
||||
|
||||
*flat = (char *)_flat;
|
||||
return p - (char *)_flat;
|
||||
len = p - (char *)_flat;
|
||||
if (len < full_len)
|
||||
memset(p, 0, full_len - len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
//#define NUM_HANDLER_THREADS 248
|
||||
|
||||
@@ -75,7 +75,7 @@ int prepare_process_ranges_args_envs(struct thread *thread,
|
||||
char *envs, int envs_len)
|
||||
{
|
||||
char *args_envs, *args_envs_r;
|
||||
unsigned long args_envs_p, args_envs_rp;
|
||||
unsigned long args_envs_p, args_envs_rp, envs_offset;
|
||||
unsigned long s, e, up;
|
||||
char **argv;
|
||||
int i, n, argc, envc, args_envs_npages;
|
||||
@@ -336,7 +336,13 @@ int prepare_process_ranges_args_envs(struct thread *thread,
|
||||
|
||||
dkprintf("envs copy, nr: %d\n", *((long *)args_envs_r));
|
||||
|
||||
memcpy_long(args_envs + p->args_len, args_envs_r, p->envs_len + sizeof(long) - 1);
|
||||
/* p->args_len is not necessarily long-aligned, even if the memory
|
||||
* below exists and is zeroed out - env must start aligned
|
||||
*/
|
||||
envs_offset = (p->args_len + sizeof(long) - 1) & ~(sizeof(long) - 1);
|
||||
|
||||
memcpy_long(args_envs + envs_offset, args_envs_r,
|
||||
p->envs_len + sizeof(long) - 1);
|
||||
|
||||
/* Only map remote address if it wasn't specified as an argument */
|
||||
if (!envs) {
|
||||
@@ -375,12 +381,12 @@ int prepare_process_ranges_args_envs(struct thread *thread,
|
||||
argv[i] = (char *)addr + (unsigned long)argv[i];
|
||||
}
|
||||
|
||||
envc = *((long *)(args_envs + p->args_len));
|
||||
envc = *((long *)(args_envs + envs_offset));
|
||||
dkprintf("envc: %d\n", envc);
|
||||
|
||||
env = (char **)(args_envs + p->args_len + sizeof(long));
|
||||
env = (char **)(args_envs + envs_offset + sizeof(long));
|
||||
for (i = 0; i < envc; i++) {
|
||||
env[i] = addr + p->args_len + env[i];
|
||||
env[i] = addr + envs_offset + env[i];
|
||||
}
|
||||
|
||||
dkprintf("env OK\n");
|
||||
|
||||
@@ -234,7 +234,7 @@ int memcmp(const void *s1, const void *s2, size_t n)
|
||||
*/
|
||||
int flatten_strings_from_user(char *pre_strings, char **strings, char **flat)
|
||||
{
|
||||
int full_len, i;
|
||||
int full_len, len, i;
|
||||
int nr_strings = 0;
|
||||
int pre_strings_count = 0;
|
||||
int pre_strings_len = 0;
|
||||
@@ -333,5 +333,8 @@ int flatten_strings_from_user(char *pre_strings, char **strings, char **flat)
|
||||
_flat[nr_strings + pre_strings_count + 1] = p - (char *)_flat;
|
||||
|
||||
*flat = (char *)_flat;
|
||||
return p - (char *)_flat;
|
||||
len = p - (char *)_flat;
|
||||
if (len < full_len)
|
||||
memset(p, 0, full_len - len);
|
||||
return len;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user