Skip to content

Commit 9d1623f

Browse files
svilenkovavagin
authored andcommitted
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>
1 parent 8553161 commit 9d1623f

File tree

2 files changed

+19
-38
lines changed

2 files changed

+19
-38
lines changed

criu/arch/x86/include/asm/shstk.h

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -205,28 +205,11 @@ static always_inline int shstk_vma_restore(VmaEntry *vma_entry)
205205
*/
206206
static always_inline int shstk_restore(struct rst_shstk_info *cet)
207207
{
208-
unsigned long *shstk_data = (unsigned long *)cet->premmaped_addr;
209-
unsigned long ssp = cet->vma_start + cet->vma_size - 8;
210-
unsigned long shstk_top = cet->vma_size / 8 - 1;
211-
unsigned long val;
212-
long ret;
208+
unsigned long ssp, val;
213209

214210
if (!(cet->cet & ARCH_SHSTK_SHSTK))
215211
return 0;
216212

217-
if (shstk_map(cet->vma_start, cet->vma_size))
218-
return -1;
219-
220-
/*
221-
* Switch shadow stack from temporary location to the actual task's
222-
* shadow stack VMA
223-
*/
224-
shstk_switch_ssp(ssp);
225-
226-
/* restore shadow stack contents */
227-
for (; ssp >= cet->ssp; ssp -= 8, shstk_top--)
228-
wrssq(ssp, shstk_data[shstk_top]);
229-
230213
/*
231214
* Add tokens for sigreturn frame and for switch of the shadow stack.
232215
* 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)
236219
*/
237220

238221
/* token for sigreturn frame */
222+
ssp = cet->ssp - 8;
239223
val = ALIGN_DOWN(cet->ssp, 8) | SHSTK_DATA_BIT;
240224
wrssq(ssp, val);
241225

@@ -247,12 +231,6 @@ static always_inline int shstk_restore(struct rst_shstk_info *cet)
247231
/* reset shadow stack pointer to the proper location */
248232
shstk_switch_ssp(ssp);
249233

250-
ret = sys_munmap(shstk_data, cet->vma_size + PAGE_SIZE);
251-
if (ret < 0) {
252-
pr_err("Failed to unmap premmaped shadow stack\n");
253-
return ret;
254-
}
255-
256234
return shstk_finalize();
257235
}
258236
#define arch_shstk_restore shstk_restore

criu/pie/restorer.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,6 +1112,23 @@ static int vma_remap(VmaEntry *vma_entry, int uffd)
11121112

11131113
pr_info("Remap %lx->%lx len %lx\n", src, dst, len);
11141114

1115+
/*
1116+
* SHSTK VMAs are a bit special, in fact we create shstk vma right in the
1117+
* shstk_vma_restore() and populate it with contents from a premapped VMA
1118+
* (which in turns is just a normal anonymous VMA!). Then, we munmap() this
1119+
* premapped VMA. After, we need to adjust vma_premmaped_start(vma_entry)
1120+
* to point to a created shstk vma and treat it as a premmaped one in vma_remap().
1121+
*/
1122+
if (vma_entry_is(vma_entry, VMA_AREA_SHSTK)) {
1123+
if (shstk_vma_restore(vma_entry)) {
1124+
pr_err("Unable to prepare shadow stack vma for remap %lx -> %lx\n", src, dst);
1125+
return -1;
1126+
}
1127+
1128+
/* shstk_vma_restore() modifies vma premapped address */
1129+
src = vma_premmaped_start(vma_entry);
1130+
}
1131+
11151132
if (src - dst < len)
11161133
guard = dst;
11171134
else if (dst - src < len)
@@ -1811,13 +1828,6 @@ __visible long __export_restore_task(struct task_restore_args *args)
18111828
if (vma_entry->start > vma_entry->shmid)
18121829
break;
18131830

1814-
/*
1815-
* shadow stack VMAs cannot be remapped, they must be
1816-
* recreated with map_shadow_stack system call
1817-
*/
1818-
if (vma_entry_is(vma_entry, VMA_AREA_SHSTK))
1819-
continue;
1820-
18211831
if (vma_remap(vma_entry, args->uffd))
18221832
goto core_restore_end;
18231833
}
@@ -1835,13 +1845,6 @@ __visible long __export_restore_task(struct task_restore_args *args)
18351845
if (vma_entry->start < vma_entry->shmid)
18361846
break;
18371847

1838-
/*
1839-
* shadow stack VMAs cannot be remapped, they must be
1840-
* recreated with map_shadow_stack system call
1841-
*/
1842-
if (vma_entry_is(vma_entry, VMA_AREA_SHSTK))
1843-
continue;
1844-
18451848
if (vma_remap(vma_entry, args->uffd))
18461849
goto core_restore_end;
18471850
}

0 commit comments

Comments
 (0)