mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-01-23 02:14:37 +00:00
x86/criu: shstk: restore SHSTK via premap loops
* call shstk_vma_restore() for VMA_AREA_SHSTK in vma_remap() * delete map/copy/unmap from shstk_restore() and keep token setup + finalize * before the loop naturally stopped at cet->ssp-8, so a -8 nudge is required here Signed-off-by: Igor Svilenkov Bozic <svilenkov@gmail.com> Co-Authored-By: Andrei Vagin <avagin@gmail.com> [ alex: small code cleanups ] Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
This commit is contained in:
parent
abf4a71d99
commit
6fd71b9ee9
2 changed files with 19 additions and 38 deletions
|
|
@ -205,28 +205,11 @@ static always_inline int shstk_vma_restore(VmaEntry *vma_entry)
|
|||
*/
|
||||
static always_inline int shstk_restore(struct rst_shstk_info *cet)
|
||||
{
|
||||
unsigned long *shstk_data = (unsigned long *)cet->premmaped_addr;
|
||||
unsigned long ssp = cet->vma_start + cet->vma_size - 8;
|
||||
unsigned long shstk_top = cet->vma_size / 8 - 1;
|
||||
unsigned long val;
|
||||
long ret;
|
||||
unsigned long ssp, val;
|
||||
|
||||
if (!(cet->cet & ARCH_SHSTK_SHSTK))
|
||||
return 0;
|
||||
|
||||
if (shstk_map(cet->vma_start, cet->vma_size))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Switch shadow stack from temporary location to the actual task's
|
||||
* shadow stack VMA
|
||||
*/
|
||||
shstk_switch_ssp(ssp);
|
||||
|
||||
/* restore shadow stack contents */
|
||||
for (; ssp >= cet->ssp; ssp -= 8, shstk_top--)
|
||||
wrssq(ssp, shstk_data[shstk_top]);
|
||||
|
||||
/*
|
||||
* Add tokens for sigreturn frame and for switch of the shadow stack.
|
||||
* The sigreturn token will be checked by the kernel during
|
||||
|
|
@ -236,6 +219,7 @@ static always_inline int shstk_restore(struct rst_shstk_info *cet)
|
|||
*/
|
||||
|
||||
/* token for sigreturn frame */
|
||||
ssp = cet->ssp - 8;
|
||||
val = ALIGN_DOWN(cet->ssp, 8) | SHSTK_DATA_BIT;
|
||||
wrssq(ssp, val);
|
||||
|
||||
|
|
@ -247,12 +231,6 @@ static always_inline int shstk_restore(struct rst_shstk_info *cet)
|
|||
/* reset shadow stack pointer to the proper location */
|
||||
shstk_switch_ssp(ssp);
|
||||
|
||||
ret = sys_munmap(shstk_data, cet->vma_size + PAGE_SIZE);
|
||||
if (ret < 0) {
|
||||
pr_err("Failed to unmap premmaped shadow stack\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return shstk_finalize();
|
||||
}
|
||||
#define arch_shstk_restore shstk_restore
|
||||
|
|
|
|||
|
|
@ -1112,6 +1112,23 @@ static int vma_remap(VmaEntry *vma_entry, int uffd)
|
|||
|
||||
pr_info("Remap %lx->%lx len %lx\n", src, dst, len);
|
||||
|
||||
/*
|
||||
* SHSTK VMAs are a bit special, in fact we create shstk vma right in the
|
||||
* shstk_vma_restore() and populate it with contents from a premapped VMA
|
||||
* (which in turns is just a normal anonymous VMA!). Then, we munmap() this
|
||||
* premapped VMA. After, we need to adjust vma_premmaped_start(vma_entry)
|
||||
* to point to a created shstk vma and treat it as a premmaped one in vma_remap().
|
||||
*/
|
||||
if (vma_entry_is(vma_entry, VMA_AREA_SHSTK)) {
|
||||
if (shstk_vma_restore(vma_entry)) {
|
||||
pr_err("Unable to prepare shadow stack vma for remap %lx -> %lx\n", src, dst);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* shstk_vma_restore() modifies vma premapped address */
|
||||
src = vma_premmaped_start(vma_entry);
|
||||
}
|
||||
|
||||
if (src - dst < len)
|
||||
guard = dst;
|
||||
else if (dst - src < len)
|
||||
|
|
@ -1811,13 +1828,6 @@ __visible long __export_restore_task(struct task_restore_args *args)
|
|||
if (vma_entry->start > vma_entry->shmid)
|
||||
break;
|
||||
|
||||
/*
|
||||
* shadow stack VMAs cannot be remapped, they must be
|
||||
* recreated with map_shadow_stack system call
|
||||
*/
|
||||
if (vma_entry_is(vma_entry, VMA_AREA_SHSTK))
|
||||
continue;
|
||||
|
||||
if (vma_remap(vma_entry, args->uffd))
|
||||
goto core_restore_end;
|
||||
}
|
||||
|
|
@ -1835,13 +1845,6 @@ __visible long __export_restore_task(struct task_restore_args *args)
|
|||
if (vma_entry->start < vma_entry->shmid)
|
||||
break;
|
||||
|
||||
/*
|
||||
* shadow stack VMAs cannot be remapped, they must be
|
||||
* recreated with map_shadow_stack system call
|
||||
*/
|
||||
if (vma_entry_is(vma_entry, VMA_AREA_SHSTK))
|
||||
continue;
|
||||
|
||||
if (vma_remap(vma_entry, args->uffd))
|
||||
goto core_restore_end;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue