Skip to content

Commit 07af330

Browse files
leeq2016avagin
authored andcommitted
restore/pie: check return value of sys_rseq on unregister
The return value of sys_rseq was previously ignored during unregistration, under the assumption that it would not fail if the rseq structure was properly registered. However, if sys_rseq fails, the kernel retains the registration. If the memory containing the rseq structure is subsequently unmapped or reused, kernel updates to the rseq area can cause the process to crash (e.g., via SIGSEGV). Check the return value of sys_rseq. If it fails, log the error code and abort the restoration process. This makes rseq unregistration failures fatal and explicit, aiding in debugging and preventing later obscure crashes. Signed-off-by: liqiang2020 <liqiang64@huawei.com>
1 parent fb59ae5 commit 07af330

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

criu/pie/restorer.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,13 +1363,19 @@ __visible void __export_unmap(void)
13631363
sys_munmap(bootstrap_start, bootstrap_len - vdso_rt_size);
13641364
}
13651365

1366-
static void unregister_libc_rseq(struct rst_rseq_param *rseq)
1366+
static int unregister_libc_rseq(struct rst_rseq_param *rseq)
13671367
{
1368+
long ret;
1369+
13681370
if (!rseq->rseq_abi_pointer)
1369-
return;
1371+
return 0;
13701372

1371-
/* can't fail if rseq is registered */
1372-
sys_rseq(decode_pointer(rseq->rseq_abi_pointer), rseq->rseq_abi_size, 1, rseq->signature);
1373+
ret = sys_rseq(decode_pointer(rseq->rseq_abi_pointer), rseq->rseq_abi_size, 1, rseq->signature);
1374+
if (ret) {
1375+
pr_err("Failed to unregister libc rseq %ld\n", ret);
1376+
return -1;
1377+
}
1378+
return 0;
13731379
}
13741380

13751381
/*
@@ -1803,7 +1809,8 @@ __visible long __export_restore_task(struct task_restore_args *args)
18031809
* for instance once the kernel will want to update (struct rseq).cpu_id field:
18041810
* https://github.com/torvalds/linux/blob/ce522ba9ef7e/kernel/rseq.c#L89
18051811
*/
1806-
unregister_libc_rseq(&args->libc_rseq);
1812+
if (unregister_libc_rseq(&args->libc_rseq))
1813+
goto core_restore_end;
18071814

18081815
if (unmap_old_vmas((void *)args->premmapped_addr, args->premmapped_len, bootstrap_start, bootstrap_len,
18091816
args->task_size))

0 commit comments

Comments
 (0)