x86/criu: shstk: add shstk_vma_restore()

1. create shadow stack vma during vma_remap cycle
2. copy contents from a premapped non-shstk VMA into it
3. unmap premapped non-shstk VMA
4. Mark shstk VMA for remap into the final destination

Signed-off-by: Igor Svilenkov Bozic <svilenkov@gmail.com>
Co-Authored-By: Andrei Vagin <avagin@gmail.com>
Co-Authored-By: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
[ alex: debugging, rework together with Andrei and code cleanup ]
Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
This commit is contained in:
Igor Svilenkov Bozic 2025-09-06 18:02:37 +02:00 committed by Andrei Vagin
parent 02462c19c4
commit abf4a71d99
2 changed files with 44 additions and 0 deletions

View file

@ -163,6 +163,43 @@ static inline int shstk_finalize(void)
return ret;
}
/*
* Create shadow stack vma and restore its content from premmapped anonymous (non-shstk) vma
*/
static always_inline int shstk_vma_restore(VmaEntry *vma_entry)
{
long shstk, i;
unsigned long *shstk_data = (void *)vma_premmaped_start(vma_entry);
unsigned long vma_size = vma_entry_len(vma_entry);
long ret;
shstk = sys_map_shadow_stack(0, vma_size, SHADOW_STACK_SET_TOKEN);
if (shstk < 0) {
pr_err("Failed to map shadow stack: %ld\n", shstk);
return -1;
}
/* restore shadow stack contents */
for (i = 0; i < vma_size / 8; i++)
wrssq(shstk + i * 8, shstk_data[i]);
ret = sys_munmap(shstk_data, vma_size);
if (ret < 0) {
pr_err("Failed to unmap premmaped shadow stack\n");
return ret;
}
/*
* From that point premapped vma is (shstk) and we need
* to mremap() it to the final location. Originally premapped
* (shstk_data) has been unmapped already.
*/
vma_premmaped_start(vma_entry) = shstk;
return 0;
}
#define shstk_vma_restore shstk_vma_restore
/*
* Restore contents of the shadow stack and set shadow stack pointer
*/

View file

@ -357,4 +357,11 @@ static inline int arch_shstk_restore(struct rst_shstk_info *shstk)
#define arch_shstk_restore arch_shstk_restore
#endif
#ifndef shstk_vma_restore
static always_inline int shstk_vma_restore(VmaEntry *vma_entry)
{
return -1;
}
#endif
#endif /* __CR_RESTORER_H__ */