Commit 2775c8f8 authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Andrei Vagin

x86/restorer/compat: let stack32 be per-thread

As threads restore in parallel, stack32 may be reused concurrently
leading to reusing others thread's data. So, let it lay on stack.
It would still worth making 32-bit stack per-task reusing it in threads
but at this moment introducing such complexity looks like premature
optimization.
It does not affect 64-bit C/R.

Fixes: file_aio, sigaltstack, clone_fs, socket_aio, different_creds, futex

travis-ci: success for 32-bit tests fixes
Signed-off-by: 's avatarDmitry Safonov <dsafonov@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent cbde93e1
......@@ -33,23 +33,14 @@ int restore_nonsigframe_gpregs(UserX86RegsEntry *r)
}
#ifdef CONFIG_COMPAT
/*
* We need here compatible stack, because 32-bit syscalls get
* 4-byte pointer and _usally_ restorer is also under 4Gb, but
* it can be upper and then pointers are messed up.
* (we lose high 4 bytes and... BUNG!)
* Nothing serious, but syscall will return -EFAULT - or if we're
* lucky and lower 4 bytes points on some writeable VMA - corruption).
*/
static void *stack32;
static int prepare_stack32(void)
static int prepare_stack32(void **stack32)
{
if (stack32)
if (*stack32)
return 0;
stack32 = alloc_compat_syscall_stack();
if (!stack32) {
*stack32 = alloc_compat_syscall_stack();
if (!*stack32) {
pr_err("Failed to allocate stack for 32-bit TLS restore\n");
return -1;
}
......@@ -59,6 +50,15 @@ static int prepare_stack32(void)
void restore_tls(tls_t *ptls)
{
/*
* We need here compatible stack, because 32-bit syscalls get
* 4-byte pointer and _usally_ restorer is also under 4Gb, but
* it can be upper and then pointers are messed up.
* (we lose high 4 bytes and... BANG!)
* Nothing serious, but syscall will return -EFAULT - or if we're
* lucky and lower 4 bytes points on some writeable VMA - corruption).
*/
void *stack32 = NULL;
unsigned i;
for (i = 0; i < GDT_ENTRY_TLS_NUM; i++) {
......@@ -68,7 +68,7 @@ void restore_tls(tls_t *ptls)
if (desc->seg_not_present)
continue;
if (prepare_stack32() < 0)
if (prepare_stack32(&stack32) < 0)
return;
builtin_memcpy(stack32, desc, sizeof(user_desc_t));
......
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